Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.Net 5 AuthorizationHandler失败重定向_C#_Asp.net_Asp.net Mvc_Asp.net Core Mvc - Fatal编程技术网

C# ASP.Net 5 AuthorizationHandler失败重定向

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方法。我尝试了任务结果的各种值。我一直像疯子一样在谷歌上搜索,但运气不好。希望有人能帮忙 所需结果:我想在失败时重定向到自定义页面,但如果不可能,至少可以重定向回登录页面。唯一似乎有效果的事情是抛出一个异常 启动中的相关注册码:

我试图添加一个自定义授权策略,该策略可以检查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中确实有效。