C# ASP.Net 5 AuthorizationHandler失败重定向
我试图添加一个自定义授权策略,该策略可以检查json配置文件中提供的组的分隔列表。我正在使用ASP.NET5-MVC6以及windows身份验证 一切都很好,除了我叫Fail的时候。然后什么也没发生。显示一个空白屏幕。这是我的HandleRequirementAsync方法。我尝试了任务结果的各种值。我一直像疯子一样在谷歌上搜索,但运气不好。希望有人能帮忙 所需结果:我想在失败时重定向到自定义页面,但如果不可能,至少可以重定向回登录页面。唯一似乎有效果的事情是抛出一个异常 启动中的相关注册码:C# ASP.Net 5 AuthorizationHandler失败重定向,c#,asp.net,asp.net-mvc,asp.net-core-mvc,C#,Asp.net,Asp.net Mvc,Asp.net Core Mvc,我试图添加一个自定义授权策略,该策略可以检查json配置文件中提供的组的分隔列表。我正在使用ASP.NET5-MVC6以及windows身份验证 一切都很好,除了我叫Fail的时候。然后什么也没发生。显示一个空白屏幕。这是我的HandleRequirementAsync方法。我尝试了任务结果的各种值。我一直像疯子一样在谷歌上搜索,但运气不好。希望有人能帮忙 所需结果:我想在失败时重定向到自定义页面,但如果不可能,至少可以重定向回登录页面。唯一似乎有效果的事情是抛出一个异常 启动中的相关注册码:
var appSettings = Configuration.GetSection("AppSettings");
services.Configure<Models.AppSettings>(appSettings);
services.AddMvc();
services.AddAuthorization(options =>
{
options.AddPolicy("RoleAuth", policy => policy.Requirements.Add(new RolesRequirement(appSettings["AllowedGroups"])));
});
services.AddSingleton<IAuthorizationHandler, RoleAuthorizationHandler>();
var-appSettings=Configuration.GetSection(“appSettings”);
服务。配置(应用程序设置);
services.AddMvc();
services.AddAuthorization(选项=>
{
options.AddPolicy(“RoleAuth”,policy=>policy.Requirements.Add(新的RolesRequirement(appSettings[“alloweGroups]”));
});
services.AddSingleton();
以及授权类别:
public class RolesRequirement : IAuthorizationRequirement
{
public RolesRequirement(string groups)
{
Groups = groups;
}
public string Groups { get; private set; }
}
public class RoleAuthorizationHandler : AuthorizationHandler<RolesRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RolesRequirement requirement)
{
if (!string.IsNullOrWhiteSpace(requirement.Groups))
{
Console.WriteLine(requirement.Groups);
var groups = requirement.Groups.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
//we could check for group membership here.... maybe???
foreach (var group in groups)
{
if (context.User.IsInRole(group))
{
context.Succeed(requirement);
return Task.FromResult(0);
}
}
}
else
{
context.Succeed(requirement);
}
context.Fail();
return Task.FromResult(0);
}
}
公共类角色要求:IAAuthorizationRequirement
{
公共角色要求(字符串组)
{
组=组;
}
公共字符串组{get;private set;}
}
公共类RoleAuthorizationHandler:AuthorizationHandler
{
受保护的覆盖任务HandleRequirementAsync(授权HandlerContext上下文,角色需求)
{
如果(!string.IsNullOrWhiteSpace(requirement.Groups))
{
控制台写入线(需求组);
var groups=requirement.groups.Split(新字符[]{',},StringSplitOptions.RemoveEmptyEntries);
//我们可以在这里查看团体成员资格…也许???
foreach(组中的var组)
{
if(context.User.IsInRole(组))
{
成功(要求);
返回Task.FromResult(0);
}
}
}
其他的
{
成功(要求);
}
context.Fail();
返回Task.FromResult(0);
}
}
我使用的是cookie身份验证而不是windows,但在Startup.cs中的Configure方法中,我有下面一段代码,告诉它去哪里
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
LoginPath = "/account/login",
AuthenticationScheme = "Cookies",
AutomaticAuthenticate = true,
AutomaticChallenge = true
});
我不知道在哪里可以配置重定向结果,但至少我能够创建这样一个“Account/AccessDenied.cshtml”文件,该文件将在失败案例中显示。“Account”是我的类名,当失败发生时,浏览器被重定向到此Url:() 这是我的控制器代码(Web/AccountController.cs)
我发现的唯一方法是,不要使用context.Fail(),而是执行以下操作: 替换:
context.Fail();
与:
允许上下文成功,将执行上下文,该上下文现在是重定向。我同意herostwist的建议,但政策可以挑战或禁止。经过深入研究后,我发现是什么让您可以直接访问AuthorizationFilterContext,如下所示(因为它们遵循命名约定并继承自AuthorizationAttribute:
public class BudgetAccessFilterAttribute : AuthorizeAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
//context.HttpContext.User.Identity.Name
//TODO: determine if user has access to budget controllers, all of them could inherit from a Common Controller with this Filter
if (false)
{
//if no access then
context.Result = new RedirectToActionResult("Index", "Home", null);
}
}
}
然后,您可以这样装饰控制器:
[BudgetAccessFilter]
public class BudgetItemController : Controller
{
}
[BudgetAccessFilter]
public class BCommonController : Controller
{
}
如果您将有许多具有相同检查的控制器,那么它们都可以继承具有如下注释的基类:
[BudgetAccessFilter]
public class BudgetItemController : Controller
{
}
[BudgetAccessFilter]
public class BCommonController : Controller
{
}
然后清洁控制器:
public class BudgetItemController : BCommonController
{
}
目前正在寻找一种在发生故障时重定向的方法,你有没有运气?没有,Alex。没有运气。抱歉。一个糟糕的解决方法是在
AccountController.AccessDenied()中再次从HandleRequirementAsync()
调用相同的代码
方法并从此处重定向。在您的情况下,您需要所需的组,这会使此任务变得困难(反射等)。将内容添加到HttpContext。项
不起作用,它在到达AccessDenied()
之前被清除。最后一个(甚至更丑)方法是在某个地方有一个静态字典,在HandleRequirementAsync()
中添加条目,然后在AccessDenied()中再次删除它们
。是的,如果有更好的方法,我也会投反对票……此解决方案只与cookie身份验证相关。通过返回使用基于属性的授权,您否定了基于策略的授权的所有好处。当您有多个复杂的策略和角色时,此筛选器将无法发挥作用。因为授权是需求随着应用程序的增长而增长,可能有些操作需要诸如“必须超过18岁”之类的策略,有些操作需要诸如“必须已验证电子邮件”之类的附加策略-您很快就会发现基于属性的授权阻碍了您的发展。据我所知,从.net core 3开始,这不再是一个选项。它在core 2.1和2.2中确实有效。