跳过 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

IdentityServer3 和通过 OpenIDConnect 进行外部登录

如何使用IdentityServer3进行登录吗

一步一步学习IdentityServer3

如何使用IdentityServer3进行登录吗

带有IdentityServer3的Oidc-client - Angular2,如何正确注销和登录