szuro
szuro

Reputation: 71

Azure API Management JWT validation fails

I'm trying to implement JWT validation as demonstrated in this video.

To achieve this I've implemented the following policies:

<policies>
<inbound>
    <validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="No auth" require-expiration-time="false" require-signed-tokens="false">
        <issuer-signing-keys>
            <key> base64key </key>
        </issuer-signing-keys>
    </validate-jwt>
    <return-response>
        <set-status code="200" reason="OK" />
        <set-body>test</set-body>
    </return-response>
    <base />
</inbound>
<backend>
    <base />
</backend>
<outbound>
    <base />
</outbound>
<on-error>
    <base />
</on-error>

require-signed-tokens and require-expiration-time will be enabled in production - I was trying to disable as much validation as i could just to get this running.

Then on JWT.io I'm generating a token: enter image description here

Then it's time to get some data from the API:

import urllib.request

headers = {"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxNTM0MDAzOTk4In0.0DlazlR4-InCb-m0dBs-9BbPbyvu5s7Opr8uXIUaMdA"}
api_request = urllib.request.Request("https://someapi", headers=headers)
try:
    api_response = urllib.request.urlopen(api_request)
    print(api_response.read())
except urllib.error.HTTPError as e:
    print(e.read())

Note that there is no Ocp-Apim-Subscription-Key header as the product containing the API doesn't require a subscription, thou I've also tested it with one. And the result:

b'{ "statusCode": 401, "message": "No auth" }'

API request trace doesn't provide any useful information.

Is there anything obvious that I'm missing?

Upvotes: 0

Views: 9365

Answers (3)

jagjeet
jagjeet

Reputation: 377

  1. I create the following policies. Please note that the key value should be Base64 string

<policies>
    <inbound>
        <base />
        <validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="No auth" require-expiration-time="false">
            <issuer-signing-keys>
                <key>UGFzc3dvcmRraHNhZXJhdmJhZSdyZWp2dmFlcg==</key>
            </issuer-signing-keys>
        </validate-jwt>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

  1. Navigate to https://jwt.io/ and create my token. Add your key value (mine is “UGFzc3dvcmRraHNhZXJhdmJhZSdyZWp2dmFlcg==” which is encoded value for Passwordkhsaeravbae'rejvvaer) to “your-256-bit-secret” and click on the “secret base64 encoded”

enter image description here

My Token was :

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIyNDc1ODc4MzU3In0.oDLvHDYVMzVYNdwQ1gGE8-n_-tA_8I4DJ-8dWjlluR8
  1. In the end, we could test it from the azure portal.

enter image description here

Upvotes: 0

szuro
szuro

Reputation: 71

So, thanks to the ULR in Swikruti Boses comment I was able to pinpoint and eliminate the problem. Turns out that trace in Azure portal does not display all available information. To be specific: it lacks the on-error entry.

After viewing the full trace, which location was provided in Ocp-Apim-Trace-Location response header, I've found this little nugget:

The algorithm: 'HS256' requires the SecurityKey.KeySize to be greater than '128' bits.

After providing a longer key, everything worked as intended.

This is what I get for being lazy on testing.

Upvotes: 3

Hans Z.
Hans Z.

Reputation: 54118

You need to add "bearer" to the Authorization header value, i.e.:

headers = {"Authorization": "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxNTM0MDAzOTk4In0.0DlazlR4-InCb-m0dBs-9BbPbyvu5s7Opr8uXIUaMdA"}

Upvotes: 0

Related Questions