首页 新闻 会员 周边

如何在 ASP.NET Core 的 Middleware 中设置用户的角色

0
悬赏园豆:30 [已解决问题] 解决于 2018-07-10 17:24

目前 middleware 中的代码是这么写的

public class AuthorizeMiddleware
{
    private RequestDelegate _next;

    public AuthorizeMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context, IUserService userService)
    {
        var identity = context.User.Identity;
        if (identity.IsAuthenticated 
            && await userService.IsUserInRole(ROLE_NAME, identity.Name))
        {
            context.User.AddIdentity(new ClaimsIdentity("Basic", ClaimTypes.Role, ROLE_NAME));
        }

        await _next(context);
    }
}

在 Authorization Policy 中使用这个角色进行授权,但不起作用

services.AddMvc(o =>
    {
        var policy = new AuthorizationPolicyBuilder()
            .RequireRole(ROLE_NAME)
            .Build();
        o.Filters.Add(new AuthorizeFilter(policy));
    });

请问如何解决这个问题?

问题补充:

通过查看 HttpAbstractionsSecurity 的源代码,知道了这个问题实际上就是如何给已有 ClaimsPrincipal (HttpContext.User) 添加 Claim

dudu的主页 dudu | 高人七级 | 园豆:30994
提问于:2018-07-10 12:14
< >
分享
最佳答案
0

自己解决了。之前使用 AddIdentity 是不正确的方法,需要在已有的 context.User.Identity 中添加 Claim ,但 context.User.Identity 的类型是 IIdentity ,它没有提供添加 Claim 的方法。

后来在 stackoverflow 的 Update claims in ClaimsPrincipal 中知道了可以将 context.User.Identity 转换为 ClaimsIdentity ,通过它就可以添加 Claim 了。

var claimsIdentity = context.User.Identity as ClaimsIdentity;
if(claimsIdentity != null)
{
    claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, ROLE_NAME));
}
dudu | 高人七级 |园豆:30994 | 2018-07-10 17:23

为什么不在登陆的时候添加role,而在中间件里动态添加role?中间件里不用判断当前访问的页面吗?

大豆男生 | 园豆:608 (小虾三级) | 2018-07-10 19:41

@大豆男生: 是登录时添加role更好,这里是特殊场景所致——暂时不能修改登录部分的代码。整个应用只允许授权角色才能访问

dudu | 园豆:30994 (高人七级) | 2018-07-10 21:38

@dudu: 学习了,感觉微软的这套设计得很复杂,还真不容易上手。

幻天芒 | 园豆:37175 (高人七级) | 2018-07-10 22:56
其他回答(2)
1

我都是加一个前置中间件,把token(or cookie)转换为userinfo,存储到Context.Items中的,然后在授权filter中检查用户权限。

收获园豆:15
幻天芒 | 园豆:37175 (高人七级) | 2018-07-10 12:21

我想充分利用 asp.net core 的 authorization 机制

支持(0) 反对(0) dudu | 园豆:30994 (高人七级) | 2018-07-10 12:24

这个方法在权限变动频繁时候太麻烦了, 所有token中除了用于不会变的东西, 我一般啥也不存储

支持(0) 反对(0) thinkershare | 园豆:402 (菜鸟二级) | 2021-07-16 11:51
0

用 AuthorizationFilter 应该比 Middleware 方便些吧

public class UserAuthorizeFilter : IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {

所有的Middleware都在app.UseMvc之前执行。所以AuthorizationFilter比Middleware能获取更多信息,包括 Controller,Action 名称等。

收获园豆:15
大豆男生 | 园豆:608 (小虾三级) | 2018-07-10 12:37
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册