IdentityServer4
IdentityServer4:2.3.2版本基于資料庫的請求token失效
- 這個問題出現在2.3.2版本内,我去看了下源碼,原因如下:
/// <summary>
/// Adds the validators.
/// </summary>
/// <param name="builder">The builder.</param>
/// <returns></returns>
public static IIdentityServerBuilder AddValidators(this IIdentityServerBuilder builder)
{
// core
builder.Services.TryAddTransient<IEndSessionRequestValidator, EndSessionRequestValidator>();
builder.Services.TryAddTransient<ITokenRevocationRequestValidator, TokenRevocationRequestValidator>();
builder.Services.TryAddTransient<IAuthorizeRequestValidator, AuthorizeRequestValidator>();
builder.Services.TryAddTransient<ITokenRequestValidator, TokenRequestValidator>();
builder.Services.TryAddTransient<IRedirectUriValidator, StrictRedirectUriValidator>();
builder.Services.TryAddTransient<ITokenValidator, TokenValidator>();
builder.Services.TryAddTransient<IIntrospectionRequestValidator, IntrospectionRequestValidator>();
builder.Services.TryAddTransient<IResourceOwnerPasswordValidator, NotSupportedResourceOwnerPasswordValidator>();
builder.Services.TryAddTransient<ICustomTokenRequestValidator, DefaultCustomTokenRequestValidator>();
builder.Services.TryAddTransient<IUserInfoRequestValidator, UserInfoRequestValidator>();
builder.Services.TryAddTransient<IClientConfigurationValidator, DefaultClientConfigurationValidator>();
builder.Services.TryAddTransient<IDeviceAuthorizationRequestValidator, DeviceAuthorizationRequestValidator>();
builder.Services.TryAddTransient<IDeviceCodeValidator, DeviceCodeValidator>();
// optional
builder.Services.TryAddTransient<ICustomTokenValidator, DefaultCustomTokenValidator>();
builder.Services.TryAddTransient<ICustomAuthorizeRequestValidator, DefaultCustomAuthorizeRequestValidator>();
return builder;
}
- 重點在這裡:
builder.Services.TryAddTransient<IResourceOwnerPasswordValidator, NotSupportedResourceOwnerPasswordValidator>();
- NotSupportedResourceOwnerPasswordValidator.cs
public class NotSupportedResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
private readonly ILogger _logger;
/// <summary>
/// Initializes a new instance of the <see cref="NotSupportedResourceOwnerPasswordValidator"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
public NotSupportedResourceOwnerPasswordValidator(ILogger<NotSupportedResourceOwnerPasswordValidator> logger)
{
_logger = logger;
}
/// <summary>
/// Validates the resource owner password credential
/// </summary>
/// <param name="context">The context.</param>
/// <returns></returns>
public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
context.Result = new GrantValidationResult(TokenRequestErrors.UnsupportedGrantType);
_logger.LogInformation("Resource owner password credential type not supported. Configure an IResourceOwnerPasswordValidator.");
return Task.CompletedTask;
}
}
- 可以看到ValidateAsync這裡直接傳回了UnsupportedGrantType,是以說我們要把這個給下。方法如下:
-
修改我們的IdentityServer伺服器的StartUp.cs:
services.AddIdentityServer()
.AddDeveloperSigningCredential()
//.AddTestUsers(Config.GetUsers()) //利用CustomResourceOwnerPasswordValidator和CustomProfileService來完成驗證
// this adds the config data from DB (clients, resources)
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
})
// this adds the operational data from DB (codes, tokens, consents)
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
// this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
options.TokenCleanupInterval = 30;
}).Services.Replace(ServiceDescriptor.Transient<IResourceOwnerPasswordValidator, CustomResourceOwnerPasswordValidator>());
- 這裡我是把IResourceOwnerPasswordValidator的注入服務給替換了一下,用自己的驗證邏輯來做。這個驗證邏輯參考曉晨大神