0

Identity Provider를 Identity Provider로 사용하고 OWIN Katana 미들웨어를 사용하여 OpenId Connect를 기반으로 핸드 셰이크를 수행합니다. 신원 확인 서버로 리디렉션되고 원래 웹 사이트로 돌아 가면 인증이 제대로 작동합니다. 하지만 invalid_client 문제는 ​​토큰을 검색하고 "OpenIdConnectAuthenticationNotifications"에서 클레임을 가져 오려고 할 때 나타납니다.IdentityServer3 : 토큰을 얻을 수 없으므로 OWIN Katana 미들웨어에서 "invalid_client"오류가 발생합니다.

아래의 코드 (시작 클래스)와 첨부 된 스크린 샷을 확인하십시오.

enter image description here

IdSvr3에서 클라이언트 구성

public sealed class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     string ClientUri = @"https://client.local"; 
     string IdServBaseUri = @"https://idm.website.com/core";l 
     string TokenEndpoint = @"https://idm.website.com/core/connect/token"; 
     string UserInfoEndpoint = @"https://idm.website.com/core/connect/userinfo"; 
     string ClientId = @"WebPortalDemo"; 
     string ClientSecret = @"aG90apW2+DbX1wVnwwLD+eu17g3vPRIg7p1OnzT14TE="; 

     //AntiForgeryConfig.UniqueClaimTypeIdentifier = "sub"; 
     JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); 

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

     app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions 
     { 
      ClientId = ClientId, 
      Authority = IdServBaseUri, 
      RedirectUri = ClientUri, 
      PostLogoutRedirectUri = ClientUri, 
      ResponseType = "code id_token token", 
      Scope = "openid profile roles", 
      TokenValidationParameters = new TokenValidationParameters 
      { 
       NameClaimType = "name", 
       RoleClaimType = "role" 
      }, 
      SignInAsAuthenticationType = "Cookies", 

      Notifications = new OpenIdConnectAuthenticationNotifications 
      { 
       AuthorizationCodeReceived = async n => 
       { 
        // use the code to get the access and refresh token 
        var tokenClient = new TokenClient(
         TokenEndpoint, 
         ClientId, 
         ClientSecret); 

        var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, n.RedirectUri); 

        if (tokenResponse.IsError) 
        { 
         throw new Exception(tokenResponse.Error); 
        } 

        // use the access token to retrieve claims from userinfo 
        var userInfoClient = new UserInfoClient(UserInfoEndpoint); 

        var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken); 

        // create new identity 
        var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType); 
        //id.AddClaims(userInfoResponse.GetClaimsIdentity().Claims); 
        id.AddClaims(userInfoResponse.Claims); 

        id.AddClaim(new Claim("access_token", tokenResponse.AccessToken)); 
        id.AddClaim(new Claim("expires_at", DateTime.Now.AddSeconds(tokenResponse.ExpiresIn).ToLocalTime().ToString())); 
        id.AddClaim(new Claim("refresh_token", tokenResponse.RefreshToken)); 
        id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); 
        id.AddClaim(new Claim("sid", n.AuthenticationTicket.Identity.FindFirst("sid").Value)); 

        n.AuthenticationTicket = new AuthenticationTicket(
         new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType, "name", "role"), 
         n.AuthenticationTicket.Properties); 
       }, 

       RedirectToIdentityProvider = n => 
       { 
        // if signing out, add the id_token_hint 
        if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) 
        { 
         var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token"); 

         if (idTokenHint != null) 
         { 
          n.ProtocolMessage.IdTokenHint = idTokenHint.Value; 
         } 

        } 

        return Task.FromResult(0); 
       } 
      } 

     }); 
    } 
} 

는 하이브리드 흐름 사용하도록 지정되어 나는 클라이언트 ID와 클라이언트 비밀 많은 시간이 올바른지 확인하는 것을 확인했다.

enter image description here

+1

신원 서버 로그는 무엇을 말하는가? – rawel

+0

ID 서버 로그는 어디에서 찾을 수 있습니까? – TejSoft

+1

https://identityserver.github.io/Documentation/docsv2/configuration/logging.html – rawel

답변

0

I 신원 서버에 의해 생성 된 로그를보고 문제를 해결할 수 있었다 : 여기

는 서버 측에서 클라이언트 구성입니다. 로그에는 신원 확인 서버에 표시되는 내용과 정확히 일치하는지 여러 번 확인했을 때 클라이언트 비밀이 잘못되었다고 기록되어 있습니다. 하지만 그때 그 비밀은 실제 텍스트가 아니라 해시 된 것이어야한다는 것을 깨달았습니다. 일 수정 된 코드는 다음과 같습니다 :

string ClientId = @"WebPortalDemo"; 
//string ClientSecret = @"aG90apW2+DbX1wVnwwLD+eu17g3vPRIg7p1OnzT14TE="; // Incorrect secret, didn't work 
string ClientSecret = @"love"; // Actual text entered as secret, worked 

제공 : @rawel