跳过 IdentityServer3 登录屏幕
Posted
技术标签:
【中文标题】跳过 IdentityServer3 登录屏幕【英文标题】:Skip IdentityServer3 login screen 【发布时间】:2015-07-08 18:04:51 【问题描述】:我们已将客户端应用程序配置为通过 OpenID Connect 协议使用 IdentityServer3 身份验证(它是使用 OWIN 中间件支持 OIDC 的 ASP.NET MVC 应用程序)。
IdentityServer3 本身被配置为使用本地登录和外部登录(例如 Azure AD)。
在常规流程中,一旦应用需要对用户进行身份验证,它会将他重定向到 IdentityServer3 登录屏幕 - 这很好。但在某些情况下,在每个请求的基础上,我想通过某种方式让 IdentityServer3 知道用户想要立即使用特定的外部身份提供者登录来绕过登录屏幕。
有可能吗?
【问题讨论】:
我发现如果客户端限制为单个 IdP,则登录屏幕会自动跳过,但在多个 IdP(例如本地登录和 Azure AD)的情况下,问题仍然存在 有一个示例如何设置 HRD 功能 here。也许它会帮助你。 @pepo,谢谢,我一定会看看的!据我了解,OpenID Connect 的“默认”OWIN 中间件无法传递有关身份验证质询的任何附加信息 - github.com/aspnet/Security/issues/99。所以不仅 Identity Server 应该支持接收有关用户意图的信息,OWIN 中间件也应该能够发送它并且它不能开箱即用,对吧? 我找到了this article。不幸的是没有时间测试它,所以我不知道它是否可以与 IdentityServer 一起使用。 @pepo,谢谢!我已经检查过了,似乎 domain_hint 对 IdentityServer3 没有影响,但现在我至少知道如何通过 OpenID Connect 中间件将任何自定义参数传递给 Identity Server:katanaproject.codeplex.com/workitem/325。因此,如果什么都没有,解决方案可能是扩展 IdentityServer。 【参考方案1】:刚刚在IdentityServer3's Authorization/Authentication Endpoint documentation找到了解决方法!
acr_values(可选)允许通过额外的认证相关 给用户服务的信息 - 还有一些特殊的值 含义:idp:name_of_idp 绕过登录/主域屏幕并 将用户直接转发给选定的身份提供者(如果 每个客户端配置允许)tenant:name_of_tenant 可用于 将租户名称传递给用户服务
如何使用 OWIN OpenID Connect 中间件传递附加参数:https://katanaproject.codeplex.com/workitem/325
这是授权请求的示例:
【讨论】:
这很好。 嘿,它在本地对我有用,但是当部署到 dev 时它不起作用,我通过了 idp:aad。你知道为什么吗?【参考方案2】:我知道这是旧的,但我认为如果他们想自动重定向到外部登录,我仍然会把它放在这里帮助某人:
public override Task PreAuthenticateAsync(PreAuthenticationContext context)
context.SignInMessage.IdP = "windows";
return base.PreAuthenticateAsync(context);
您基本上可以覆盖 UserServiceBase 上的 PreAuthenticateAsync 并将 context.SignInMessage 上的属性 IdP 更改为您启动时设置的外部提供程序名称。这将重定向。
【讨论】:
【参考方案3】:当您使用外部提供程序配置 identtyserver 时,通常在 AuthenticationOptions 中将 AutheticationType
设置为某个字符串。如下所示
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions
AuthenticationType = "Google",
Caption = "Sign-in with Google",
SignInAsAuthenticationType = signInAsType,
ClientId = ConfigurationManager.AppSettings["google:clientid"],
ClientSecret = ConfigurationManager.AppSettings["google:clientsecret"],
);
然后在客户端应用程序中,您可以将acrvalues
设置为如下所示的身份验证类型
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
Notifications = new OpenIdConnectAuthenticationNotifications
RedirectToIdentityProvider = (n) =>
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.AuthenticationRequest)
if(n.Request.Uri == "someurl")
//set acrvalues. the value of the `idp`, (which is `Google` in this case) must match with the `AutheticationType` you set in IdentityServer
n.ProtocolMessage.AcrValues = "idp:Google";
return Task.FromResult(0);
另请注意,idp
值区分大小写。
另一个选项(我没有尝试过)。您可以在客户端应用程序中设置tenant
,而不是设置idp
。
n.ProtocolMessage.AcrValues = "tenant:" + n.Request.Uri.ToString();
正如@TheRock 提到的,在 IndentityServer 中检查SignInMessage
中的租户并覆盖Idp
public override Task PreAuthenticateAsync(PreAuthenticationContext context)
if(context.SignInMessage.Tenant = "sometenant")
context.SignInMessage.IdP = "Google";
return base.PreAuthenticateAsync(context);
通过这种方式,当您不断添加新的外部提供程序时,您不必更改客户端应用程序中的代码。您只需更新 IndentityServer 代码。如果您有多个客户端应用程序连接到同一个身份服务器,这尤其有用。
【讨论】:
以上是关于跳过 IdentityServer3 登录屏幕的主要内容,如果未能解决你的问题,请参考以下文章
OIDC - 使用 IdentityServer3 和 Spring Boot 实现 OAuth2