Asp.Net Core 基于策略的授权以 401 Unauthorized 结尾

编程入门 行业动态 更新时间:2024-10-25 11:28:17
本文介绍了Asp.Net Core 基于策略的授权以 401 Unauthorized 结尾的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在建立一个基于自定义策略的授权框架,它将有一组业务规则来授权当前登录的用户.但是,目前骨架总是以 401 Unauthorized 结束.

I am working on setting up a skeleton of custom policy based authorization which will have a set of business rules to authorized the currently logged on user. But, currently the skeleton always ends up with 401 Unauthorized.

这是我的代码,

public class MyAuthorizationRequirement : IAuthorizationRequirement { public MyAuthorizationRequirement() { } } public class MyAuthorizationHandler : AuthorizationHandler<MyAuthorizationRequirement> { public MyAuthorizationHandler() { } protected override void Handle(AuthorizationContext context, MyAuthorizationRequirement requirement) { context.Succeed(requirement); } }

然后在 Startup.cs

public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IAuthorizationHandler, MyAuthorizationHandler>() .AddAuthorization(options => { options.AddPolicy("MyAuthorization", policy => policy.Requirements.Add(new MyAuthorizationRequirement())); }); }

这就是我在 HomeController (MVC 6) 中使用它的方式

And this is how I use it in my HomeController (MVC 6)

[Authorize(Policy = "MyAuthorization")] public class HomeController : Controller { public IActionResult Index() { return View(); } }

当我不放置 Authorize 属性时,索引视图呈现良好.但是,当我包含 Authorize 属性时,我只会收到空白视图.当我检查开发人员工具(网络)时,我会得到以下幕后细节.

When I don't put the Authorize attribute, the Index view renders fine. But, when I include the Authorize attribute, I just receive the blank view. And when I check the developer tools (Network) I get the following behind the scene details.

Request URL:localhost:51129/ Request Method:GET Status Code:401 Unauthorized Remote Address:[::1]:51129

我的需求和处理程序类的构造函数的断点被调用,但是Handler类的Handle方法的断点和Index Controller 类的方法永远不会被调用.

The breakpoints to the constructors of my requirement and handler classes are invoked, but the breakpoints to the Handle method of Handler class, and Index method of Controller class never get invoked.

推荐答案

那是因为AuthorizeFilter 为每个 [Authorize] 属性添加到管道中,需要对用户进行身份验证.

That is because the AuthorizeFilter added to the pipeline for every [Authorize] attribute requires users to be authenticated.

如果您查看源代码,您会发现即使不调用任何策略,它也可以确保用户已通过身份验证:

If you look at the source code, you will see that even without calling any policy it is making sure the user is authenticated:

// Note: Default Anonymous User is new ClaimsPrincipal(new ClaimsIdentity()) if (httpContext.User == null || !httpContext.User.Identities.Any(i => i.IsAuthenticated) || !await authService.AuthorizeAsync(httpContext.User, context, Policy)) { context.Result = new ChallengeResult(Policy.AuthenticationSchemes.ToArray()); }

该条件 httpContext.User.Identities.Any(i => i.IsAuthenticated) 对于匿名用户将是 false.

That condition httpContext.User.Identities.Any(i => i.IsAuthenticated) will be false for anonymous users.

  • DefaultPolicyL19" rel="nofollow noreferrer">AuthorizationOptions 验证用户是否经过身份验证.您可以在 AddAuthorization 配置中将其设置为 null,但即使在这种情况下,上面的 AuthorizeFilter 也会确保用户已通过身份验证
  • There is also a DefaultPolicy in the AuthorizationOptions that verifies the user is authenticated. You can set that as null in the AddAuthorization configuration, but even in this case the AuthorizeFilter above will make sure the user is authenticated

您尝试代码的最简单方法是添加一个经过身份验证的匿名用户,这样任何匿名用户都会被分配一个经过身份验证的 ClaimsPrincipal(因为它已经GenericIdentity 而不是空的 ClaimsIdentity):

The easiest way just for you to try your code would be adding an authenticated anonymous user, so any anonymous user gets assigned a ClaimsPrincipal that is authenticated (as it has a GenericIdentity instead of an empty ClaimsIdentity):

//Add this before app.UseMvc app.Use(async (context, next) => { if (!context.User.Identities.Any(i => i.IsAuthenticated)) { //Assign all anonymous users the same generic identity, which is authenticated context.User = new ClaimsPrincipal(new GenericIdentity("anonymous")); } await next.Invoke(); });

在一个真实的应用程序中,您可能会有一些身份验证框架,用户可以在其中进行身份验证,因此您不会遇到这个问题.

In a real app you will probably have some authentication framework where users can authenticate themselves, so you wouldn't have this problem.

否则您可能需要使用应用程序约定,并将 AuthorizeFilter 替换为您自己的调整实现,不需要经过身份验证的用户,这个答案朝着那个方向发展.

Otherwise you might need to play with the application conventions, and replace the AuthorizeFilter with your own tweaked implementation that doesn't require authenticated users, this answer goes in that direction.

更多推荐

Asp.Net Core 基于策略的授权以 401 Unauthorized 结尾

本文发布于:2023-11-14 10:30:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1586971.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:结尾   策略   Net   Asp   Core

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!