when client requests resource with jwt-token, first resource need to verify token. In simple scenario , resource server verifies itself. But there are cases when oauth server is called to verify the token.
So my question is, why oauth server could be called to verify the token?
It all depend's on how you are using validating token.
Methods used for validating token
Introspection
This is a method to get actual token information via special endpoint
directly from the Authorization Server. Token information usually
includes token type, status (active or not), user, client identifier,
available OAuth2 scopes, and expiration time.The method requires
direct interaction with Authorization Server for every token
validation. It has high safety but low performance.
Token validation by signature (JWT tokens only).
This is a method when the token is validated according to its
cryptographic signature and all required token information is received
from token itself. It means that token validity is verified without
interaction with an Authorization server, and if the token was revoked
before its expiration, we’ll never know about it. So, this method is
fast but less secure than introspection.
You can have more details on token validation on https://dzone.com/articles/oauth2-tips-token-validation
Related
There is a lot of information on OAuth, OIDC and Keycloak, but the main thing every tutorial seems to gloss over is offline validation. The only information I found is in the Keycloak docs on RPT introspection:
No. Just like a regular access token issued by a Keycloak server, RPTs also use the JSON web token (JWT) specification as the default format. If you want to validate these tokens without a call to the remote introspection endpoint, you can decode the RPT and query for its validity locally. Once you decode the token, you can also use the permissions within the token to enforce authorization decisions.
If I wanted to verify a user's request with an authorization token, I would make a request to the Keycloak introspection (or userinfo?) API. I'm not completely sure, but I would guess that Keycloak then verifies the info encoded in the JWT with the Keycloak user database.
However, what if I don't want to make a Keycloak request on every API request? This could improve system performance by limiting the amount of HTTP requests. There are mentions of JWT signature validations and reading the scope and user information encoded in the JWT, but I don't see how this guarantees safety. Isn't it possible to just generate any old JWT, encode any information you want and basically spoof an authorization token? How would I check if the user mentioned in the JWT really exists in the Keycloak database?
I think I am missing some crucial part of this technology.
For example, in ASP.NET Core, an API that receives a JWT token will, at startup, download the public signing keys from the token provider, and by default, it will refresh the keys every 24 hours.
So, when the API receives a JWT token, it will do various checks to validate the token, including:
Validating the signature using the provider public signing key
Validate the audience claim (is the token intended for me?)
Validate the expiry date
The API should not need to query anything against the token provider (keycloak) to let the user in.
However, then we have authorization (What the user is allowed to do), which is a different thing, and that all depends on your requirements.
JWT is all about who the user is; if the token is valid, you can trust that information.
With JWT-tokens, your API can work almost offline from the token provider. It can even be 100% disconnected if you copy the public signing key manually into the API.
I am implementing the oauth2 client credentials flow. When Auth server is called to get token... I return a jwt token including also scopes into it (e.g. read:orders and write:orders) and as audience the api identifier (.. /serv/api/v1/orders). When I use then token I pass it in authentication header as Bearer token. When I check if token is valid I check expire date.. If the API called is the same of audience and if the endpoint called has a scope included in my token. If server side I delete scope (e.g. I remove write:order scope) the previous token also contains the write scope. Actually the only thing I do is to wait token fails and when I get a new token I will don't have the write scope.
How can I invalidate the previous token before expiration?
Should I check scope server side during token validation? In this case I suppose is useless to register scopes into token.
Thanks for help.
If you need to invalidate tokens before expiration date then you have to keep track of the issued tokens in your Authorization Server, mark those which should be invalidated, and then make the API verify the token by making a request to the Authorization Server.
As you've pointed out, in such a setup there is not much use of the scopes in the token. I would suggest to use an opaque token instead of a JWT as your access token. Then have your API perform token introspection - which is a standardised operation in OAuth. The Authorization Server will return scopes corresponding to your token, or 404 if the token has been invalidated.
If you request a token from the server (with the same credentials and within the lifespan of an old token) should it either:
return a fresh token every time
return the same token with a shorter lifespan
something else / depends on
Is it depending on whether you use a refresh token?
Can you please reference the OAuth 2 RFC in your answer ?
The OAuth 2.0 Authorization Framework is a framework that allow a Resource Owner to CONSENT to allow DELEGATION of their permissions to access a Resource Server to another party (OAuth Client).
The Authorization Request is performed by the OAuth Client and is fulfilled by the Authorization Server only after obtaining CONSENT from the Resource Owner by the Authorization Response (which includes a Access Token).
The Access Token is a Bearer Token with a limited lifetime.
The refresh Token, if used, by the client to requests a new access token by authenticating with the authorization server and presenting the refresh token. The client authentication requirements are based on the client type and on the authorization server policies.
The "same" Access Token is never returned or reused by the Authorization Server.
Reading and following the Security Considerations with any Authentication or Authorization Protocols is a must. Most breaches are caused by implementation errors rather than protocol errors.
You should Tell us what you have tried and show logs or results and Read:
https://stackoverflow.com/help/how-to-ask
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?
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!
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 ..
Why can't the client simply send both the access and refresh tokens together for every authorized request? If the access token is expired, it wouldn't require two additional trips to retrieve a new access token and finally making the relevant request.
I realize this operation is amortized, but it would lessen the number of requests for very short access tokens. And under SSL, I don't see how adding the refresh token makes this any more vulnerable. Or does it?
I think the main reason is that the refresh token and the access token are sent to different places. The access token is sent to the resource server and the refresh token is sent to the authorization server. In the general case, there's nothing that the resource server can do with the refresh token.
Some reasons:
The access token provides an abstraction layer, replacing different
authorization constructs (e.g., username and password) with a single
token understood by the resource server. This abstraction enables
issuing access tokens more restrictive than the authorization grant
used to obtain them, as well as removing the resource server's need
to understand a wide range of authentication methods.
https://www.rfc-editor.org/rfc/rfc6749#section-1.4
Having the resource servers understand refresh tokens means more work for them when it can / should be abstracted away (by the authorization server).
...
Because refresh tokens are typically long-lasting credentials used to
request additional access tokens, the refresh token is bound to the
client to which it was issued. If the client type is confidential or
the client was issued client credentials (or assigned other
authentication requirements), the client MUST authenticate with the
authorization server as described in Section 3.2.1.
https://www.rfc-editor.org/rfc/rfc6749#section-6
A refresh request requires client credentials. The resource server shouldn't have to ever see the client's credentials.
Refresh tokens are meant to be long-lasting, while access tokens aren't (or shouldn't be).