4

I'm using IdentityServer4 to secure some webapis. Because of a quirk in our customer setup, we need to support a setup where we will have multiple applications running IdentityServer4 to issue tokens to different clients. Those clients, however, will end up calling into some common services.

So those common services need to be able to validate a token from multiple instances of IdentityServer4. Since you register an instance of IdentityServer with the resource server on startup, I thought as long as all of the IdentityServers sign the token in the same way, it will work.

I assumed that setting up IdentityServer to use a shared X509 cert would allow tokens from one IdentityServer to be verified on a resource server configured to use a different IdentityServer, but that does not seem to be the case. Requesting a token from Server1, then submitting it to a resource server using Server2 does not work, even though they are all using the same cert.

Is there a way to make this work?

2
  • When configuring your resource server to use Identity Server for authentication, you need to specify things such as the scope and authority ... do all your identity servers have the same 'authority', as in URI. Commented Feb 18, 2017 at 12:16
  • Would love to see an answer to this... had a similar situation but using two domain names pointed to the same Identity Server instance- that didn't work either, since you have to set Api Resource's "Auhority" to single URI. Commented Feb 24, 2017 at 1:13

1 Answer 1

1

Are you using JWT or Reference tokens?

Reference tokens are verified by the authority-holding Identity-server. It might be difficult to use different identity-servers and verify tokens supplied by another one than the one verifying it. If you are using JWT you can use the Discovery-Endpoint to capture the public key. Then you should be able to use this to verify the signature...

You can do this like:

            // Define the client to access the IdentityServer Discovery-Endpoint
            var discos = new DiscoveryClient(ConfigurationManager.AppSettings["IdentityserverLocation"]);
            var disco = await discos.GetAsync();

            // get the public key from the discovery-endpoint
            var keys = disco.KeySet.Keys;

            //Build the authorization request
            //param: Disco.AuthorizeEndpoint --> retrieves the authorization url from the identityserver
            var request = new AuthorizeRequest(disco.AuthorizeEndpoint);
            var url = request.CreateAuthorizeUrl(
                clientId: ConfigurationManager.AppSettings["ClientId"],
                responseType: "id_token",
                scope: "openid profile email",
                responseMode: OidcConstants.ResponseModes.FormPost,
                redirectUri: ConfigurationManager.AppSettings["RedirectUrl"],
                state: CryptoRandom.CreateUniqueId(),
                nonce: CryptoRandom.CreateUniqueId());

            //Try to initiate validation
            try
            {

                // Check if the token data exists in the request, parse is to a correct token
                var idToken = Request.Form.Get("id_token");
                JwtSecurityToken j = new JwtSecurityToken(idToken);
                var keylist = new List<SecurityKey>();
                foreach (var webKey in disco.KeySet.Keys)
                {
                    var exp = Base64Url.Decode(webKey.E);
                    var mod = Base64Url.Decode(webKey.N);
                    var key = new RsaSecurityKey(new RSAParameters() { Modulus = mod, Exponent = exp });
                    keylist.Add(key);
                }

                //define the parameters for validation of the token
                var parameters = new TokenValidationParameters
                {
                    ValidIssuer = disco.Issuer,
                    ValidAudience = "viper",
                    IssuerSigningKeys = keylist,
                };

                var handler = new JwtSecurityTokenHandler();
                handler.InboundClaimTypeMap.Clear();

                //validate the token using the defined parameters, return the token when validation is succesful
                var user = handler.ValidateToken(j.RawData, parameters, out var validatedtoken);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.