【发布时间】: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