Pass custom header value to IdentityServer4 Login

2020-08-05 11:14发布

I am trying to pass a custom header value (no cookies) to IdentityServer4 as the user attempts to login. Here is how its all setup.

Custom authorisation attribute:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class CustomAuthorizeAttribute : AuthorizeAttribute, IAuthorizationFilter
{
    private readonly string _customId;

    public CustomAuthorizeAttribute(string customId)
    {
        _customId = customId;
    }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        context.HttpContext.Request.Headers.Add("X-CustomId", _customId);
    }
}

Controller:

[CustomAuthorize("0123456789")]
    public IActionResult Secure()
    {
        ViewData["Message"] = "Secure Page.";

        return View();
    }

IdentityServer > AccountControlelr:

[HttpGet]
    public async Task<IActionResult> Login(string returnUrl)
    {
        var customId = _httpContextAccessor.HttpContext.Request.Headers["X-CustomId"];

        // build a model so we know what to show on the login page
        var vm = await BuildLoginViewModelAsync(returnUrl);

        if (vm.IsExternalLoginOnly)
        {
            // we only have one option for logging in and it's an external provider
            return await ExternalLogin(vm.ExternalLoginScheme, returnUrl);
        }

        return View(vm);
    }

The custom header value never makes it to any of the login endpoints. Wondering if anyone has come across this before and have any ideas how to get it working? Many Thanks

1条回答
▲ chillily
2楼-- · 2020-08-05 11:38

You can pass custom parameter to the authorize endpoint. If you are using the OpenID Connect Middleware , you can add the value to query string of authorize request of OnRedirectToIdentityProvider function :

 services.AddAuthentication(options =>
        {
            options.DefaultScheme = "Cookies";
            options.DefaultChallengeScheme = "oidc";
        })
            .AddCookie("Cookies")

            //hybrid flow
            .AddOpenIdConnect("oidc", options =>
            {
                options.SignInScheme = "Cookies";

                options.Authority = "http://localhost:62888/";
                options.RequireHttpsMetadata = false;

                options.ClientId = "mvc2";
                options.ClientSecret = "secret";
                options.ResponseType = "code id_token";

                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;

                options.Scope.Add("api1");
                options.Scope.Add("offline_access");
                options.Events.OnRedirectToIdentityProvider = async n =>
                {
                    var headerValue = n.HttpContext.Request.Headers["X-CustomId"];

                    n.ProtocolMessage.SetParameter("X-CustomId", headerValue.ToString());

                    await Task.FromResult(0);
                };
            });

Then in login page , you could easily get the querString :

    [HttpGet]
    [AllowAnonymous]
    public async Task<IActionResult> Login(string returnUrl = null)
    {

        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();
    }

Then prase the queryString to get value of X-CustomId: enter image description here

查看更多
登录 后发表回答