我们已将Client App配置为通过OpenID Connect协议使用IdentityServer3身份验证(它是使用OWIN中间件支持OIDC的ASP.NET MVC App)。
IdentityServer3本身配置为使用本地登录和外部登录(例如Azure AD)。
在常规流程中,一旦App需要对用户进行身份验证,它会将其重定向到IdentityServer3登录屏幕 - 这很好。但在某些情况下,基于每个请求,我想以某种方式绕过登录屏幕,让IdentityServer3知道用户想要立即登录特定的外部身份提供商。
这可能吗?
刚刚在IdentityServer3's Authorization/Authentication Endpoint documentation找到解决方案!
acr_values(可选)允许将其他与身份验证相关的信息传递给用户服务 - 还有一些具有特殊含义的值:idp:name_of_idp绕过login / home领域屏幕并将用户直接转发到所选的身份提供者(如果允许每个客户端配置) )tenant:name_of_tenant可用于将租户名称传递给用户服务
如何使用OWIN OpenID Connect中间件传递其他参数:https://katanaproject.codeplex.com/workitem/325
以下是授权请求的示例:
我知道这已经过时了,但我想如果他们想要自动重定向到外部登录,我还是会把它放在这里帮助别人:
public override Task PreAuthenticateAsync(PreAuthenticationContext context)
{
context.SignInMessage.IdP = "windows";
return base.PreAuthenticateAsync(context);
}
您基本上可以覆盖UserServiceBase上的PreAuthenticateAsync,并将context.SignInMessage上的属性IdP更改为已在启动时设置的外部提供程序名称。这将重定向。
使用外部提供程序配置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
设置为Authentication-type,如下所示
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
,而不是设置tenant
。
n.ProtocolMessage.AcrValues = "tenant:" + n.Request.Uri.ToString();
正如@TheRock所提到的,In IndentityServer检查SignInMessage
中的租户并覆盖Idp
public override Task PreAuthenticateAsync(PreAuthenticationContext context)
{
if(context.SignInMessage.Tenant = "sometenant")
{
context.SignInMessage.IdP = "Google";
return base.PreAuthenticateAsync(context);
}
}
这样,当您不断添加新的外部提供程序时,您不必更改客户端应用程序中的代码。您只需更新IndentityServer代码。如果您有多个客户端应用程序连接到同一身份服务器,这尤其有用。