'Generating a valid JWT

I've been getting into using Identity Server 4 this weekend, and I've mostly been impressed with the ease and it feels like I've gotten a good grip for the procedure for creating an access_token. Been using both Implicit- and ResourceOwner-Flow for creating tokens.

My problem is that my identityserver3 wep api is unable to validate the JWT created, it also fails when I'm using jwt.io for manual validation.

Example token:

eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNyc2Etc2hhMjU2Iiwia2lkIjoiRkRFQUE5NTBDRjczODM0MzEwNTZBNzY3Mjc1RTNEMzE5N0VERDJGOSIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0NjMzNDM2MjgsImV4cCI6MTQ2MzM0NzIyOCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwL3Jlc291cmNlcyIsImNsaWVudF9pZCI6ImJyZnBvcnRhbF9hcGkiLCJzY29wZSI6ImJyZnBvcnRhbGJhY2tlbmQiLCJzdWIiOiIyIiwiYXV0aF90aW1lIjoxNDYzMzQzNjI4LCJpZHAiOiJpZHNydiIsInVuaXF1ZV9uYW1lIjoidGVzdCIsImJyZklkIjowLCJhcHROYnIiOiIwIiwiYW1yIjpbInBhc3N3b3JkIl19.iUvP7jVYSZPXozF0htLbaRrl_iqz_JOIczU5WpIoA5RHfgY17YGN4ERm-8NNPvXQBgJDe2ZeCpLV3MJR4smSOxNOBlzWWlgGApl5VauE62L0POxUnwzRFt2OYh5MVcilz0hRaKstB02EPXy-rDmgsNY8u_iT0bPU8bDD0XTETPy7QRldSMNKfUmeMOC0y8RQYypmXlZsO89HlseyfqE4kptruAho_EIp61qQ3CchJrkXwSB9YBWz4PrJHAiEA_ntzskOQ7K_96jQYZDH2NxaIQRKz7RPZWQreZHtnM7tUG6PNYI02raUFF7w8SQFTjjKUBQROcPezKZMtgFiv-c2Ww

One issue I see is that according to my understanding the web api will check

http://localhost:5000/.well-known/openid-configuration/jwks

for the public key in the public key. The public key is as far as I can see available in the "x5c"-field, but when I use it for validation on jwt.io it doesn't work.

"keys": [
  {
    "kty": "RSA",
    "use": "sig",
    "kid": "_eqpUM9zg0MQVqdnJ149MZft0vk",
    "x5t": "_eqpUM9zg0MQVqdnJ149MZft0vk",
    "x5c": [
      "MIIDFTCC..."
    ]
  }
]

FDEAA950CF7383431056A767275E3D3197EDD2F9

is my certificate thumbprint, which is the same as the "kid"-field of my JWT. But shouldn't the "kid"-field of the jwks response be the same, there

This is my code in the identityserver:

Setup identityserver4 with InMemory-configuration for Clients, Scopes and Users. This does seem to be working, as in getting JWTs with correct data in them.

        var certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        certStore.Open(OpenFlags.ReadOnly);

        var certCollection = certStore.Certificates.Find(
                                   X509FindType.FindByThumbprint,
                                   "FDEAA950CF7383431056A767275E3D3197EDD2F9",
                                   false);

        if (certCollection.Count > 0)
        {
            var cert = certCollection[0];

            var builder = services.AddIdentityServer(options =>
            {
                options.SigningCertificate = cert;
                options.RequireSsl = true;
            });

            builder.AddInMemoryClients(Clients.Get());
            builder.AddInMemoryScopes(Scopes.Get());
            builder.AddInMemoryUsers(Users.Get());
        }

I'm not adding my Clients, Scopes and Users classes here, because I don't think the issue lies there.

Here is my code in the Web API using IdentityServer3.AccessTokenValidation:

        app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
        {
            Authority = "http://localhost:5000",
            RequiredScopes = new[] { "testscope" }
        });

I can see my API accessing the identity server from the logs, but still after trying to find an issue in my process I keep getting "Authorization has been denied for this request." for every request.



Solution 1:[1]

I solved this error by changing the command from

git diff --name-only ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}...${CI_COMMIT_REF_NAME}

to

git diff --name-only remotes/origin/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}...remotes/origin/${CI_COMMIT_REF_NAME}.

It seems that the gitlab runner doesn't have any local branches. So we have to tell it to compare the difference between remote branches.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Brian