2017-07-28 59 views
0

我正在使用身份服務器4進行身份驗證,使用授予類型作爲「ResourceOwnerPassword」。我能夠對用戶進行身份驗證,但無法獲得與用戶相關的聲明。那麼我怎麼能得到這些?使用資源所有者密碼在身份服務器中獲取聲明

下面是我的代碼

客戶

Startup.cs

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions 
      { 
       Authority = "http://localhost:5000", 
       RequireHttpsMetadata = false, 
       ApiName = "api1" 
      }); 

控制器

public async Task<IActionResult> Authentication(LoginViewModel model) 
     { 
      var disco = await DiscoveryClient.GetAsync("http://localhost:5000"); 

      // request token 
      var tokenClient = new TokenClient(disco.TokenEndpoint, "ro.client", "secret"); 
      var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync(model.Email, model.Password, "api1"); 

      if (tokenResponse.IsError) 
      { 
       Console.WriteLine(tokenResponse.Error); 
      } 
// Here I am not getting the claims, it is coming Forbidden 
      var extraClaims = new UserInfoClient(disco.UserInfoEndpoint); 
      var identityClaims = await extraClaims.GetAsync(tokenResponse.AccessToken); 
      if (!tokenResponse.IsError) 
      { 
       Console.WriteLine(identityClaims.Json); 
      } 

      Console.WriteLine(tokenResponse.Json); 
      Console.WriteLine("\n\n"); 
} 

服務器 Startup.cs

services.AddIdentityServer() 
       .AddTemporarySigningCredential() 
       .AddInMemoryPersistedGrants() 
       .AddInMemoryIdentityResources(Config.GetIdentityResources()) 
       .AddInMemoryApiResources(Config.GetApiResources()) 
       .AddInMemoryClients(Config.GetClients(Configuration)) 
       .AddAspNetIdentity<ApplicationUser>() 
       .AddProfileService<IdentityProfileService>() 
       .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>(); 

Config.cs

public static IEnumerable<Client> GetClients(IConfigurationRoot Configuration) 
     { 
      // client credentials client 
      return new List<Client> 
      { 

       // resource owner password grant client 
       new Client 
       { 
        ClientId = "ro.client", 
        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, 

        ClientSecrets = 
        { 
         new Secret("secret".Sha256()) 
        }, 
        AlwaysSendClientClaims = true, 
        AlwaysIncludeUserClaimsInIdToken = true, 


        AccessTokenType = AccessTokenType.Jwt 

       } 

      }; 
     } 

public static IEnumerable<ApiResource> GetApiResources() 
     { 
      return new List<ApiResource> 
      { 
       new ApiResource("api1", "My API") 
      }; 
     } 

但是,當我檢查我的訪問令牌jwt.io那裏我可以看到的指控,但爲什麼我不能夠在控制器中得到什麼?

對此有任何幫助表示讚賞!

回答

2

您可以撥打UserInfoEndpoint,按照你的榜樣,但你還可以得到額外的要求,如果你定義ApiResource如要求他們。

例如,而不是僅僅定義你ApiResource像你:

new ApiResource("api1", "My API") 

您可以使用擴展格式,並確定你想獲取此範圍的訪問令牌時有什麼UserClaims。 例如:

new ApiResource 
{ 
    Name = "api1", 
    ApiSecrets = { new Secret(*some secret*) }, 
    UserClaims = { 
     JwtClaimTypes.Email, 
     JwtClaimTypes.PhoneNumber, 
     JwtClaimTypes.GivenName, 
     JwtClaimTypes.FamilyName, 
     JwtClaimTypes.PreferredUserName 
    }, 
    Description = "My API", 
    DisplayName = "MyApi1", 
    Enabled = true, 
    Scopes = { new Scope("api1") } 
} 

然後在你自己實現的IProfileService的你會發現,調用GetProfileDataAsync有什麼請求在上下文(ProfileDataRequestContext.RequestedClaimTypes)索賠清單。根據所要求的列表,您可以將您喜歡的任何聲明(不管您是否喜歡)添加到您從該方法返回的context.IssuedClaims。這些將成爲訪問令牌的一部分。

如果您只希望通過專門調用UserInfo端點來確定某些聲明,則需要創建一個IdentityResource定義,並將該範圍作爲原始令牌請求的一部分。 例如:

new IdentityResource 
{ 
    Name = "MyIdentityScope", 
    UserClaims = { 
     JwtClaimTypes.EmailVerified, 
     JwtClaimTypes.PhoneNumberVerified 
    } 
} 

但這樣你就不會得到「禁止」作爲迴應用戶信息端點您的第一個問題就是在這裏下對方的回答!

0

嘗試在調用UserInfoEndpoint時沿請求發送令牌。試試這個:

var userInfoClient = new UserInfoClient(doc.UserInfoEndpoint, token); 

var response = await userInfoClient.GetAsync(); 
var claims = response.Claims; 

official docs

相關問題