IdentityServer4 自定义 AuthorizeInteractionResponseGenerator

问题描述 投票:0回答:1

遗憾的是,非常缺乏关于在 IdentityServer4 中实现自定义

AuthorizeInteractionResponseGenerator
的文档。

我正在尝试实现我自己的

AuthorizeInteractionResponseGenerator
,因为我需要进一步的用户交互步骤(在身份验证之后)。我的场景是单个身份(电子邮件)可以与多个租户相关联。所以在登录后,我需要向用户显示相关租户列表,以便他们可以选择一个。

我评估了源代码,并提出了以下自定义

AuthorizeInteractionResponseGenerator

public class AccountChooserResponseGenerator : AuthorizeInteractionResponseGenerator
    {
        public AccountChooserResponseGenerator(ISystemClock clock, 
            ILogger<AuthorizeInteractionResponseGenerator> logger, 
            IConsentService consent, IProfileService profile) 
            : base(clock, logger, consent, profile)
        {
        }

        public override async Task<InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
        {
            var response = await base.ProcessInteractionAsync(request, consent);
            if (response.IsConsent || response.IsLogin || response.IsError)
                return response;

            return new InteractionResponse
            {
                RedirectUrl = "/Organization"
            };
        }
    }

它继承自IdentityServer4内置的基础AuthorizeInteractionResponseGenerator,因此可以显示标准的登录和同意页面。发生这种情况,然后用户被正确重定向到

/Organization
url 以选择一个组织(租户)。

然后呢?由于缺乏文档和示例,我真的很难弄清楚以下两个问题:

1) 我现在如何在选择租户后向我的自定义 AccountChooserResponseGenerator 指示我的交互已完成,并且现在可以将用户重定向回客户端?

编辑:

回答1:表示交互完成,你我要返回一个空的new InteractionResponse()。在我的例子中,检查 TenantId 声明是否存在就足够了,如下所示:

if (!request.Subject.HasClaim(c=> c.Type == "TenantId" && c.Value != "0"))
                return new InteractionResponse
                {
                    RedirectUrl = "/Organization"
                };

            return new InteractionResponse();

2) 我怎样才能获得有关所选租户的信息以添加到 IdentityServer4 传递回客户端的身份令牌中?

编辑:对 2 的回答:在选择租户后执行的控制器操作方法中,我调用了:

 await HttpContext.SignInAsync(User.Claims.Single(r=> r.Type == "sub").Value,
                new System.Security.Claims.Claim("TenantId", tenant.Id.ToString()));

            return Redirect(ReturnUrl);

...这是 IdentityServer4 提供的 HttpContext 扩展

c# identityserver4
1个回答
0
投票

要在 IdentityServer4 中实现自定义交互响应生成器并将有关所选租户的信息添加到身份令牌,您可以从基础 AuthorizeInteractionResponseGenerator 继承并覆盖 ProcessInteractionAsync 方法。也可以使用IdentityServer4提供的IProfileService接口,在签发token前,将租户信息作为用户身份的声明添加

实现自定义交互响应生成器的步骤:

继承自基础 AuthorizeInteractionResponseGenerator 并覆盖 ProcessInteractionAsync 方法:

// Example implementation of ProcessInteractionAsync
public override async Task<InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
{
    // Your custom logic here

    // Indicate that the interaction is complete
    return new InteractionResponse();
}

将有关所选租户的信息添加到身份令牌:

// Example implementation of IProfileService
public class CustomProfileService : IProfileService
{
    private readonly UserManager<ApplicationUser> _userManager;

    public CustomProfileService(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }

    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var user = await _userManager.GetUserAsync(context.Subject);
        if (user != null)
        {
            var tenantIdClaim = user.Claims.FirstOrDefault(c => c.Type == "TenantId");
            if (tenantIdClaim != null)
            {
                context.IssuedClaims.Add(new Claim("tenant_id", tenantIdClaim.Value));
            }
        }
    }

    public Task IsActiveAsync(IsActiveContext context)
    {
        return Task.CompletedTask;
    }
}

在 Startup.cs 文件中使用 IdentityServer4 注册 CustomProfileService:

services.AddTransient<IProfileService, CustomProfileService>();

温馨提示:

  1. 从 IdentityServer4 覆盖方法时,总是首先调用基类方法。
  2. 检查请求对象以获取有关当前流程的详细信息。
  3. 将 DEBUG 级别日志记录到标准输出以跟踪通过您的自定义逻辑的流程。 使用注入到生成器中的 IConsentService 和 IProfileService 来访问用户配置文件和许可数据。 检查用于编译源代码的 IdentityServer 构建说明,因为它使调试更容易!
© www.soinside.com 2019 - 2024. All rights reserved.