在为Identity Server 4中的TestUser设置的ASP.NET MVC 5客户端中获取声明

问题描述

我已将我的客户端添加到IdentityServer4身份提供商应用程序中。

library(data.table)
dt <- data.table(probs = runif(5),probs2 = runif(5))
dt[,hit := sapply(probs,function(x) sample(0:1,1,prob=c(1 - x,x)))]
dt
#>        probs     probs2 hit
#> 1: 0.1196779 0.46539006   0
#> 2: 0.9896483 0.31307527   1
#> 3: 0.4169862 0.08778795   0
#> 4: 0.9456939 0.09123848   1
#> 5: 0.5033147 0.27397908   0

还有类似的IdentityResources

     new Client
        {
            ClientId = "mvc4Simple",ClientName = "MVC 4 Web Client",AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,AllowAccesstokensViabrowser = true,RequireConsent = false,ClientSecrets =
            {
                new Secret("secret".Sha256())
            },AlwaysIncludeUserClaimsInIdToken=true,AlwaysSendClientClaims=true,RedirectUris = { "https://localhost:44347/signin-oidc" },PostlogoutRedirectUris = { "https://localhost:44347/signout-callback-oidc" },AllowedScopes = new List<string>
             {
              IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile,IdentityServerConstants.StandardScopes.Email                 
             },AllowOfflineAccess = true,RequirePkce = false,AllowPlainTextPkce = false
        }

我的TestUser就是这样

     public static IEnumerable<IdentityResource> GetIdentityResources()
    {
        return new List<IdentityResource>
        {
         new IdentityResources.OpenId(),new IdentityResources.Profile(),new IdentityResources.Email()
        };
    }

我的客户端是一个简单的asp.net MVC应用程序。客户端配置就是这样

  new TestUser
  {
      SubjectId = "12345678",Username = "John",Password = "12345",Claims = new List<Claim> {
                new Claim(ClaimTypes.Email,"[email protected]"),new Claim(ClaimTypes.Role,"admin")
            }
  }

身份验证正常。它将我重定向回我的应用程序,但我想知道如何获取TestUser的声明集,即电子邮件和角色?

解决方法

我读了一些有关它的文章。并解决了。 我必须添加一个范围。

     new ApiScope("api1.read","Read Access to API #1")
         {
           UserClaims={
                ClaimTypes.Email,ClaimTypes.Role
                }
         }

然后更改客户详细信息

    new Client
    {
        ClientId = "mvc4Simple",ClientName = "MVC 4 Web Client",AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,AllowAccessTokensViaBrowser = true,RequireConsent = false,ClientSecrets =
        {
            new Secret("secret".Sha256())
        },AlwaysIncludeUserClaimsInIdToken=true,AlwaysSendClientClaims=true,RedirectUris = { "https://localhost:44347/signin-oidc" },PostLogoutRedirectUris = { "https://localhost:44347/signout-callback-oidc" },AllowedScopes = new List<string>
         {
          IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile,IdentityServerConstants.StandardScopes.Email 
          "api1.read"                
         },AllowOfflineAccess = true,RequirePkce = false,AllowPlainTextPkce = false
    }

然后在Startup类中添加令牌作为响应类型。

     public void Configuration(IAppBuilder app)
     {
        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap =
        new Dictionary<string,string>();            
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
          AuthenticationType = "cookie"
        });          
        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
         AuthenticationType = "oidc",Authority = "https://localhost:44316",ClientId = "mvc4Simple",ClientSecret = "secret",ResponseType = "code id_token token",Scope = "openid profile api1.read",//Include that scope here
         UseTokenLifetime = false,RedirectUri = "https://localhost:44347/signin-oidc",PostLogoutRedirectUri = "https://localhost:44347/signout-callback-oidc",SignInAsAuthenticationType = "cookie",SaveTokens=true,Notifications = new OpenIdConnectAuthenticationNotifications
         {
            SecurityTokenValidated = context =>
                    {                             
                    context.AuthenticationTicket.Identity.AddClaim(new 
                    Claim(ClaimTypes.NameIdentifier,context.ProtocolMessage.IdToken));
              context.AuthenticationTicket.Identity.AddClaim(new Claim("access_token",context.ProtocolMessage.AccessToken));//Set access token in access_token claim
                        return Task.FromResult(0);
                    },RedirectToIdentityProvider = n =>
            {
                if (n.ProtocolMessage.RequestType ==                    
      Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectRequestType.Logout)
                {
             var idTokenHint =n.OwinContext.Authentication.User.FindFirst("id_token");
                    if (idTokenHint != null)
                    {
                        n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
                    }

                }
                return Task.FromResult(0);
            }
          }
       });
     }

最后,我能够按如下方式在控制器的操作方法中获得这些要求

    public ActionResult Index()
    {
        var identity = (ClaimsIdentity)User.Identity;     
        var token= identity.Claims.Where(x => x.Type == "access_token").ToList();
        if (token.Count > 0) 
        {
            var jwtToken = new JwtSecurityToken(token[0].Value);
            var claimsjwt=jwtToken.Claims;//Here you can get all the claims set for the user i.e email,role
        }
        return View();
    }