【问题标题】:IdentityServer4: How to specify an identity provider as part of authorization request?IdentityServer4:如何指定身份提供者作为授权请求的一部分?
【发布时间】:2019-08-10 18:45:25
【问题描述】:

我已经在我的项目中使用外部提供者实现了 IdentityServer4。现在,当请求受限页面时,用户会被重定向到我的 IdentityServer 登录页面,他可以在其中输入用户名和密码,也可以使用 Google 或 Facebook 登录。如何从客户端指定要使用的身份提供者,以便我的身份服务器将直接重定向到特定提供者而不显示登录页面?

【问题讨论】:

    标签: asp.net-core .net-core identityserver4


    【解决方案1】:

    您可以将自定义参数传递给授权端点。

    如果您使用的是 OpenID 连接中间件,您可以将值添加到 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 登录过程。

    【讨论】:

      猜你喜欢
      • 2021-01-06
      • 2021-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-07
      • 2023-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多