У меня есть проект 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
.
Метод снятия защиты реализован следующим образом.
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 и т. д.), но просто не могу понять, как это сделать.
Есть ли способ сделать это, иесли да, то как?
Заранее спасибо за любую помощь.