2017-12-06 12 views
1

작동하지 역 직렬화 티켓, 다음 코드는 여기에 ASP.NET API OAuth2를 새로 고침 토큰 - 나는 ASP.NET API2와 OWIN와의 OAuth 2 새로 고침 토큰을 구현하고있어

public static OAuthAuthorizationServerOptions AuthorizationServerOptions 
    { 
     get 
     { 
      if (_AuthorizationServerOptions == null) 
      { 
       _AuthorizationServerOptions = new OAuthAuthorizationServerOptions() 
       { 
        AuthenticationType = OAuthDefaults.AuthenticationType, 
        AllowInsecureHttp = true, 
        TokenEndpointPath = new PathString(AuthSettings.TokenEndpoint), 
        AuthorizeEndpointPath = new PathString(AuthSettings.AuthorizeEndpoint), 
        AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(AuthSettings.TokenExpiry), 
        Provider = new CustomOAuthAuthorizationServerProvider(AuthSettings.PublicClientId), 
        // TODO: Remove the dependency with Thinktecture.IdentityModel library here 
        AccessTokenFormat = new CustomJWTFormat(), 
        RefreshTokenProvider = new CustomRefreshTokenProvider() 
       }; 
      } 
      return _AuthorizationServerOptions; 
     } 
    } 

내 CustomRefreshTokenProvider 클래스 내 OAuthAuthorizationOptions입니다 내가 Postman refresh token 서버 수익 400 잘못된 요청 상태 코드를 다음과 같이 토큰 끝점에 POST 요청을 보내는 우편 배달부를 사용했다

public override Task CreateAsync(AuthenticationTokenCreateContext context) 
    { 
     var identifier = context.Ticket.Identity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier); 
     if (identifier == null || string.IsNullOrEmpty(identifier.Value)) 
     { 
      return Task.FromResult<object>(null); 
     } 
     var refreshToken = HashHelper.Hash(Guid.NewGuid().ToString("n")); 
     var tokenIssued = DateTime.UtcNow; 
     var tokenExpire = DateTime.UtcNow.AddSeconds(AuthSettings.RefreshTokenExpiry); 
     context.Ticket.Properties.IssuedUtc = tokenIssued; 
     context.Ticket.Properties.ExpiresUtc = tokenExpire; 
     context.Ticket.Properties.AllowRefresh = true; 
     var protectedTicket = context.SerializeTicket(); 
     AuthService.AddUserRefreshTokenSession(
      identifier.Value, 
      refreshToken, 
      tokenIssued, 
      tokenExpire, 
      protectedTicket); 
     context.SetToken(refreshToken); 
     return Task.FromResult<object>(null); 
    } 
    public override Task ReceiveAsync(AuthenticationTokenReceiveContext context) 
    { 
     var refToken = context.Token; 
     var protectedTicket = AuthService.GetProtectedTicket(refToken); 
     if (!string.IsNullOrEmpty(protectedTicket)) 
     { 
      context.DeserializeTicket(protectedTicket); 
     } 
     return Task.FromResult<object>(null); 
    } 

. 나는 디버깅과 context.DeserializeTicket (protectedTicket) 나는 그것이 AuthSettings.RefreshTokenExpiry 지금부터 30 일입니다 때문에 만료 문제라고 생각하지 않습니다 예외

Exception thrown: 'System.Security.Cryptography.CryptographicException' in System.Web.dll 

를 던질 것을 발견했다. 또한 내 web.config에 컴퓨터 키를 추가하려고 시도했습니다. OAuth Refresh Token does not deserialize/invalid_grant

여전히 작동하지 않습니다.

누구나 아이디어가 있습니까? 모든 솔루션을 높이 평가할 것입니다.

+0

당신이 해결책을 찾았습니까? 나는 똑같은 문제가 있습니다. –

+0

@Amin K 늦은 응답을 드려 죄송합니다. 방금 대답했습니다. 필요한 것입니까? –

답변

0

늦게 답변드립니다. 당신은 여전히 ​​Thinktecture을 사용할 경우 충돌이 System.IdentityModel.Tokens.JWT.dll

또 다른 방법으로 어떻게 든 이후 나는이 문제를 해결하고 내 프로젝트에서 완전히 Thinktecture.Identity 제거 해결책을 종료 한 .Identity는 System.IdentityModel.Tokens.JWT를 v4.0.2.206221351로 다운 그레이드하는 것입니다 (이 버전은 저에게 효과적이며 다른 버전에서는 테스트하지 않았습니다). 여기

는 CustomJWTFormat.cs

 


    using Microsoft.Owin.Security; 
    using Microsoft.Owin.Security.OAuth; 
    using MST.Service.Core.Logging; 
    using System; 
    using System.Security.Claims; 

    namespace MST.Service.Core.Auth 
    { 
     public class CustomJWTFormat : ISecureDataFormat 
     { 
      private byte[] _SymetricKey = null; 
      public CustomJWTFormat() 
      { 
       _SymetricKey = Convert.FromBase64String(AuthSettings.JwtTokenSecret); 
      } 
      /// 
      /// Create jwt token 
      /// 
      /// 
      /// Token string 
      public string Protect(AuthenticationTicket data) 
      { 
       var tokenHandler = new System.IdentityModel.Tokens.JwtSecurityTokenHandler(); 

       var now = DateTime.UtcNow; 
       System.IdentityModel.Tokens.JwtSecurityToken jwtSecurityToken = new System.IdentityModel.Tokens.JwtSecurityToken(
        AuthSettings.Issuer, 
        AuthSettings.JwtAudiences, 
        data.Identity.Claims, 
        DateTime.UtcNow, 
        DateTime.UtcNow.AddMinutes(AuthSettings.TokenExpiry), 
        new System.IdentityModel.Tokens.SigningCredentials(
         new System.IdentityModel.Tokens.InMemorySymmetricSecurityKey(_SymetricKey), 
        System.IdentityModel.Tokens.SecurityAlgorithms.HmacSha256Signature, 
        System.IdentityModel.Tokens.SecurityAlgorithms.Sha256Digest) 
        ); 
       var token = tokenHandler.WriteToken(jwtSecurityToken); 
       return token; 
      } 

      public AuthenticationTicket Unprotect(string protectedText) 
      { 
       var tokenHandler = new System.IdentityModel.Tokens.JwtSecurityTokenHandler(); 
       var validationParameters = new System.IdentityModel.Tokens.TokenValidationParameters() 
       { 
        RequireExpirationTime = true, 
        ValidateIssuer = true, 
        ValidateLifetime = true, 
        AuthenticationType = OAuthDefaults.AuthenticationType, 
        ValidIssuers = new string[] { AuthSettings.Issuer }, 
        ValidAudiences = new string[] { AuthSettings.JwtAudiences }, 
        ValidateAudience = true, 
        ValidateIssuerSigningKey = false, 
        IssuerSigningKey = new System.IdentityModel.Tokens.InMemorySymmetricSecurityKey(_SymetricKey) 

       }; 
       System.IdentityModel.Tokens.SecurityToken securityToken = null; 

       ClaimsPrincipal principal = null; 
       try 
       { 
        principal = tokenHandler.ValidateToken(protectedText, validationParameters, out securityToken); 
        var validJwt = securityToken as System.IdentityModel.Tokens.JwtSecurityToken; 

        if (validJwt == null) 
        { 
         throw new ArgumentException("Invalid JWT"); 
        } 
       } 
       catch (Exception ex) 
       { 
        LoggerManager.AuthLog.Error($"Parse token error: {ex.ToString()}"); 
        return null; 
       } 

       // Validation passed. Return a valid AuthenticationTicket: 
       return new AuthenticationTicket(principal.Identity as ClaimsIdentity, new AuthenticationProperties()); 
      } 
     } 
    } 

 

및 JWTBearerAuthenticationOptions (동일한 시스템에서 자원 서버 및 인증 서버를 호스팅하는 경우) Startup.cs에서

public static JwtBearerAuthenticationOptions JwtAuthenticationOptions 
    { 
     get 
     { 
      if (_JwtAuthenticationOptions == null) 
      { 
       _JwtAuthenticationOptions = new JwtBearerAuthenticationOptions() 
       { 
        //AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive, 
        AuthenticationType = OAuthDefaults.AuthenticationType, 
        AllowedAudiences = new[] { AuthSettings.JwtAudiences }, 
        IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[] 
        { 
         new SymmetricKeyIssuerSecurityTokenProvider(AuthSettings.Issuer, AuthSettings.JwtTokenSecret) 
        } 
       }; 
      } 
      return _JwtAuthenticationOptions; 
     } 
    } 

단지 등의 미들웨어를 등록의 코드 평소

app.UseJwtBearerAuthentication(AuthenticationOptions.JwtAuthenticationOptions);