Azure API Management: authorization with Oauth2 401 gives "Unauthorized. Access token is missing or invalid."

azure api management oauth client credentials
azure api management subscription key
azure api management jwt token
azure api management oauth 2.0 authorization server
azure api management openid connect
azure api management authentication
azure api management basic authentication
azure api management security best practices

I have a few APIs (Logic Apps, Functions) that I want to expose through Azure API Management. They work fine, so I decided to add OAuth2 autorization.

I followed step by step https://docs.microsoft.com/fr-fr/azure/api-management/api-management-howto-protect-backend-with-aad:

  • Register an application (backend-app) in Azure AD to represent the API.
  • Register another application (client-app) in Azure AD to represent a client application that needs to call the API.
  • In Azure AD, grant permissions to allow the client-app to call the backend-app.
  • Configure the Developer Console to call the API using OAuth 2.0 user authorization.
  • Add the validate-jwt policy to validate the OAuth token for every incoming request.
  • Also use Postman to test

Everything works until the "validate-jwt" policy step. When I add it, I get a "401 - Unauthorized. Access token is missing or invalid." I can get the token, in Developer Console and Postman, but as soon as I do the API call... 401!

When I used jwt.ms to check the content of the token, I noticed that the aud param has nothing to do with the backend Application ID. The value in the token is "00000003-0000-0000-c000-000000000000", whereas the backend app ID is like "16caXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXc0".

I'm running out of ideas and need the help of some Azure gurus out there! Help would be very much appreciated...

Here below the inbound policy as per the MS doc:

<policies>
    <inbound>
        <validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized. Access token is missing or invalid.">
            <openid-config url="https://login.microsoftonline.com/MY_AD_TENANT_ID/.well-known/openid-configuration" />
            <required-claims>
                <claim name="aud">
                    <value>MY8BACKEND_APP_ID_GUID</value>
                </claim>
            </required-claims>
        </validate-jwt>
    </inbound>
    <backend>
        <forward-request />
    </backend>
    <outbound />
    <on-error />
</policies>

Screen cap of the Postman screen where I get the token (this works, but then when I send the request --> 401)

Screen cap of aud param in jwt.ms

I had some problems with validating Azure AD tokens a couple of years back - see my write up.

I suspect the problem is the nonce in the JWT header. I am a little out of touch with Azure AD - but I hope this gives you a pointer in the right direction.

Authorize developer accounts using OAuth 2.0 in API Management , Learn how to authorize users using OAuth 2.0 in API Management. This topic shows examples using Azure Active Directory as an OAuth 2.0 provider. management of accounts - for example, https://contoso.com/login . Now that you have configured an OAuth 2.0 authorization server, the Developer Console can obtain access tokens from Azure AD. The next step is to enable OAuth 2.0 user authorization for your API. This enables the Developer Console to know that it needs to obtain an access token on behalf of the user, before making calls to your API.

You're not really required to check value of aud parameter. You could remove required-claims alltogether, this way token presence and signature would still be validated. If you want to make sure that token was issued for your app, just find the claim that contains app id and use it in name="..." to match against your app id value.

Protect SPA backend with OAuth 2.0 by using Azure Active Directory , Create the Azure AD B2C Calling (Frontend, API Management) and API Firstly Let's configure Authentication / Authorization, so click on the name Now your Function API is deployed and should throw 401 responses if Next, Select the Oauth 2.0 blade from the Security Tab, and click 'Add'; Give values� APIM policy for oAuth 2.0 Authorization with Azure AD Authentication and AWS Cognito Merry He Authentication , Azure API Management March 27, 2020 March 30, 2020 3 Minutes Recently Aravindh Kathiresan and I implemented OAuth 2.0 authentication in API for a project.

if using v2 version endpoint, go to -> azure ad -> app registration -> select backend-app -> manifest -> update property "accessTokenAcceptedVersion": 2,"

Protecting APIs with OAuth2 in API Management, I've been playing a lot lately with Azure API Management. can configure a new OAuth2 authorization server in our API Management instance. failed-validation -httpcode="401" header-name="Authorization"> But then when I try to authorize I get a auth token but when I try it out it still gives me the 401. Azure API Management extension for VS Code for creating APIs, operations and to edit our policy. Rest Client extension for VS Code for sending HTTP requests and to test our configuration. JWT Decoder extension for VS Code for inspecting the Azure AD OAuth 2.0 JSON Web Tokens (JWTs). I don’t recommend using public sites to inspect your JWTs

OAuth 2.0 Authorisation with the Client Credentials Flow on Azure , To secure API Management using the OAuth 2.0 client credentials flow, we provides very useful notes on each of the claims in Azure AD JWTs. <validate- jwt header-name="Authorization" failed-validation-httpcode="401"� API Management authentication policies. 06/12/2020; 3 minutes to read +8; In this article. This topic provides a reference for the following API Management policies. For information on adding and configuring policies, see Policies in API Management. Authentication policies. Authenticate with Basic - Authenticate with a backend service using

Discover How To Secure Your Azure API Management Infrastructure, If you are considering Azure API Management and security is top of your agenda, a valid OAuth2 JWT token – otherwise a 401 Unauthorized will be returned. Note: The APIM Developer Portal supports OAuth2/JWT, whereby an Authorisation Within the APIM policy a context object is available that gives access to both� Microsoft.Azure.AppService.Authentication Information: 0 : Sending response: 401.71 Unauthorized The thread 0x3b00 has exited with code 0 (0x0). What appears to be the issue is that the Audience presented with the request is https but the validParameters.ValidAudiences collection only contains http.

Secure API in Azure API Management using OKTA Identity , OKTA provides authorization server to manage identity of user. We can Azure provides API Developer Portal for API Documentation. <validate-jwt header- name="Authorization" failed-validation-httpcode="401" url="https://dev-374027. okta.com/oauth2/default/.well-known/oauth-authorization-server"� 401 Unauthorized means request is unauthorized because the backend API is protected by Azure Active Directory. Before successfully calling the API the developer portal must be configured to authorize developers using OAuth 2.0. Check the below link for more information and let us know whether it helps.

Comments
  • Hi Gary, thanks for your write up, it definitely put me on the right track. As you explain in it, "If there is a nonce field in the JWT’s header then it is intended only for Microsoft developed Azure APIs . These tokens require special handling and will always fail standards based validation." --> that is the case. Unfortunately, I plan to expose Logic Apps through APIM, so adding home made code to validate the jwt is not an option.
  • Maybe it is because I've started a few weeks ago on APIM/Functions/Logic Apps, but there is actually something I don't get here: MS is providing jwt tokens that can't be validated by its own inbound policies (validate-jwt)? how come? Note: another interesting thing is that when I use Postman from which I get the jwt token, I use the scope "user.read" (the one I created), and in the jwt, the scope is "User.Read profile openid email"
  • If I remember rightly, a couple of years back I stopped using the v2 OAuth endpoints and used v1 endpoints - in order to get rid of nonce from the JWT header so that I could validate tokens. I was not using graph API and just trying to use a custom API as in your case.
  • I agree with your frustration. It would be much easier if Microsoft just followed OAuth 2.0 and Open Id Connect standards by default. Instead their unnatural vendor extensions makes their tech difficult to use for common use cases. Looks like lots of people are struggling with this: github.com/AzureAD/microsoft-authentication-library-for-js/…
  • Thank you so much Gary!! By using the v1 endpoints, no more nonce and it worked right away, both in Postman and Developer Console!
  • Hi Vitaliy, thank you for your idea. I tried what you proposed, but no luck: I removed the check on aud, but I still have the "401 - Unauthorized. Access token is missing or invalid.". So I guess my problem is somewhere else, and I can't find it (in the Developer Portal I can't see debug info, nor in the Activity log : it shows the "Get Token" and "Get SSO Token" calls, and they succeed).
  • Use test console in Azure Portal to make a call: open APIM service, go to APIs, select API, select Operation, go to Test tab. Make sure to add your token to request. This way you will get trace of the call with explanation what went wrong.
  • Thank you Vitaliy, I tried that and fetched the ocp-apim-trace-location, that showed an interesting piece: "on-error": [ { "source": "validate-jwt", "data": { "message": "JWT Validation Failed: IDX10511: Signature validation failed. Keys tried: 'Microsoft.IdentityModel.Tokens.X509SecurityKey , KeyId: piVlloQDSMKxh1m2ygqGSVdgFpA\r\n'. \nkid: 'piVlloQDSMKxh1m2ygqGSVdgFpA'. \nExceptions caught:\n ''.\ntoken: '{\"typ\":\"JWT\",\"nonce\":\"Tuh4aIzD0u0CKgZg1\",\"alg\":\"RS256\", } } ],
  • Hi Vitaliy, thanks for your help: Gary pointed me in the right direction (comments in the previous answer) --> by using the v1 endpoints instead of v2, the nonce disappeared in the jwt, and it worked right away both in Developer Console and in Postman.
  • Hi Laurent - just to get back to you on this, I recently updated my Azure Code Sample + Docs to use 2.0 endpoints. It is pretty unintuitive, but I got it working. Just thought I'd post back in case it's useful to you in future. Regards ..