跳过IdentityServer3登录界面

16
我们已经配置了客户端应用程序,使用OpenID Connect协议通过IdentityServer3进行身份验证(它是使用OWIN中间件支持OIDC的ASP.NET MVC应用程序)。
IdentityServer3本身被配置为同时使用本地登录和外部登录(例如Azure AD)。
在常规流程中,一旦应用程序需要验证用户,它会将用户重定向到IdentityServer3登录界面-这很好。但在某些情况下,基于每个请求的基础上,我希望通过某种方式让IdentityServer3知道用户想要马上使用特定的外部身份提供程序登录,从而绕过登录屏幕。
这是否可能实现? image

我已经发现,如果客户端限制为单个IdP,则登录屏幕会自动跳过,但是在多个IdP(例如本地登录和Azure AD)的情况下,问题仍然存在。 - Eugene D. Gubenkov
这里有一个如何使用 HRD 功能的示例 链接,也许可以帮到你。 - pepo
@pepo,谢谢,我一定会看看!据我所知,“默认”的OpenID Connect OWIN中间件无法在身份验证挑战中传递任何其他信息-https://github.com/aspnet/Security/issues/99。因此,不仅Identity Server应该支持接收有关用户意图的信息,而且OWIN中间件也应该能够发送它,但它不能开箱即用,对吧? - Eugene D. Gubenkov
我发现了这篇文章。不幸的是,我没有时间测试它,所以我不知道它是否适用于IdentityServer。 - pepo
@pepo,谢谢!我已经检查过了,似乎domain_hint对IdentityServer3没有影响,但现在我至少知道如何通过OpenID Connect中间件将任何自定义参数传递给Identity Server:https://katanaproject.codeplex.com/workitem/325。所以如果没有留下什么问题,解决方案可能是扩展IdentityServer。 - Eugene D. Gubenkov
3个回答

19

刚在IdentityServer3的授权/认证端点文档中找到了解决方案!

acr_values(可选)允许向用户服务传递其他身份验证相关信息,还有带有特殊含义的值:idp:idp名称可以绕过登录/主页领域屏幕并直接将用户转发到所选的身份提供者 (如果按客户端配置允许)。tenant:租户名称可用于向用户服务传递租户名称。

如何使用OWIN OpenID Connect中间件传递附加参数: https://katanaproject.codeplex.com/workitem/325

这是授权请求的示例:

sample request


1
那是一个不错的发现。 - Dmytro Mykhailov
嘿,我的本地测试是可以的,但在部署到开发环境后不起作用。我传递了idp:aad。你知道为什么吗? - Neel

7

我知道这已经是老问题了,但是我认为如果有人想要自动重定向到外部登录,我仍然可以在这里提供帮助:

public override Task PreAuthenticateAsync(PreAuthenticationContext context)
{
    context.SignInMessage.IdP = "windows";
    return base.PreAuthenticateAsync(context);  
}

您可以在UserServiceBase上基本覆盖PreAuthenticateAsync,并将context.SignInMessage的属性IdP更改为在启动中设置的外部提供程序名称。这将进行重定向。

0

当您使用外部提供程序配置IdentityServer时,在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的值区分大小写。
另一种选择(我没有尝试过)。您可以在客户端应用程序中设置租户而不是设置idp
   n.ProtocolMessage.AcrValues = "tenant:" + n.Request.Uri.ToString();

正如@TheRock所提到的,在IdentityServer中检查SignInMessage中的租户并覆盖Idp

public override Task PreAuthenticateAsync(PreAuthenticationContext context)
{
   if(context.SignInMessage.Tenant = "sometenant")
   {
      context.SignInMessage.IdP = "Google";
      return base.PreAuthenticateAsync(context);  
   }
}

通过这种方式,当您不断添加新的外部提供者时,您无需更改客户端应用程序中的代码。您只需要更新IdentityServer代码即可。如果您有多个客户端应用程序连接到同一个身份验证服务器,这将特别有帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接