I have the following architecture.
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?
The app can then verify
, is the app the client JavaScript application? – Dressel