Search code examples
owinidentityserver3owin-middleware

Send a custom parameter to an external identity provider


Is it possible to send a custom parameter to an external login provider/custom owin middleware

I have an Identity Server 3 who handles my authentication, and I have an external identity provider middleware which handles the signing in of the user, to sign in I have to send a token to the middleware, which the middleware uses to authenticate.

I tried following approaches:

  1. acr_values: I sent the token as a acr_value, but this approach does not work for 2 reasons:
    The token is to long( >900 characters, even after setting the InputLengthRestrictions for the AcrValues to 51200 in the IdentityServerOptions).
    The acr_values get stored in the sign in message which is not accessible in neither the ApplyResponseChallengeAsync()-Method nor in the AuthenticateCoreAsync()-Method
  2. QueryString Parameter: I added a QueryString Parameter containing the token, this does not work either, because the parameter is not stored when redirecting to the external provider

Is there any way to store the parameter in a way that I can transfer it to the external IdProvider? and/or can I access the SignInMessage during ApplyResponseChallengeAsync() or AuthenticateCoreAsync()?


Solution

  • There exists an extension method in the IdentityServer3 Nuget Package:

    Context.Environment.GetSignInMessage(string signinId)
    

    This can be used in the ApplyResponseChallengeAsync() method, because the signin Id is there passed as a queryString-parameter

    And in the signInMessage you have access to the return url (including the QueryString parameter passed when redirecting to the identity provider) and the acr_values, and more.

    So you just have to get the signin value from the Query and call GetSignInMessage()

    protected override Task ApplyResponseChallengeAsync()
    {   
        //...
        string signInId = null;
        IReadableStringCollection query = Request.Query;
        var values = query.GetValues("signin");
        if(values!= null && values.Count == 1)
        {
            signInId = values[0];
        }
        if (signInId == null)
            return Task.FromResult<object>(null);
    
        var signInMessage = Context.Environment.GetSignInMessage(signInId);
        //...
    }
    

    So after all this was pretty easy, but it was hard to find as there is nearly no research material, except for this github issue(which is basically the source to this answer):
    Custom values to external provider #1318