2017-05-25 14 views
1

私はOAuthクマトークン認証を使用してREST APIを持っています。トークンは非対称キーで署名され、REST APIは公開キーを使用してトークンを検証します。私は以下のようなコードの作業を得た。しかし、キーを更新する必要があるときに対処する必要があるケースがあります。私は二次公開鍵を渡して、フレームワークが主キーと二次キーを使用してトークンを最初に検証するように考えています。このようにして、私はキーを更新する必要があるときに、簡単に二次キーを追加し、スワップしてリタイアすることができます。問題は、下のコードでは署名キーが1つしかないことを確認しています。複数を指定する方法はありますか?UseJwtBearerAuthenticationで複数のIssuerSigningKeyを指定する方法は?

public void ConfigureAuth(IAppBuilder app) 
    { 
     app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 

     // codes to get signningKey ignored here 

     app.UseJwtBearerAuthentication(
      new JwtBearerAuthenticationOptions 
      { 
       TokenValidationParameters = new TokenValidationParameters 
       { 
        ValidateAudience = false, 
        ValidateIssuer = false, 
        IssuerSigningKey = new RsaSecurityKey(signingKey) 
       }, 
      }); 
    } 

おかげで、

答えて

0

[OK]を、私はそれを考え出したと思います。 2つの方法があります。単純に単純な方法は、IssuerSigningKeysプロパティを使用することです(どのように最初の場所でそれを発見できないか)。コードは次のようになります。

 app.UseJwtBearerAuthentication(
      new JwtBearerAuthenticationOptions 
      { 
       TokenValidationParameters = new TokenValidationParameters 
       { 
        ValidateAudience = false, 
        ValidateIssuer = false, 
        IssuerSigningKeys = new List<RsaSecurityKey> 
        { 
         Utils.GetSigningKey(isPrimary: true), 
         Utils.GetSigningKey(isPrimary: false) 
        }, 
       }, 
      }); 

2番目の方法は、IOAuthBearerAuthenticationProviderをカスタマイズすることです。コードは次のようになります。まず、

 app.UseJwtBearerAuthentication(
      new JwtBearerAuthenticationOptions 
      { 
       AllowedAudiences = new string[] { "*" }, 
       IssuerSecurityTokenProviders = new List<IIssuerSecurityTokenProvider>() 
       { 
        // Dummy object which won't be used anywhere. It is used to work around parameter validation error about no token provider specified. 
        new SymmetricKeyIssuerSecurityTokenProvider("dummy", "dummy") 
       }, 

       // This is where validation work happens. 
       Provider = new BearerAuthenticationProvider(app) 
      }); 

その後、BearerAuthenticationProviderクラス:

/// <summary> 
/// Bearer authentication provider. 
/// </summary> 
public class BearerAuthenticationProvider : IOAuthBearerAuthenticationProvider 
{ 
    /// <summary> 
    /// App config. 
    /// </summary> 
    private readonly IAppBuilder appConfig; 

    /// <summary> 
    /// Handles applying the authentication challenge to the response message. 
    /// </summary> 
    public Func<OAuthChallengeContext, Task> OnApplyChallenge { get; set; } 

    /// <summary> 
    /// Handles processing OAuth bearer token. 
    /// </summary> 
    public Func<OAuthRequestTokenContext, Task> OnRequestToken { get; set; } 

    /// <summary> 
    /// Handles validating the identity produced from an OAuth bearer token. 
    /// </summary> 
    public Func<OAuthValidateIdentityContext, Task> OnValidateIdentity { get; set; } 

    /// <summary> 
    /// Initializes a new instance of the <see cref="T:Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationProvider" /> class 
    /// </summary> 
    public BearerAuthenticationProvider(IAppBuilder appConfig) 
    { 
     this.appConfig = appConfig; 
     this.OnRequestToken = (OAuthRequestTokenContext context) => 
     { 
      var idContext = new OAuthValidateIdentityContext(context.OwinContext, null, null); 

      this.ValidateIdentity(idContext); 
      return Task.FromResult<int>(0); 
     }; 
     this.OnValidateIdentity = (OAuthValidateIdentityContext context) => Task.FromResult<object>(null); 
     this.OnApplyChallenge = (OAuthChallengeContext context) => Task.FromResult<object>(null); 
    } 

    /// <summary> 
    /// Handles applying the authentication challenge to the response message. 
    /// </summary> 
    /// <param name="context"></param> 
    /// <returns></returns> 
    public Task ApplyChallenge(OAuthChallengeContext context) 
    { 
     return this.OnApplyChallenge(context); 
    } 

    /// <summary> 
    /// Handles processing OAuth bearer token. 
    /// </summary> 
    /// <param name="context"></param> 
    /// <returns></returns> 
    public virtual Task RequestToken(OAuthRequestTokenContext context) 
    { 
     return this.OnRequestToken(context); 
    } 

    /// <summary> 
    /// Handles validating the identity produced from an OAuth bearer token. 
    /// </summary> 
    /// <param name="context"></param> 
    /// <returns></returns> 
    public virtual Task ValidateIdentity(OAuthValidateIdentityContext context) 
    { 
     const string AuthHeaderName = "Authorization"; 
     if (context.Request.Headers.ContainsKey(AuthHeaderName)) 
     { 
      var jwt = context.Request.Headers[AuthHeaderName].Replace("Bearer ", string.Empty); 
      var token = new JwtSecurityToken(jwt); 
      var claimIdentity = new ClaimsIdentity(token.Claims, "ExternalBearer"); 

      var param = new TokenValidationParameters() 
      { 
       ValidateAudience = false, 
       ValidateIssuer = false, 
       IssuerSigningKeys = new List<RsaSecurityKey> 
       { 
        Utils.GetSigningKey(isPrimary: true), 
        Utils.GetSigningKey(isPrimary: false) 
       }, 
      }; 

      SecurityToken securityToken = null; 
      var handler = new JwtSecurityTokenHandler(); 
      var identity = handler.ValidateToken(token.RawData, param, out securityToken); 

      var claimPrincipal = new ClaimsPrincipal(claimIdentity); 
      context.Response.Context.Authentication.User = claimPrincipal; 
      context.Validated(claimIdentity); 
     } 
     else 
     { 
      throw new Exception("Invalid authorization header."); 
     } 

     return this.OnValidateIdentity(context); 
    } 
} 

最初のアプローチは、アプリの起動時に2つの署名鍵を初期化したときに、プロセスの再起動変更を行うための唯一の方法です。 2番目の方法は実行時にキーを取得するため、キーのロールオーバーにはサービスの再起動は必要ありません。

関連する問題