首页 > 解决方案 > Identity Server 4 IDP Auto-redirect to external provider

问题描述

I need to auto-redirect my user to an idp if specified by the client. I am essentially checking in my AuthenticationController's Login method that if the IDP is set I redirect out to a different method on that controller which then calls the Challenge to the IDP, this feels a bit messy as I would really like to create another controller to handle the External authentication and not have to muddle local login with an IDP check/redirect.

It got me thinking though, is there a way for Identity Server 4 to automatically redirect you if you set an idp? I have set the EnableLocalLogin to false for the client and specified the idp on the client (this adds the ACR as expected). Any help would be really appreciated.

Server Startup.cs:

services.AddAuthentication()
        .AddMicrosoftAccount("Microsoft", options =>
        {
            options.ClientId = this.Configuration["Credentials:AzureADClientID"];
            options.SignInScheme = "Identity.External";
            options.ClientSecret = this.Configuration["Credentials:AzureADClientSecret"];
            options.AuthorizationEndpoint = this.Configuration["IdentityServer:AzureADAuthorisationEndpoint"];
            options.TokenEndpoint = this.Configuration["IdentityServer:AzureADTokenEndpoint"];
        })
        .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
        {
            options.Cookie.Name = defaultSecurityPolicy.AuthenticationCookieName;
            options.Cookie.Expiration = TimeSpan.FromMinutes(defaultSecurityPolicy.CookieValidForMinutes);
            options.LoginPath = "/LogIn";
            options.SlidingExpiration = true;
            options.AccessDeniedPath = "/error/403";
            options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
        });

Server AuthenticationController.cs

[HttpGet("login")]
public async Task<IActionResult> Login(string username, string returnUrl)
{
        await this.HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);

        var context = await this.interactionService.GetAuthorizationContextAsync(returnUrl);
        if (context?.IdP != null)
        {
            var url = returnUrl;

            var redirectUrl = this.Url.Action(nameof(this.ExternalLoginCallback), new { returnUrl = url });

            var properties = this.signInManager.ConfigureExternalAuthenticationProperties("Microsoft", redirectUrl);
            return this.Challenge(properties, "Microsoft");
        }

        var vm = new LoginViewModel { Username = username, ReturnUrl = returnUrl };

        return this.View(vm);
    }

Client Startup.cs

services.AddAuthentication(options =>
        {
            options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        })
        .AddCookie(o =>
        {
            o.Cookie.Name = "CookieName";
            o.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.Always;
            o.Cookie.HttpOnly = true;
            o.AccessDeniedPath = "/error/403";
            o.Events.OnRedirectToAccessDenied = x =>
            {
                x.HttpContext.Response.StatusCode = 403;
                return Task.CompletedTask;
            };
        })
        .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, o =>
        {
            o.Authority = this.Configuration.GetSection("IdentityServer").GetValue<string>("Url");
            o.AuthenticationMethod = OpenIdConnectRedirectBehavior.RedirectGet;
            o.ClientId = this.Configuration.GetSection("IdentityServer").GetValue<string>("ClientId");
            o.ClientSecret = this.Configuration.GetSection("IdentityServer").GetValue<string>("ClientSecret");
            o.RequireHttpsMetadata = true;
            o.SaveTokens = true;
            o.ResponseType = "code id_token";
            o.GetClaimsFromUserInfoEndpoint = true;
            o.Scope.Add("openid profile");
            o.Events.OnRedirectToIdentityProvider = n =>
            {
                if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
                {
                    n.ProtocolMessage.AcrValues = "idp:Microsoft";
                }
                return Task.FromResult(0);
            };
        });

标签: identityserver4idp

解决方案


推荐阅读