如何让 Angular Client 通知 Identity Server 使用哪种登录方式?
How to make Angular Client to inform Identity Server which login method to use?
我将 IdentityServer 4 与 Angular 10 客户端一起使用,该客户端使用 OIDC Client JS:
要重定向用户登录,我在 Angular 的客户端上调用 signinRedirect:
UserManager.signinRedirect(args)
重定向到 IdentityServer 4 AcccountController's Login 操作:
[HttpGet]
public async Task<IActionResult> Login(string returnUrl) {
var vm = await BuildLoginViewModelAsync(returnUrl);
if (vm.IsExternalLoginOnly) {
// we only have one option for logging in and it's an external provider
return RedirectToAction("Challenge", "External", new { scheme = vm.ExternalLoginScheme, returnUrl });
}
return View(vm);
}
问题
我在 Identity Server 中配置了 Google 和 Facebook 外部提供商。
如何使用 signinRedirect
并通知 IdentityServer 使用外部提供商,如 Google 进行登录?
我想绕过 IdentityServer 中的登录页面,其中有 3 个选项:
- 使用用户名和密码登录
- 使用 Google
登录
- 使用 Facebook 登录
因此 Angular 客户端会通知 Identity Server 应使用哪种登录方法。
更新
经过一些研究,规范中似乎有一种方法可以为用户指定哪个提供商:
UserManager.signinRedirect({ acr_values: 'IdP:Google' }));
然后在 AccountController's BuildLoginViewModelAsync 上有以下内容:
var context = await _interactionService.GetAuthorizationContextAsync(returnUrl);
if (request?.IdP != null && await _schemeProvider.GetSchemeAsync(request.IdP) != null) {
var local = request.IdP == IdentityServer4.IdentityServerConstants.LocalIdentityProvider;
如果我没记错 IF
条件和以下代码是检查应使用哪个登录提供程序:本地或配置的外部提供程序之一。
我调试了 context
并得到以下信息:
已解析 AcrValues,但未定义 属性 IdP。
AcrValues 不应该是解决这个问题的方法吗?我错过了什么?
通过使用 signinRedirect
方法的 args
参数,可以使用 oidc-client 向身份提供者发送消息。
如果您从他们的 github 存储库查看 oidc-client-js/src/SigninRequest.js,您会发现您可以为上述方法提供以下可选参数:
data
,
prompt
,
display
,
max_age
,
ui_locales
,
id_token_hint
,
login_hint
,
acr_values
,
resource
,
response_mode
,
request
,
request_uri
,
extraQueryParams
,
request_type
,
client_secret
,
extraTokenParams
,
skipUserInfo
在代码的后面,在这个文件版本的第 75 行,他们有这个:
for(let key in extraQueryParams){
url = UrlUtility.addQueryParam(url, key, extraQueryParams[key])
}
这意味着他们允许开发人员使用 extraQueryParams
来提供自定义参数。
现在假设您的自定义消息参数可能被称为 useExternalProvider
,您应该能够像这样调用 signInRedirect
:
UserManager.signinRedirect({
extraQueryParams: {
useExternalProvider: "google"
}});
要在您的 IdentityServer 上访问此参数,找到调用 GetAuthorizationContextAsync
的行并检查协议消息参数,如下所示:
var context = await interaction.GetAuthorizationContextAsync(returnUrl);
var externalProviderToUse = context.Parameters.Get("useExternalProvider");
如果您使用他们的 QuickStart,通常在 BuildLoginViewModelAsync(string returnUrl)
方法中。
从那里你可以从数据库中检索外部登录参数,或者从你保存这些参数的任何地方,而不是将用户重定向到登录页面,使用 [=39] 将他们直接重定向到你的 ExternalLogin(string provider, string returnUrl)
=].
编辑
如果你想为此使用 acr_values
参数,稍后在 IdentityServer 授权上下文中想要使用 Idp
属性,你可以调用:
// "idp:" is case sensitive
UserManager.signinRedirect({ acr_values: 'idp:Google' }));
我将 IdentityServer 4 与 Angular 10 客户端一起使用,该客户端使用 OIDC Client JS:
要重定向用户登录,我在 Angular 的客户端上调用 signinRedirect:
UserManager.signinRedirect(args)
重定向到 IdentityServer 4 AcccountController's Login 操作:
[HttpGet]
public async Task<IActionResult> Login(string returnUrl) {
var vm = await BuildLoginViewModelAsync(returnUrl);
if (vm.IsExternalLoginOnly) {
// we only have one option for logging in and it's an external provider
return RedirectToAction("Challenge", "External", new { scheme = vm.ExternalLoginScheme, returnUrl });
}
return View(vm);
}
问题
我在 Identity Server 中配置了 Google 和 Facebook 外部提供商。
如何使用 signinRedirect
并通知 IdentityServer 使用外部提供商,如 Google 进行登录?
我想绕过 IdentityServer 中的登录页面,其中有 3 个选项:
- 使用用户名和密码登录
- 使用 Google 登录
- 使用 Facebook 登录
因此 Angular 客户端会通知 Identity Server 应使用哪种登录方法。
更新
经过一些研究,规范中似乎有一种方法可以为用户指定哪个提供商:
UserManager.signinRedirect({ acr_values: 'IdP:Google' }));
然后在 AccountController's BuildLoginViewModelAsync 上有以下内容:
var context = await _interactionService.GetAuthorizationContextAsync(returnUrl);
if (request?.IdP != null && await _schemeProvider.GetSchemeAsync(request.IdP) != null) {
var local = request.IdP == IdentityServer4.IdentityServerConstants.LocalIdentityProvider;
如果我没记错 IF
条件和以下代码是检查应使用哪个登录提供程序:本地或配置的外部提供程序之一。
我调试了 context
并得到以下信息:
已解析 AcrValues,但未定义 属性 IdP。
AcrValues 不应该是解决这个问题的方法吗?我错过了什么?
通过使用 signinRedirect
方法的 args
参数,可以使用 oidc-client 向身份提供者发送消息。
如果您从他们的 github 存储库查看 oidc-client-js/src/SigninRequest.js,您会发现您可以为上述方法提供以下可选参数:
data
,prompt
,display
,max_age
,ui_locales
,id_token_hint
,login_hint
,acr_values
,resource
,response_mode
,request
,request_uri
,extraQueryParams
,request_type
,client_secret
,extraTokenParams
,skipUserInfo
在代码的后面,在这个文件版本的第 75 行,他们有这个:
for(let key in extraQueryParams){
url = UrlUtility.addQueryParam(url, key, extraQueryParams[key])
}
这意味着他们允许开发人员使用 extraQueryParams
来提供自定义参数。
现在假设您的自定义消息参数可能被称为 useExternalProvider
,您应该能够像这样调用 signInRedirect
:
UserManager.signinRedirect({
extraQueryParams: {
useExternalProvider: "google"
}});
要在您的 IdentityServer 上访问此参数,找到调用 GetAuthorizationContextAsync
的行并检查协议消息参数,如下所示:
var context = await interaction.GetAuthorizationContextAsync(returnUrl);
var externalProviderToUse = context.Parameters.Get("useExternalProvider");
如果您使用他们的 QuickStart,通常在 BuildLoginViewModelAsync(string returnUrl)
方法中。
从那里你可以从数据库中检索外部登录参数,或者从你保存这些参数的任何地方,而不是将用户重定向到登录页面,使用 [=39] 将他们直接重定向到你的 ExternalLogin(string provider, string returnUrl)
=].
编辑
如果你想为此使用 acr_values
参数,稍后在 IdentityServer 授权上下文中想要使用 Idp
属性,你可以调用:
// "idp:" is case sensitive
UserManager.signinRedirect({ acr_values: 'idp:Google' }));