Identity Server 4 OIDC 授权_代码流多租户

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

我在使用应用程序(Blazor 服务器/WASM)对 IS4 服务器上的用户进行身份验证时遇到问题。 我的 IDSRV4 与要保护的 API 位于同一应用程序上,每个客户端都有自己的数据库(用于用户和业务模型)。

为了选择好的数据库,我使用了标头,并在 EF Core 上设置了一个拦截器来根据标头值选择数据库。

除了身份验证之外,一切都很好。我正在使用 resource_owner_password 流与 JavaScript 应用程序(安全漏洞,我知道),这允许我为每个调用传递自定义标头(使用我的自定义标头调用 /connect/token)。

现在,通过 authorization_code 流程,我无法设法传递标头来选择好的租户,这意味着好的数据库,这会导致身份验证失败,因为令牌是在用户当前注册的另一个数据库上进行验证的。

我可以在登录过程中通过租户选择数据库(在 IDSRV4 端发布登录信息时),并且我已经在客户端设置了事件,以便在发送回代码以返回 id_token 时添加标头,但我失去了该功能在我的 idp 重定向用户登录 /connect/authorize 后执行此操作(IDSRV4 端似乎没有用于添加自定义标头的扩展)。

因此,我的用户发布了登录数据(带有租户信息),这些数据在重定向到 /connect/authorize 时丢失了,而且我无法对此进行自定义。有机会这样做吗?

将所有用户合并到同一个数据库中不是一个选项。

asp.net-core asp.net-identity identityserver4 openid-connect
2个回答
1
投票

您仍然可以将任何自定义标头添加到托管 Identityserver 的 MVC 应用程序中的任何

HttpResponse

// public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
app.UseCustomHeaders();

//CustomHeadersMiddleware.cs
public static class CustomHeadersMiddlewareExtensions
{
  public static IApplicationBuilder UseCustomHeaders(
    this IApplicationBuilder builder)
  {
    return builder.UseMiddleware<CustomHeadersMiddleware>();
  }
}

public class CustomHeadersMiddleware
{
  private readonly RequestDelegate _next;
  private readonly ILogger<CustomHeadersMiddleware> _logger;

  public CustomHeadersMiddleware(RequestDelegate next, 
    ILogger<CustomHeadersMiddleware> logger)
  {
    _next = next;
    _logger = logger;
  }

  public async Task Invoke(HttpContext context)
  {
    var watch = new Stopwatch();
    watch.Start();

    //To add Headers AFTER everything you need to do this
    context.Response.OnStarting(() =>
    {
      if (!context.Response.Headers.ContainsKey("X-Response-Time-Milliseconds"))
                    context.Response.Headers.Add("X-Response-Time-Milliseconds",
                        new[] {watch.ElapsedMilliseconds.ToString()});

      return Task.FromResult(0);
    });

    await _next(context);
  }
}



0
投票

这是旧帖子,但这就是我处理此案的方式。 您可以在调用授权方法之前将tenantId存储在localstorage中 并在httpLoaderFactory中从localstorage获取tenantId并设置OpenIdConfiguration的customParamsCodeRequest。不幸的是,在代码流上调用authorize()或checkAuth()方法时,我无法传递customParams,这只能通过隐式流实现。

Angular oidc 示例:

localStorage.setItem("tenantId", "my_tenant_id");
this.oidcSecurityService.authorize();

应用程序模块:

export const httpLoaderFactory = (http: HttpClient) => {
    let config$: Observable<OpenIdConfiguration> = new Observable((s) => {
        let tenantId = localStorage.getItem("tenantId") ?? "";
        let c: OpenIdConfiguration = {
            authority: "identityserver",
            redirectUrl: window.location.origin + "/",
            postLogoutRedirectUri: window.location.origin,
            clientId: "aaa",
            scope: "openid profile api1",
            responseType: "code",
            silentRenew: true,
            useRefreshToken: true,
            logLevel: LogLevel.Debug,
            customParamsCodeRequest: { tenantId: tenantId },
        };
        return s.next(c);
    });
    return new StsConfigHttpLoader(config$);
};

AppModule 导入:

imports: [
        ...
        AuthModule.forRoot({
            loader: {
                provide: StsConfigLoader,
                useFactory: httpLoaderFactory,
                deps: [HttpClient],
            },
        }),
    ],
© www.soinside.com 2019 - 2024. All rights reserved.