IdentityServer / IdentityServer3

OpenID Connect Provider and OAuth 2.0 Authorization Server Framework for ASP.NET 4.x/Katana
https://identityserver.github.io/Documentation/
Apache License 2.0
2.01k stars 764 forks source link

Incompatibility betwwen IdS AccessTokenValidation and thirdparty #1631

Closed laellyo closed 9 years ago

laellyo commented 9 years ago

Hello,

I'm currently creating an API gateway with Anypoint platform from Mulesoft. To secure my API, i'm trying to configure an OAuth2 authorization server thanks to IdentityServer3. All work fine until the access token validation send by Anypoint to IdentityServer.

From IIS server, I can see the request received by IdS is : GET /authz/connect/accessTokenValidation access_token=eyJ0eXAiOiJKV1Q(...)

The query parameter "access_token" is not supported by IdS because it expects the query parameter named "token". ("AccessTokenValidationController" class, Get() method) My first question is "The name of the query parameter is it specified by OAuth2 protocol?". I don't find any thing about that. If it is not specified, can you enable IdS to support other query parameter names by configuration?

Thanks in advance for your response.

Regards,

David

leastprivilege commented 9 years ago

The OAuth2 spec does not define an endpoint for access token validation at all - it is an identity server specific implementation.

In the case of JWT access tokens, the resource typically validates the tokens itself. The IdSrv access token endpoint is mostly for reference tokens (and resource servers that don't have the necessary JWT libraries).

laellyo commented 9 years ago

Thanks Dominick for your quick answer! :)

I understand that is is not depending of the OAuth2 spec but only from identity sever implementation. I looked for information on Mulesoft side to see how to validate JWT token from its side. Unfortunately, if I refer to the Anypoint documentation (https://developer.mulesoft.com/docs/display/current/External+OAuth+2.0+Token+Validation+Policy), for them the token validation is done by the OAuth provider, not the ressource server (in my case, my APIs).

I could try to build an external OAUth provider based on Mulesoft technologies (https://developer.mulesoft.com/docs/display/current/Building+an+External+OAuth+2.0+Provider+Application) but it doesn't cover all our business needs... So I would prefer to find a solution based on IdServer 3. :)

leastprivilege commented 9 years ago

You could build your own token validation endpoint that conforms to their proprietary requirements.

laellyo commented 9 years ago

Thanks Dominick.

For information, I successfully developped my own token validation service adapted to Mulesoft requirements. If it can help other people, you can see below a simple code to do that.

  1. Create a Web API project in VS
  2. Create a TokenValidationController
  3. Copy/Paste and adapt this code :
    [EditorBrowsable(EditorBrowsableState.Never)]
    [RoutePrefix("accessTokenValidation")]
    public class TokenValidationController : ApiController
    {
        private JwtSecurityTokenHandler handler;

        public TokenValidationController()
        {
            handler = new JwtSecurityTokenHandler();
        }

        public IHttpActionResult Get()
        {
            var queryParams = Request.RequestUri.ParseQueryString();

            var token = queryParams.Get("access_token");
            if (token.IsMissing())
            {
                return BadRequest("access_token query parameter is missing.");
            }

            SecurityToken decryptedToken = null;
            ClaimsPrincipal principal = null;
            X509Certificate2 signingCertificate = LoadCertificate();
            TokenValidationParameters parameters = new TokenValidationParameters
            {
                ValidAudience = "https://your-audience-uri.com",
                IssuerSigningToken = new X509SecurityToken(signingCertificate),
                ValidIssuer = "https://your-issuer-uri.com",
                ValidateLifetime = true
            };
            try
            {
                principal = handler.ValidateToken(token, parameters, out decryptedToken);
            }
            catch (Exception exc)
            {
                InternalServerError(exc);
            }

            if (decryptedToken != null)
            {
                JwtSecurityToken jwtToken = decryptedToken as JwtSecurityToken;

                return Ok<JwtSecurityToken>(jwtToken);
            }

            return InternalServerError();

        }
        private X509Certificate2 LoadCertificate()
        {
            X509Store store = new X509Store(StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadOnly);
            var certificates = store.Certificates.Find(X509FindType.FindByIssuerName, "your-signing-certificate-name", false);
            if (certificates.Count > 0)
            {
                return certificates[0];
            }

            return null;
        }
    } 

INFO: This implementation doesn't manage scope validation but it is easy to improve this implementation to add more validation processes.

leastprivilege commented 9 years ago

cool!