[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番目の方法は実行時にキーを取得するため、キーのロールオーバーにはサービスの再起動は必要ありません。