我有一个IdentityServer4
网站,用作其他网站的OpenIdConnect
授权。
当用户尝试连接时,他们输入登录名和密码,然后重定向到客户端网站。
我想在重定向到站点之前添加一些验证。我尝试使用EventSink,但我不知道如何使用
public class IdentityEventSink : IEventSink
{
private readonly UserManager<Utilisateur> userManager;
private readonly IHttpContextAccessor httpContextAccessor;
public IdentityEventSink(UserManager<Utilisateur> userManager, IHttpContextAccessor httpContextAccessor)
{
this.userManager = userManager;
this.httpContextAccessor = httpContextAccessor;
}
public async Task PersistAsync(Event evt)
{
switch (evt.Id)
{
case EventIds.TokenIssuedSuccess:
var user = await userManager.GetUserAsync(httpContextAccessor.HttpContext.User);
if (!user.IsAllowedToDoThis)
{
//TODO : cancel and redirect to specific page
}
break;
}
}
}
我不确定EventSink是否允许执行此操作,或者是否有更好的方法来执行此操作。
答案 0 :(得分:1)
当您需要在不与用户交互的情况下同步执行检查时,最简单的方法是实施ICustomAuthorizeRequestValidator
。例如,在下面的代码段中,我们检查了当前用户的租户是否不受特定特定应用程序(客户端)的限制,其他服务则显示错误消息而不是重定向。
public Task ValidateAsync(CustomAuthorizeRequestValidationContext context)
{
var request = context.Result.ValidatedRequest;
var identity = request.Subject?.Identity;
var sub = identity?.IsAuthenticated == true ? identity.GetSubjectId() : null;
if (sub != null)
{
var tenantId = _users.GetUserTenant(sub);
if (tenantId != null)
{
var tenantInfo = _tenantService.GetTenantInfoAsync(tenantId).Result;
var subscribedModules = tenantInfo?.Subscription?.Modules?.ToArray() ?? new string[] { };
if (!subscribedModules.Contains((request.Client as WebAppClient).SubscriptionModule))
{
context.Result.Error =
$"Module {(request.Client as WebAppClient).SubscriptionModule} is not in the subscription.";
context.Result.IsError = true;
}
}
}
return Task.CompletedTask;
}
要将自定义验证器添加到DI中,只需将.AddCustomAuthorizeRequestValidator<CustomAuthorizeRequestValidator>()
添加到您的services.AddIdentityServer()
链中。