ASP.Net 5 AuthorizationHandler失败重定向

时间:2016-08-30 14:44:09

标签: c# asp.net asp.net-mvc asp.net-core-mvc

我正在尝试添加自定义授权策略,该策略可以检查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);
    }
}

4 个答案:

答案 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();
    }
}