Spring Webflux throws an error "Failed to validate the token", when used with Azure AD
Closed this issue · 9 comments
Background (Concise) :
I am working on one of the projects of my firm, which uses Spring Webflux + Kotlin + Azure AD stack. I meticulously tried to understand the steps detailed here, and modified it for my use case, wherein I just set up a WebfluxConfig class, and moved the security filters into it. (annotated the class with all the necessary annotations as mentioned by you). I have my controllers annotated with @PreAuthorize, trying to look for the scope that's there in the auth context.
Issue:
The application starts up well, and I have spring security logging enabled as well. When I do a POST call with Auth headers using Postman, I get 401 unauthorized. On the log, it says:
"logger":"org.springframework.security.web.server.authentication.AuthenticationWebFilter","details":{"message":"Authentication failed: Failed to validate the token"},"level":"DEBUG"
What's done:
I suspected that maybe I am not putting the issuer URI correctly, but I double-checked and its proper. Is it that I will have to set jwk-set-uri
and other such properties, to get this working? Does Azure AD not fully work with Spring Webflux?
Kindly help. Thanks :)
@naridnevahgar I tried to use my access token with your project. I encountered the same error. After some research, I found out that access token, contains a field called 'nonce' in their header. This makes it a proprietary JWT, intended for graph API. More on this here I wanted to know, if the access token you are using also has this field. Note that my authentication is being done at frontend using MSAL react libraries, while spring backend is only acting as a resource server, to validate access token received from frontend and authorize API access. I need to know how your access tokens were generated, and other details surrounding it (any links if available would be nice)
Okay! I'll get back to you after checking with the frontend team how our tokens are getting generated.
@naridnevahgar - So when you did that, I assume that your tokens had 'nonce' field in the header. This is because with that field the spring resource server can't validate the token, because Graph API is the verifier for it. I want to understand whether you configured Graph API with the spring application in your Azure portal. Can you share a sample access token if possible which worked with your project? Link me to some resources which you followed to implement this project.
Hi @leology, as I mentioned above, for my case, I needed access tokens in V2 format. The v2 format does not contain nonse claim.
The format can be found here - Access Token V2 format.
The decoded JWT would look like below. In my case, I will have the roles
claim populated with the ACLs of the Users.
{
"aud": "6e74172b-be56-4843-9ff4-e66a39bb12e3",
"iss": "https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47/v2.0",
"iat": 1537231048,
"nbf": 1537231048,
"exp": 1537234948,
"aio": "AXQAi/8IAAAAtAaZLo3ChMif6KOnttRB7eBq4/DccQzjcJGxPYy/C3jDaNGxXd6wNIIVGRghNRnwJ1lOcAnNZcjvkoyrFxCttv33140RioOFJ4bCCGVuoCag1uOTT22222gHwLPYQ/uf79QX+0KIijdrmp69RctzmQ==",
"azp": "6e74172b-be56-4843-9ff4-e66a39bb12e3",
"azpacr": "0",
"name": "Abe Lincoln",
"oid": "690222be-ff1a-4d56-abd1-7e4f7d38e474",
"preferred_username": "abeli@microsoft.com",
"rh": "I",
"scp": "access_as_user",
"sub": "HKZpfaHyWadeOouYlitjrI-KffTm222X5rrV3xDqfKQ",
"tid": "72f988bf-86f1-41af-91ab-2d7cd011db47",
"uti": "fqiBqXLPj0eQa82S-IYFAA",
"ver": "2.0"
}
Regarding the application configuration, the only configuration I needed as the issuer uri.
Hope this helps!
@naridnevahgar This is helpful, though I can still see the "ver" as 1.0 I can still see them in the access token's claim (but its 2.0 in the id token claims), even after changing the version to 2.0 in the manifest. My tokens are getting generated via the msal-react library. Can you tell me how did you obtain the access tokens from Azure AD? I was following a tutorial and it claimed that the tokens generated via msal-react are safe from replay-attacks, which I believe is why I have the 'nonce' field in my token's header somehow (and the version problem too). As always, thank you for taking time to help me out :)
EDIT: I think the token you are using is ID token and not access token. For authorization, we are supposed to use access token right? If I use ID token, then token validation failure does not happen.
@naridnevahgar - I now could make sense of the things you mentioned to me earlier. I was able to detect the problem. The access token I was generating from the frontend vial msal-react
, was using the wrong scope (it was that of Graph API), and my custom scope. Tried using my scope, and it worked well! I am able to authorize spring endpoints using token from backend. Many thanks for assisting me throughout :)
Closing this thread, as issue is resolved.