2016-06-15 1 views
0

IdSrv를 통해 인증 할 때 검색되는 액세스 토큰에 기본적으로 클레임을 포함하려고합니다. Access Ticket은 리소스 범위 인 새 범위를 만들고 ScopeClaim으로 Ticket을 포함하여 항상 액세스 토큰에 포함되어야합니다. 그러나 IdSrv가 액세스 토큰을 만들 때 GetProfileDataAsync을 호출 할 때 IdSrv 로그에서 볼 수 있듯이 컨텍스트에서 요청 된 클레임 목록이 비어 있으며 액세스 토큰에 클레임이 추가되지 않습니다.Authorize 엔드 포인트에서 검색 한 액세스 토큰에 클레임을 포함하려면 어떻게합니까?

어떻게이 클레임을 기본적으로 액세스 토큰에 포함시킬 수 있습니까?

Resource 범위를 요청하면 해당 범위의 클레임을 액세스 토큰의 일부로 반환 할 수 있습니다.

스코프

 public static List<Scope> Get() 
     { 
      return new List<Scope> 
      { 
       StandardScopes.OpenId //standard scope when dealing with open id connect 
       , 
       StandardScopes.OfflineAccess 
       , 
       new Scope 
       { 
        Name = "App", 
        DisplayName = "App", 
        Type = ScopeType.Identity, 
        Claims = new List<ScopeClaim> 
        { 
         new ScopeClaim 
         { 
          AlwaysIncludeInIdToken = false, 
          Name = "App", 
          Description = "Role Information" 
         }, 
//      new ScopeClaim 
//      { 
//       AlwaysIncludeInIdToken = false, 
//       Name = "Ticket", 
//       Description = "Login ticket" 
//      } 
        }, 
        IncludeAllClaimsForUser = false 
       }, 
       new Scope 
       { 
        Name = "AppAccess", 
        DisplayName = "AppAccess", 
        Type = ScopeType.Resource, 
        Claims = new List<ScopeClaim> 
        { 
         new ScopeClaim 
         { 
          Name = "Ticket", 
          Description = "Login ticket", 
         } 
        }, 
        IncludeAllClaimsForUser = true 
       } 
      }; 

주장

public static List<Client> Get() 
    { 
     return new List<Client> 
     { 
      new Client 
      { 
       ClientName = "Hybrid Flow", 
       ClientId = "apphybrid", 
       Enabled = true, 
       Flow = Flows.Hybrid, 
       AllowAccessToAllScopes = true, 
       IdentityTokenLifetime = 120, 
       AccessTokenLifetime = 400, 
       RequireConsent = false, 
       ClientSecrets = new List<Secret> 
       { 
        new Secret("secret".Sha256()) 
       }, 
       RedirectUris = new List<string> 
       { 
        "localhost/App/login/Login.mr" 
       }, 
       PostLogoutRedirectUris = new List<string> 
       { 
        "localhost/App/login/Login.mr" 
       }, 
       AllowedScopes = new List<string> 
       { 
        Constants.StandardScopes.OpenId, 
        Constants.StandardScopes.OfflineAccess, 
        "App", 
        "AppAccess" 
       } 
      } 
     }; 
    } 

IDSrv 구성

public override Task AuthenticateLocalAsync(LocalAuthenticationContext context) 
     { 
      var securityServiceProxy = new SecurityServiceProxy(new ServiceHeadersParameters { UserHostAddress = Ctx.Request.Host.Value }); 

      var ticket = securityServiceProxy.UseServiceClient(serviceClient => serviceClient.AuthenticateUser(context.UserName, context.Password, Configuration.ProviderCode)); 

      if (!ticket.IsValid()) 
      { 
       context.AuthenticateResult = new AuthenticateResult("Invalid credentials"); 
       return Task.FromResult(0); 
      } 

      var claims = new List<Claim> { 
       new Claim(GlobalConstant.TicketClaim, ticket.Ticket.ToString()) 
      }; 

      context.AuthenticateResult = new AuthenticateResult(
       ticket.UserObjId.ToString(), 
       context.UserName, 
       claims: claims, 
       authenticationMethod: Constants.AuthenticationMethods.Password, 
       identityProvider: Configuration.ProviderCode 
       ); 

      return Task.FromResult(0); 
     } 

     public override Task GetProfileDataAsync(ProfileDataRequestContext context) 
     { 
      var applicationDto = GetApplicationDto(context); 

      var claims = new List<Claim> 
      { 
       new Claim(Constants.ClaimTypes.Subject, context.Subject.GetSubjectId()), 
      }; 

      Log.Debug("The requested claims..."); 
      if (context.RequestedClaimTypes == null) 
      { 
       Log.Debug("Requested Claims is null"); 
      } 
      else 
      { 
       foreach (var x in context.RequestedClaimTypes) 
       { 
        Log.Debug($"Claims {x}"); 
       } 

       if (context.RequestedClaimTypes.Contains(GlobalConstant.TicketClaim)) 
        claims.Add(context.Subject.Claims.Where(x => x.Type.Equals(GlobalConstant.TicketClaim)).FirstOrDefault()); 

       if (context.RequestedClaimTypes.Contains(GlobalConstant.ApplicationClaim)) 
        claims.Add(new Claim(GlobalConstant.ApplicationClaim, applicationDto.Jsonify())); 
      } 

      // set the issued claims - these are the ones that were requested, if available 
      context.IssuedClaims = claims; 
      Log.Debug("Finished ProfileDataAsync"); 
      return Task.FromResult(0); 
     } 

     private ApplicationDto GetApplicationDto(ProfileDataRequestContext context) 
     { 
      var securityServiceProxy = new SecurityServiceProxy(new ServiceHeadersParameters { UserHostAddress = Ctx.Request.Host.Value }); 

      return securityServiceProxy.UseServiceClient(serviceClient => serviceClient.RetrieveAuthenticatedUser(GetUserTicketFromContext(context))); 
     } 

     private static UserTicketDto GetUserTicketFromContext(ProfileDataRequestContext context) 
     { 
      Log.Debug("The claims in the context..."); 
      foreach(var x in context.Subject.Claims) 
      { 
       Log.Debug($"Cliams {x.Type} {x.Value}"); 
      } 

      var ticketString = context.Subject.Claims.Where(x => x.Type.Equals(GlobalConstant.TicketClaim)).FirstOrDefault()?.Value; 
      var userIdString = context.Subject.GetSubjectId(); 

      Guid Ticket, UserId; 

      if(Guid.TryParse(ticketString, out Ticket) && Guid.TryParse(userIdString, out UserId)) 
      { 
       return new UserTicketDto { Ticket = Ticket, UserObjId = UserId }; 
      } 

      return new UserTicketDto(); 
     } 

웹 설정

JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); 

    AntiForgeryConfig.UniqueClaimTypeIdentifier = IdentityModel.JwtClaimTypes.Name; 

    app.Use(async (ctx, next) => { await next(); }); 

    app.UseCookieAuthentication(new CookieAuthenticationOptions 
    { 
     AuthenticationType = "cookies" 
    }); 

    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions 
    { 
     ClientId = OAuthConstant.Client, 
     RedirectUri = "localhost/App/login/Login.mr", 
     PostLogoutRedirectUri = "localhost/App/login/Login.mr", 
     Authority = "localhost/Oauth2server/securetoken", 
     SignInAsAuthenticationType = "Cookies", 
     ResponseType = "token code id_token", 
     Scope = "OpenId App offline_access AppAccess", 
     ClientSecret = "secret", 
     UseTokenLifetime = false, 
     Notifications = new OpenIdConnectAuthenticationNotifications() 
     { 
      AuthorizationCodeReceived = IdentityServerClient.HandleOther, 
      SecurityTokenReceived = IdentityServerClient.HandleOther, 
      MessageReceived = IdentityServerClient.HandleOther, 
      AuthenticationFailed = IdentityServerClient.HandleOther, 
      RedirectToIdentityProvider = IdentityServerClient.HandleRedirectToIdentityProvider, 
      SecurityTokenValidated = IdentityServerClient.HandleSecurityTokenValidated 
     } 
    }); 

로그

2016-06-15 12:04:51.943 -05:00 [Information] Login page submitted 
2016-06-15 12:04:55.320 -05:00 [Information] Login credentials successfully validated by user service 
2016-06-15 12:04:55.332 -05:00 [Information] Calling PostAuthenticateAsync on the user service 
2016-06-15 12:04:55.338 -05:00 [Information] issuing primary signin cookie 
2016-06-15 12:04:55.344 -05:00 [Information] redirecting to: http://localhost/OAuth2Server/securetoken/connect/authorize?client_id=apphybrid&redirect_uri=http:%2F%2Flocalhost%2Fapp%2FLogin%2FLogin.mr&response_mode=form_post&response_type=code id_token token&scope=App openid offline_access AppAccess&state=OpenIdConnect.AuthenticationProperties%3DebxFcJnjMiMq2m1gPqBsYlrBWdLct2kaJSYn-s0nxImnff-37i4t8Wa3wAJewJGFe9msgeeqJDKtR1gwwfA0e8Pdd6RNAi6YPo_CqT4l5zV8ifohYQVN9TrWfLXITXuKId9IW2cCeRQL6d8uWfkzSANqAGSbSGJYZ5pgOLULQresbAiJ7N77FgBmgrVtX4hDQuwGGL5vZFCb_C5tjl8_ezH12w8zQfifKuLwjaDmOSGYyo2AqpowQXXeSSSDgKBF&nonce=636016067018002117.MWY4MGVjOWItYTFjYS00MTVlLTg4MDYtMjYxYjkwMWEzNzU4ZWViNzEyNTQtMjE0Mi00MjYzLTk2ZjMtODdhYmIxYTM5Mjg5 
2016-06-15 12:04:55.368 -05:00 [Debug] Incoming request: /securetoken/connect/authorize 
2016-06-15 12:04:55.381 -05:00 [Information] Start authorize request 
2016-06-15 12:04:55.381 -05:00 [Information] Start authorize request protocol validation 
2016-06-15 12:04:55.381 -05:00 [Information] "Authorize request validation success" 
"{ 
    \"ClientId\": \"apphybrid\", 
    \"ClientName\": \"app Hybrid Flow\", 
    \"RedirectUri\": \"http://localhost/app/Login/Login.mr\", 
    \"AllowedRedirectUris\": [ 
    \"http://localhost/app/Login/Login.mr\" 
    ], 
    \"SubjectId\": \"783bf872-b864-4042-853d-04fbcb7a505a\", 
    \"ResponseType\": \"code id_token token\", 
    \"ResponseMode\": \"form_post\", 
    \"Flow\": \"Hybrid\", 
    \"RequestedScopes\": \"app openid offline_access appAccess\", 
    \"State\": \"OpenIdConnect.AuthenticationProperties=ebxFcJnjMiMq2m1gPqBsYlrBWdLct2kaJSYn-s0nxImnff-37i4t8Wa3wAJewJGFe9msgeeqJDKtR1gwwfA0e8Pdd6RNAi6YPo_CqT4l5zV8ifohYQVN9TrWfLXITXuKId9IW2cCeRQL6d8uWfkzSANqAGSbSGJYZ5pgOLULQresbAiJ7N77FgBmgrVtX4hDQuwGGL5vZFCb_C5tjl8_ezH12w8zQfifKuLwjaDmOSGYyo2AqpowQXXeSSSDgKBF\", 
    \"Nonce\": \"636016067018002117.MWY4MGVjOWItYTFjYS00MTVlLTg4MDYtMjYxYjkwMWEzNzU4ZWViNzEyNTQtMjE0Mi00MjYzLTk2ZjMtODdhYmIxYTM5Mjg5\", 
    \"SessionId\": \"e79cd97a339b4513b45038e7755c1b88\", 
    \"Raw\": { 
    \"client_id\": \"apphybrid\", 
    \"redirect_uri\": \"http://localhost/app/Login/Login.mr\", 
    \"response_mode\": \"form_post\", 
    \"response_type\": \"code id_token token\", 
    \"scope\": \"app openid offline_access appAccess\", 
    \"state\": \"OpenIdConnect.AuthenticationProperties=ebxFcJnjMiMq2m1gPqBsYlrBWdLct2kaJSYn-s0nxImnff-37i4t8Wa3wAJewJGFe9msgeeqJDKtR1gwwfA0e8Pdd6RNAi6YPo_CqT4l5zV8ifohYQVN9TrWfLXITXuKId9IW2cCeRQL6d8uWfkzSANqAGSbSGJYZ5pgOLULQresbAiJ7N77FgBmgrVtX4hDQuwGGL5vZFCb_C5tjl8_ezH12w8zQfifKuLwjaDmOSGYyo2AqpowQXXeSSSDgKBF\", 
    \"nonce\": \"636016067018002117.MWY4MGVjOWItYTFjYS00MTVlLTg4MDYtMjYxYjkwMWEzNzU4ZWViNzEyNTQtMjE0Mi00MjYzLTk2ZjMtODdhYmIxYTM5Mjg5\" 
    } 
}" 
2016-06-15 12:04:55.399 -05:00 [Information] Creating Hybrid Flow response. 
2016-06-15 12:04:55.412 -05:00 [Information] Creating Implicit Flow response. 
2016-06-15 12:04:55.416 -05:00 [Debug] Creating access token 
2016-06-15 12:04:55.424 -05:00 [Debug] Getting ProfileDataAsync 
2016-06-15 12:04:55.436 -05:00 [Debug] The claims in the context... 
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams sub 783bf872-b864-4042-853d-04fbcb7a505a 
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams name dev.guser 
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams amr password 
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams idp IDSRV 
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams auth_time 1466010295 
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams ticket fc05cd84-7756-4ec5-ac3c-53ac6d4d5e2a 
2016-06-15 12:04:55.975 -05:00 [Debug] The requseted claims... 
2016-06-15 12:04:55.976 -05:00 [Debug] Requested Claims Is Null 
2016-06-15 12:04:55.976 -05:00 [Debug] Finished ProfileDataAsync 
2016-06-15 12:04:55.982 -05:00 [Debug] Creating JWT access token 
2016-06-15 12:04:56.049 -05:00 [Debug] Creating identity token 
2016-06-15 12:04:56.054 -05:00 [Information] Getting claims for identity token for subject: 783bf872-b864-4042-853d-04fbcb7a505a 
2016-06-15 12:04:56.054 -05:00 [Debug] Getting ProfileDataAsync 
2016-06-15 12:04:56.066 -05:00 [Debug] The claims in the context... 
2016-06-15 12:04:56.066 -05:00 [Debug] Cliams sub 783bf872-b864-4042-853d-04fbcb7a505a 
2016-06-15 12:04:56.066 -05:00 [Debug] Cliams name dev.guser 
2016-06-15 12:04:56.066 -05:00 [Debug] Cliams amr password 
2016-06-15 12:04:56.066 -05:00 [Debug] Cliams idp IDSRV 
2016-06-15 12:04:56.066 -05:00 [Debug] Cliams auth_time 1466010295 
2016-06-15 12:04:56.066 -05:00 [Debug] Cliams ticket fc05cd84-7756-4ec5-ac3c-53ac6d4d5e2a 
2016-06-15 12:04:56.338 -05:00 [Debug] The requseted claims... 
2016-06-15 12:04:56.338 -05:00 [Debug] Cliams sub 
2016-06-15 12:04:56.338 -05:00 [Debug] Finished ProfileDataAsync 
2016-06-15 12:04:56.338 -05:00 [Debug] Creating JWT identity token 
2016-06-15 12:04:56.344 -05:00 [Debug] Adding client "apphybrid" to client list cookie for subject "783bf872-b864-4042-853d-04fbcb7a505a" 
2016-06-15 12:04:56.349 -05:00 [Information] End authorize request 
2016-06-15 12:04:56.352 -05:00 [Information] Posting to http://localhost/app/Login/Login.mr 
2016-06-15 12:04:56.352 -05:00 [Debug] Using AssetManager to render authorization response HTML 
2016-06-15 12:04:56.388 -05:00 [Debug] Incoming request: /securetoken/assets/app.FormPostResponse.js 

//Web 
2016-06-15 12:04:56,422 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Triggered MessageReceivedNotification`2 notification 
2016-06-15 12:04:56,426 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Triggered SecurityTokenReceivedNotification`2 notification 
2016-06-15 12:04:56,487 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Triggered SecurityTokenValidated notification 
2016-06-15 12:04:56,487 [16] DEBUG app.Web.IdentityServer.IdentityServerClient The Claims in the identity 
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: iss http://localhost/OAuth2Server/securetoken 
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: aud apphybrid 
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: exp 1466010416 
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: nbf 1466010296 
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: nonce 636016067018002117.MWY4MGVjOWItYTFjYS00MTVlLTg4MDYtMjYxYjkwMWEzNzU4ZWViNzEyNTQtMjE0Mi00MjYzLTk2ZjMtODdhYmIxYTM5Mjg5 
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: iat 1466010296 
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: at_hash 6pIu3P1cEeTQJMcK8Gcnhw 
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: c_hash VsSw9HC0xyodlSkSCZefLw 
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: sid e79cd97a339b4513b45038e7755c1b88 
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: sub 783bf872-b864-4042-853d-04fbcb7a505a 
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: auth_time 1466010295 
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: idp IDSRV 
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: amr password 
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient The access token: [Omitted] 
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient The id token: [Omitted] 
2016-06-15 12:04:56,491 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Triggered AuthenticationFailedNotification`2 notification 
//Web 

//Logs 

문제의 로그 출력 ...

2016-06-15 12:04:55.412 -05:00 [Information] Creating Implicit Flow response. 
2016-06-15 12:04:55.416 -05:00 [Debug] Creating access token 
2016-06-15 12:04:55.424 -05:00 [Debug] Getting ProfileDataAsync 
2016-06-15 12:04:55.436 -05:00 [Debug] The claims in the context... 
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams sub 783bf872-b864-4042-853d-04fbcb7a505a 
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams name dev.guser 
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams amr password 
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams idp IDSRV 
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams auth_time 1466010295 
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams ticket fc05cd84-7756-4ec5-ac3c-53ac6d4d5e2a <- Has the claim I want 
2016-06-15 12:04:55.975 -05:00 [Debug] The requseted claims... 
2016-06-15 12:04:55.976 -05:00 [Debug] Requested Claims Is Null <- but this needs to indicate that we want that claim... 
2016-06-15 12:04:55.976 -05:00 [Debug] Finished ProfileDataAsync 

답변

1

업데이트 2 : 좋아, 지금은 자세히 보면, 당신은 IncludeAllClaimsForUser = true 있습니다. GetProfileData에는 문맥에 비슷한 플래그가 있습니다. 그게 네가 수집품에 클레임이없는 이유 인 것 같아.

업데이트 1 : 토큰에 들어가려는 요청은 메서드의 AuthenticateResult이 아닌 GetProfile에 추가해야합니다.

원본 : 범위 유형을 Identity에서 Resource으로 변경하십시오. 이것은 클레임이 들어간 토큰에 영향을 미칩니다.

+0

범위 유형이'AppAccess' 범위의 'Resource'입니다. –

+0

아, App 범위를보고있었습니다. –

+0

아마도 질문에 대답하도록 업데이트되었습니다. –

관련 문제