我正在尝试添加自定义授权策略,该策略可以检查json配置文件中提供的分隔的组列表。我正在使用ASP.Net 5 - MVC 6,以及Windows身份验证。
一切正常,除非我打电话给失败。然后什么都没发生显示空白屏幕。这是我的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>();
授权类:
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);
}
}
答案 0 :(得分:2)
我发现这样做的唯一方法是,不要使用context.Fail(),而是这样做:
取代:
context.Fail();
使用:
var mvcContext = context.Resource as AuthorizationFilterContext;
mvcContext.Result = new RedirectToActionResult("Action", "Controller", null);
context.Succeed(requirement);
允许上下文成功,将执行上下文,现在是重定向。
答案 1 :(得分:0)
我选择了herostwist所建议的,但政策可以挑战或禁止。经过深入研究后,我发现了一些可以直接访问AuthorizationFilterContext的内容(因为它们遵循命名约定并继承自AuthorizeAttribute:
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
{
}
然后清理控制器:
public class BudgetItemController : BCommonController
{
}
答案 2 :(得分:-2)
我正在使用cookie身份验证而不是Windows,但在Startup.cs中的Configure方法中,我有以下代码告诉它去哪里
gridOptions
答案 3 :(得分:-3)
我不知道你可以在哪里配置重定向结果,但至少我能够创建这样一个“Account / AccessDenied.cshtml”文件,该文件将在失败案例中显示。 “帐户”是我的班级名称,当失败发生时,浏览器被重定向到此网址:(http://localhost:39339/Account/AccessDenied?ReturnUrl=%2Fapp%2Fequipments)
这也是我的控制器代码(Web / AccountController.cs)。
public class AccountController : Controller
{
public IActionResult AccessDenied()
{
return View();
}
}