Where to validate nonce in OAuth 2.0 Implict Flow?
Asked Answered
D

2

7

I have the following architecture.

enter image description here

Where:

  • Client - is a single page JavaScript application.
  • Authorisation server - is Azure AD.
  • Resource server - is an Azure App Service using Azure AD authentication.
  • All communications are secured using HTTPS.

I am using Implicit Flow to access a JWT access token from Azure AD.

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=id_token+token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&scope=openid%20https%3A%2F%2Fgraph.microsoft.com%2Fmail.read
&response_mode=fragment
&state=12345
&nonce=678910

This JWT token is then later passed to the resource server as a Bearer authorization. The same token could be reused multiple times before it expires.

As part of the Authorize request I pass state and a nonce value.

Presently I validate the state on my client in JavaScript using a simple if:

function isValid() {
    if (token.state !== expectedState) {
        return false;
    }

    ...
}

If I understand correctly the nonce is to prevent replay attacks - which I assume meant against my resource server, but perhaps also against the client.

I am unsure where (or if) I should validate the nonce.

On the server doesnt seem right, the token as a whole is being validated, and the token is meant to be reusable (within its expiry).

On the client, seems to be a better location, but is that any different to validating the state?

Dressel answered 24/4, 2018 at 12:19 Comment(0)
W
6

I am unsure where (or if) I should validate the nonce.

Of course, you should validate the nonce. Because the nonce is required and it will be returned and contained as a claim in the id_token. When you validate the id_token, you would just validate the nonce claim. Using nonce is to mitigate token replay attacks (someone who want to use token replay attack won't know the nonce, so each token has different nonce to identify the origin of the request).

There is a clear explanation for nonce for AAD v2 endpoint:

#nonce (required)

A value included in the request, generated by the app, that will be included in the resulting id_token as a claim. The app can then verify this value to mitigate token replay attacks. The value is typically a randomized, unique string that can be used to identify the origin of the request.

So, you can just validate the id_token to validate the nonce.

but is that any different to validating the state?

Yes, the effect of nonce is different from state. First, nonce will be returned in the id_token and you can validate it when you decode and validate the id_token. But state is returned in the response, not in the token. Also, state has different meaning and effect from nonce.

#state (recommended)

A value included in the request that will also be returned in the token response. It can be a string of any content that you wish. A randomly generated unique value is typically used for preventing cross-site request forgery attacks. The state is also used to encode information about the user's state in the app before the authentication request occurred, such as the page or view they were on.

Additional, replay attack is different from cross-site request forgery attacks. You can refer for more details about these two attacks. Then, you will understand why nonce is in the token and state is in the response.

Whether validate the nonce (token) at client

For id_token, yes, it just should be validate from the client. For SPA with implicit flow, we can use ADAL.js to validate nonce, the id_token which contains the nonce claim to mitigate token replay attacks.

Hope this helps!

Wallinga answered 24/4, 2018 at 14:6 Comment(3)
In this context The app can then verify, is the app the client JavaScript application?Dressel
Yes that is part of my confusion. The nonce is created in the client, and known only to the client, so logically the nonce has to be validated in the client - having now had a look at the ADAL.js it appears they are also validating the nonce in the client by simply reading the Base64 encoded JWT.Dressel
@JamesWood . Right, For SPA,we validate the token use ADAL.js. Here we validate the id_token in the SPA client to mitigate token replay attacks.Wallinga
M
1

As a general point I'd recommend using the excellent oidc-client certified library to do this for you

It is tricky with Azure AD but I have a documented sample that works and that we used at my last company: http://authguidance.com/2017/11/30/azure-active-directory-setup/

Happy to answer any questions if it helps ..

Mientao answered 17/6, 2019 at 19:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.