如何将ASP.net身份角色放入Identityserver4身份令牌 [英] How to put ASP.net Identity Roles into the Identityserver4 Identity token

查看:72
本文介绍了如何将ASP.net身份角色放入Identityserver4身份令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尽管我很高兴IdentityServer4的存在并使我在身份验证方面的生活在许多方面变得更加轻松,但我还是偶然发现了这个问题以及在社区中为索赔添加角色的许多讨论.

Although I am very happy that IdentityServer4 exists and makes life I with regards to authentication much easier in many ways, I've stumbled onto the problem and the many discussions of adding roles to claims within the community.

我的要求很简单:

  1. 我开发需要身份验证和授权的应用(xamarin表单)
  2. 我需要一个系统来存储我的用户的身份(姓名,密码,角色,电话...)-> ASP.net身份
  3. 我需要一个用于验证我的用户身份的系统-> IdentityServer 4
  4. 每个用户的角色非常有限(用户/管理员),并且保持不变
  5. 我需要一个API后端和一个MVC管理站点(asp.net核心)
  6. 我想使用[Authorize(Roles ="Admin")]限制对某些API/MVC控制器的访问

我花了无数小时来尝试不同的配置,以使asp.net身份角色在身份验证后传递给我的MVC应用程序,但是没有运气.目的如第6点所述.

I've spent countless hours trying different configurations to get asp.net Identity roles to be passed to my MVC application after authentication but without luck. The purpose is as described in point 6.

我也花费了无数的时间来阅读,但是我感到自版本v1.0.0起,有关角色的实现IdentityServer4.AspIdentity发生了很大变化.

I've also spent countless hours reading but I have a feeling that the implementation IdentityServer4.AspIdentity regarding roles has changed a lot since the version v1.0.0.

在阅读了很多有关此内容的内容后,仍不清楚如何实际执行此操作,因为似乎仅两个月前描述的某些解决方案已不再有效.

After reading a lot about this, it remains unclear how to actually implement this as it seems that some of the solution described only 2 months ago are no longer valid.

所以,到目前为止,我相信这里有2条路径:

So, for now I believe there are 2 paths:

  1. 通过仅请求身份令牌来使用身份令牌 并使用AlwaysIncludeInIdToken?
  2. 让客户端检索角色 使用userinfo端点并将它们注入到 httpcontext(?)允许mvc使用[Authorize(Roles = 管理员")]?
  1. Role into the identity token by only requesting an identity token and using AlwaysIncludeInIdToken?
  2. Let the client retrieve the roles using the userinfo endpoint and somehow inject them into the httpcontext(?) alowing mvc to check using [Authorize(Roles = "Admin")]?

无论如何,这是我的假设.

Anyway, that's my assumptions.

所以,请帮忙并详细解释/记录文档,以便我们能够以持久的方式开始执行此操作?一些可行的例子也很好.

So, please help out and explain/document in detail so we can start implementing this in a durable way? Some workable examples would be great as well.

推荐答案

因此,经过调查,我想出了两种方法来做到这一点:

So, after investigation I’ve come up with 2 methods to do this:

  1. 在Identity Server上包括角色/其他声明
  2. 在客户端添加角色/其他声明

包含在身份服务器端

ravi punjwani提供了如何使用带有IdentityServer4的ASP.Net Identity添加如何添加在access_token中的其他声明的答案.他的解决方案仍在草拟中,但是该解决方案允许您在将令牌发送回客户端之前添加任何声明.这是链接:

ravi punjwani provided the answer in ‘How to add additional claims to be included in the access_token using ASP.Net Identity with IdentityServer4. His solution is still in draft but the solution allows you to add any claim before the token is send back to the client. This is the link: How to add additional claims to be included in the access_token using ASP.Net Identity with IdentityServer4

包含在客户端

这有点困难,因为它涉及在客户端的请求管道中添加"IClaimsTransformer".结果是,对于每个请求,Claimstransformer都将检索该用户的声明,并将其添加到User Identity声明(令牌)中.设置Claimstransformer并不容易,因为要使DI正常工作很棘手,但是经过大量研究后,celow解决方案为我完成了这项工作.

This one is a little tougher as it involves adding ‘IClaimsTransformer’ in the request pipeline of the client. The result is that per request, the Claimstransformer will retrieve the claims for the user and add it to the User Identity claims (the token). The set-up of the Claimstransformer is not easy as it’s tricky to get DI to work but after lots of research the celow solution does it for me.

Custom ClaimsTransformer类在中间件中进行转换: 公共类KarekeClaimsTransformer:IClaimsTransformer { 私有只读UserManager _userManager;

The Custom ClaimsTransformer class does the transformation in the Middleware: public class KarekeClaimsTransformer : IClaimsTransformer { private readonly UserManager _userManager;

    public KarekeClaimsTransformer(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }

    public async Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context)
    {
        if (context.Principal.Identity.IsAuthenticated)
        {
            Claim userId = context.Principal.FindFirst("sub");

            if (context.Principal.FindFirst("role") == null && userId != null)
            {
                ApplicationUser user = await _userManager.FindByIdAsync(userId.Value);
                var roles = await _userManager.GetRolesAsync(user);
                foreach (var role in roles)
                {
                    ((ClaimsIdentity)context.Principal.Identity).AddClaim(new Claim(JwtClaimTypes.Role, role,
                        "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"));
                }
            }
        }
        return Task.FromResult(context.Principal).Result;
    }
}

在客户端启动类中,您需要将其添加到ConfigureServices中的作用域

In the Client start-up class you need to Add it to the scope in ConfigureServices

public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        ...
        services.AddScoped<IClaimsTransformer, KarekeClaimsTransformer>();
        // Add framework services.
        services.AddMvc();
    }

最后,添加"Configure":

Lastly, add in Configure:

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
        {
            Authority = "http://localhost:5000",
            RequireHttpsMetadata = false,

            ApiName = "api1"
        });

        app.UseClaimsTransformation((context) =>
        {
            IClaimsTransformer transformer = context.Context.RequestServices.GetRequiredService<IClaimsTransformer>();
            return transformer.TransformAsync(context);
        });

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "api/{controller}/{action?}/{id?}");
        });
    }

这篇关于如何将ASP.net身份角色放入Identityserver4身份令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆