【问题标题】:IdentityServer4 handle multiple facebook AppIds for tenancyIdentityServer4 处理多个 facebook AppIds 进行租赁
【发布时间】:2020-11-23 00:15:36
【问题描述】:

我们正在向 IdentityServer4 (https://github.com/IdentityServer/IdentityServer4) 实施添加租赁。到目前为止一切都很好。 AspIdentity 根据请求中的主机名向用户名附加一个前缀,即。 sso.domain1.com 和 sso.domain2.com 在身份数据库中创建租户。谷歌的外部 oauth 工作正常,谷歌的 API 控制台允许多个网站访问同一个 AppId。另一方面,Facebook 只允许每个 AppId 一个域。外部提供程序是在应用程序启动期间注册的,因此这会带来一个问题,因为我们需要根据主机名确定每个请求使用的正确 Facebook AppId。

对处理这种情况的适当方法有什么建议吗?我尝试在启动时注册所有 Facebook AppId,并让登录页面 UI 确定要显示哪个 Facebook 按钮。 IdentityServer 为此抛出了一个异常,因为它不允许多个具有相同方案名称的提供者。

管道中是否存在我们可以重载以传入请求主机并更改每个请求的外部提供程序 AppId 的地方?

更新 1:

基于 McGuireV10 答案,我能够更接近目标。现在的问题是,如果我可以设置 ClientId 和 ClientSecret 选项属性,但这不会更改为 RequestUri 属性生成的 Uri。我应该以不同的方式进行操作,还是需要重建上下文以重新生成 RedirectUri?我一直在尝试浏览 Microsoft 的安全源代码,但还没有找到。想法?

services.AddAuthentication().AddFacebook(externalAuthentication.Name, options => {
                options.SignInScheme = externalAuthentication.SignInScheme;
                options.ClientId = externalAuthentication.DefaultClientId;
                options.ClientSecret = externalAuthentication.DefaultClientSecret;
                options.RemoteAuthenticationTimeout = TimeSpan.FromMinutes(5);
                options.Events = new Microsoft.AspNetCore.Authentication.OAuth.OAuthEvents {
                    OnRedirectToAuthorizationEndpoint = context => {
                        var tenancySetting = GetExternalAuthProviderForRequest(context.Request, externalAuthentication);
                        if (tenancySetting != null) {
                            context.Options.ClientId = tenancySetting.ClientId;
                            context.Options.ClientSecret = tenancySetting.ClientSecret;
                        }

                        context.RedirectUri = BuildChallengeUrl(context);
                        context.HttpContext.Response.Redirect(context.RedirectUri);
                        return Task.FromResult(0);
                    }
                };
            });

更新 2:

它现在正在工作。我确信一定有更好的方法来做到这一点,但我现在采取了简单的方法。我获取了 Microsoft 的源代码 (https://github.com/aspnet/Security),在查看完之后我很确定在进入 RedirectToAuthorizationEndpoint 事件之前,在管道中调用了 HandleChallengeAsync 方法 (Microsoft.AspNetCore.Authentication.OAuth.OAuthHandler)。 HandleChallegeAsync 负责在上下文中构建 RedirectUri 属性。在微软的代码中似乎没有重建 RedirectUri 的现有方法,所以我复制了他们的 BuildChallegeUrl 代码并用它来重建 RedirectUri。我更新了示例代码以反映此更改。

【问题讨论】:

    标签: asp.net-core identityserver4 facebook-oauth


    【解决方案1】:

    尝试为OnRedirectToIdentityProvider 事件添加一个OpenIdConnectEvents 处理程序并在那里替换ClientId 和ClientSecret 属性,但我不知道这是否会以某种方式混淆Identity Server。我没有类似的用例,所以我自己没有尝试过这个特定的东西,但是我拦截了其他事件并更改了协议属性而没有任何问题。我也不知道您是否还需要在 options 属性本身上设置 id 和 secret,但这很容易测试。它看起来像这样:

    services.AddAuthentication()
        .AddFacebook("Facebook", options =>
        {
            options.Events = new OpenIdConnectEvents
            {
                OnRedirectToIdentityProvider = context =>
                {
                    context.ProtocolMessage.ClientId = "abc";
                    context.ProtocolMessage.ClientSecret = "xyz";
                    return Task.FromResult<object>(null);
                }
            };
            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
            // you probably don't need these:
            options.ClientId = oauth2config["FacebookId"];
            options.ClientSecret = oauth2config["FacebookSecret"];
        });
    

    显然,您需要更复杂且特定于实现的东西才能真正找出客户端等。

    【讨论】:

    • 这让我走上了正轨,但有些项目已关闭。我正在使用 aspnet 核心 2.0。到目前为止,我将在下面发布我所拥有的内容。
    • 啊,你能分享一下你的发现吗?我也遇到了同样的问题!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-12
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2017-06-22
    相关资源
    最近更新 更多