我有一个asp.net WebAPI项目来提供REST服务,在这里我使用以下程序包来创建和使用JWT令牌来进行承载者身份验证/授权。
<package id="Microsoft.Owin.Security" version="4.0.0" targetFramework="net47" />
<package id="Microsoft.Owin.Security.Jwt" version="3.1.0" targetFramework="net47" />
<package id="Microsoft.Owin.Security.OAuth" version="4.0.0" targetFramework="net47" />
我将其配置如下。
OAuthAuthorizationServerOptions oauthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString(TokenEndPoint),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(config.SecuritySettings.AccessTokenExpiryMins ?? 1),
Provider = new AuthorisationServerProvider(servicesFacade, securityDataRepository, resourceProvider, m_logger),
AccessTokenFormat = new CustomJwtFormat(config, resourceProvider, m_logger),
RefreshTokenProvider = new RefreshTokenProvider(securityDataRepository, config.SecuritySettings, m_logger),
};
app.UseOAuthAuthorizationServer(oauthServerOptions);
OAuthBearerAuthenticationOptions bearerOptions = new OAuthBearerAuthenticationOptions
{
AccessTokenFormat = oauthServerOptions.AccessTokenFormat,
AccessTokenProvider = oauthServerOptions.AccessTokenProvider,
AuthenticationMode = oauthServerOptions.AuthenticationMode,
AuthenticationType = oauthServerOptions.AuthenticationType,
Description = oauthServerOptions.Description,
SystemClock = oauthServerOptions.SystemClock
};
app.UseOAuthBearerAuthentication(bearerOptions);
var issuer = config.SecuritySettings.AudienceId;
byte[] audienceSecret = System.Text.Encoding.Unicode.GetBytes(config.SecuritySettings.AudienceSecret);
// API controllers with an [Authorize] attribute will be validated with JWT
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
{
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
AllowedAudiences = new[] {config.SecuritySettings.AudienceId},
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
{
new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret)
},
});
在CustomJwtFormat
中,我重写了Protect
和Unprotect
方法。
Unprotect方法的实现如下。
public AuthenticationTicket Unprotect(string protectedText)
{
var handler = new JwtSecurityTokenHandler();
ClaimsPrincipal principal;
try
{
SecurityToken validToken;
principal = handler.ValidateToken(protectedText, m_tokenValidationParameters, out validToken);
var validJwt = validToken as JwtSecurityToken;
if (validJwt == null)
throw new ArgumentException(m_resourceProvider.GetInvalidJwtError().ToString());
if (!validJwt.Header.Alg.Equals(SigningAlgorithm, StringComparison.Ordinal))
throw new ArgumentException(m_resourceProvider.GetInvalidJwtAlgorithmError().ToString());
// Additional custom validation of JWT claims here (if any)
}
catch (SecurityTokenValidationException ex)
{
m_logger.WriteInformation(ex.ToString());
return null;
}
catch (ArgumentException aex)
{
m_logger.WriteError(aex.ToString());
return null;
}
// Validation passed. Return a valid AuthenticationTicket:
return new AuthenticationTicket(principal.Identities.FirstOrDefault(), new AuthenticationProperties());
}
}
我想做的是,当Unprotect失败(例如令牌不再有效)时,我想为返回的错误提供自己的json模式,以匹配我的应用程序的其余部分,而不是其他内容图书馆用品。
我已经尝试了所有我能想到的东西(ExceptionFilters,Handlers等),但是看不到如何做到这一点。
有办法做到这一点吗?
在此先感谢您的帮助。