我已经在项目中使用外部提供程序实现了IdentityServer4。现在,当请求一个受限制的页面时,该用户将被重定向到我的IdentityServer登录页面,他可以在其中输入用户名和密码,或者使用Google或Facebook登录。如何从客户端指定要使用哪个身份提供者,以便我的身份服务器将直接重定向到特定提供者,而无需显示登录页面?
答案 0 :(得分:1)
您可以将自定义参数传递给授权端点。
如果使用的是OpenID Connect中间件,则可以将值添加到OnRedirectToIdentityProvider
函数的授权请求的查询字符串中:
options.Events.OnRedirectToIdentityProvider = async n =>
{
var headerValue = n.HttpContext.Request.Headers["X-idp"];
n.ProtocolMessage.SetParameter("X-idp", headerValue.ToString());
await Task.FromResult(0);
};
您可以创建自定义CustomAuthorizeAttribute来传递您要登录的身份提供者:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class CustomAuthorizeAttribute : AuthorizeAttribute, IAuthorizationFilter
{
private readonly string _idp;
public CustomAuthorizeAttribute(string idp)
{
_idp = idp;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
context.HttpContext.Request.Headers.Add("X-idp", _idp);
}
}
在您的控制器中:
[CustomAuthorizeAttribute("AAD")]
因此,在Identity Server端,您可以通过查询字符串获取所需的Identity提供信息:
AccountController.cs(ASP.Net身份):
[Authorize]
[Route("[controller]/[action]")]
public class AccountController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IEmailSender _emailSender;
private readonly ILogger _logger;
private readonly IIdentityServerInteractionService _interaction;
public AccountController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender,
ILogger<AccountController> logger, IIdentityServerInteractionService interaction)
{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_logger = logger;
_interaction = interaction;
}
[TempData]
public string ErrorMessage { get; set; }
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl = null)
{
var context = await _interaction.GetAuthorizationContextAsync(returnUrl);
var idp = context.Parameters["X-idp"];
var redirectUrl = Url.Action(nameof(ExternalLoginCallback), "Account", new { returnUrl });
var properties = _signInManager.ConfigureExternalAuthenticationProperties(ipd, redirectUrl);
return Challenge(properties, idp);
//var customId = HttpContext.Request.Query["X-CustomId"].ToString();
//var queryString = HttpContext.Request.Query["returnUrl"].ToString();
//// Clear the existing external cookie to ensure a clean login process
//await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
//ViewData["ReturnUrl"] = returnUrl;
//return View();
}
.....
}
在上面的代码示例中,如果您具有像这样的外部提供程序,它将使用IIdentityServerInteractionService
方法GetAuthorizationContextAsync
来获取值。
services.AddAuthentication()
.AddOpenIdConnect("AAD", "Azure Active Directory", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.SignOutScheme = IdentityServerConstants.SignoutScheme;
options.Authority = "https://login.microsoftonline.com/xxxx.onmicrosoft.com";
options.ClientId = "xxxxxxxxxxxxxxxxxxxxxxxxxx";
options.Scope.Add("openid");
});
它将通过名称AAD
找到该身份验证架构,并启动Azure AD登录过程。