I have an IdentityServer4 set up to authenticate using google, and thats working great, including storing the tokens in AspNetUserTokens.
Additionally I have a separate service that needs to be able to use the access and refresh tokens to call google's API on behalf of the user later, when they are not logged in.
I'm not understanding how to request the tokens from identityserver, and keep them up to date(swap out the access token and expiration date). I can do this directly by adding an endpoint to identityserver to request the tokens, but then the external access token in IdentityServer would never be updated.
Your best bet was to use Hybrid Flow where the refresh token is stored in your service DB directly. IDS is just a proxy here and is not responsible for storing refresh token not issued by itself.
Related
I have an application developed using React in the front-end and ASP.Net Web API in the backend. I am using JWT for authorization. The process is
When a user logs in and is authenticated, 2 tokens are sent to the front-end, access token and refresh token. An access token is the JWT and a refreshes token is a random string and a refresh token is stored in a database.
For every subsequent call to APIs access token is attached in the header, I have an authentication filter that validates the access token.
Once the access token is expired, a 401 status is thrown with the error message TokenExpired.
Once the front-end receives 401, it calls the refresh token API to get the refresh token
The question I have is that I cannot have an authentication filter to validate the access token of refresh tokens API as it will throw 401 due to the expired access token, so I need to make the refresh token API to be anonymous so it does not hit authentication filter. If I make anonymous I am making a call to the database to get the refresh token stored for the user and compare it with the one I received from the front-end. So is it safe to make the refresh token API anonymous, if not what's the best way?
At Auth0, Created a set of features that mitigate the risks associated with using refresh tokens by imposing safeguards and controls on their lifecycle. Our identity platform offers refresh token rotation, which also comes with automatic reuse detection.
Please read the following topic.
Refresh Token Rotation
Refresh Token Automatic Reuse Detection
The JWT is signed using preshared secret key. Since it’s REST API in the backend and stateless, jwt is used for authorization and construct principal object
As you say, the access token represent authorisation in your application, if the refresh token is exposed then the refresh token can be presented by a bad actor to obtain an access token they can use for the same authorisation.
Using a 'preshared secret' indicates the JWT is a HMAC only variant of JWT, i.e. there is no encryption as that would indicate private and public key pair opposed to a 'preshared secret'. So the JWT is essentially a signature for the puposes of security characteristics we are ensuring integrity that the claims of the JWT are well-formed and have not been changed since signed. It also means same secret is used for signing on one end as was used to verify on the other end, the same secret has to be used because verifying a signature requires that both ends generate the signature and both of the signature match. So no data is being encrypted, so not data in the JWT is sensitive and needs to be protected.
Given this context, both the refresh and access token are a simple JWT that can only be generated by the holder of the secret - if they are exposed they can be used to make malicious requests as long as they remain valid (nbf claim).
Essentially this type of JWT can be misused if exposed to impersonate the identity the secret that signed the JWT represents, without actually knowing the secret itself, until the nbf claim expires the token - and a refresh token is the mechanism to extend the nbf claim without having the secret (which would result in a new signature, because the nbf claim would change when used).
There is one protection from access token reuse, it is the nonce claim. If you do not currently use a nonce claim you can read about how OIDC have implemented and do he same in your app. But as you say, your app is stateless but hopefully the backend has a form of state to ensure no nonce reuse and prevent JWT signature reuse. For every nonce the JWT signature changes, therefore the access token changes and can be used only 1-time. So if stolen it is a race condition who uses the token first, which greatly minimises the risk but not a perfect solution.
I am working on a .net MVC and web API project and using active directory to authenticate users to API, on authentication, a code is being returned from AD and I have to exchange the code to obtain a token and use that token to call the API, the question is why is the code returned and why do I have to exchange it for the token? can I directly obtain a token?
This is all because of security reasons.
OAuth 2.0 wanted to meet these two criteria:
All developers will not have an SSL enabled server and you should allow them to use non-HTTPS redirect URI
You don't want hackers to be able to steal access/refresh tokens by intercepting requests.
Since the Authorization Code grant has the extra step of exchanging the authorization code for the access token, it provides an additional layer of security not present in the Implicit grant type.
According to Nate Barbettini we want the extra step of exchanging the authentication code for the access token, because the authentication code can be used in the front channel (less secure), and the access token can be used in the back channel (more secure).
Thus, the security benefit is that the access token isn't exposed to the browser, and thus cannot be intercepted/grabbed from a browser. We trust the web server more, which communicates via back channels. The access token, which is secret, can then remain on the web server, and not be exposed to the browser (i.e. front channels).
For more information, watch this fantastic video:
OAuth 2.0 and OpenID Connect (in plain English) https://youtu.be/996OiexHze0?t=26m30s (Start 26 mins)
Your question isn't really specific to Azure AD, and is more about the OAuth flow and why it is used.
The flow seems a bit complex, and well, it is, but there are reasons for all the things it does.
I encourage you to use authorization code flow instead of other approaches.
It has many advantages:
Your app will never see the user's password
The user cannot see your app's client secret
The user cannot see your app's access tokens (and neither can a man-in-the-middle attacker)
You get a refresh token that you can use to get new tokens whenever needed (you do need to specify the offline_access scope for this though)
The user can go through multi-factor authentication, federated authentication with ADFS etc., and your app doesn't need to care about that
Alternative flows and their downsides:
Implicit flow
Gives you a token directly without the code exchange
There is no refresh token
Mainly used in Single Page Apps, where refresh is done using a hidden iframe, but that depends on the user's session remaining active
If you use this outside a SPA, you can't really refresh the token, requiring the user to login again every hour
User can see and take your app's access tokens
Client credentials flow
Instead of accessing the API as a user, you access it as the app itself
Some APIs do not support this approach and require you to make calls on behalf of a user
This doesn't allow you to authenticate a user
Application permissions are needed to use this flow, which usually give very broad access to the entire organization
The upside of this flow is that it is very simple
Resource Owner Password Credentials flow
Do not use this flow
HTTP request to token endpoint with app + user credentials
Exposes user password to your app (!)
Does not work if user has MFA, expired password etc.
I Create a Web API in the asp.net web API its Generate the access-token and store in the browser storage cache or session storage what if someone stole the access-token from the browser he can expose the API Data by using fiddler or Post Man so how can we prevent that issue how can we expire the token manually or forcefully
I dont think you can expire an access token generated in that way. Access tokens are good for the extent of their lifetime. This is why access tokens short lived tokens, normally an hour.
Even having the user revoke their consent is not going to expire an access token.
That being said the OAuth 2.0 Token Revocation RFC 7009 specification supplements the core specification with a mechanism to revoke both types of tokens. A token is a string representing an authorization grant issued by the resource owner to the client. A revocation request will invalidate the actual token and, if applicable, other tokens based on the same authorization grant and the authorization grant itself.
POST /revoke HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
token=45ghiukldjahdnhzdauz&token_type_hint=access_token
But this will probably only work if you are using an Authentication server to get your Access token and if the Authentication server supports this endpoint. IIR Googles for example only supports revoke of the refresh token not the access token. This is not a default thing. I have never implemented it myself it would probably entail storing the access token on the auth server and then testing that somehow rather than having it be a standard JWT.
The usual mechanism is to introduce refresh tokens. Let the access tokens have a short lifespan, say one day, and have a long lived refresh token request new access tokens every day. The server can then be asked to revoke access for a specific account by disabling the access for a refresh token.
I developed a Web API that uses token based authentication (using Identity and OWIN).
What I need to do is to identify the user in each request made with the token so that I can provide the data that only belongs to that user.
My idea is to insert / update that user record with the token right after the successfull authentication.
How can I do that?
I mean, how can I grab the token before returning the response to the client?
Or... is there any other way to accomplish that?
You don't need to store the token to identify the user. The user identity is self-contained in the token.
When the resource server gets the request OAuth2.0 middleware (implemented in Microsoft.Owin.Security.OAuth dll) decrypts the token and set it into the Identity property (context.Ticket.Identity or context.Identity in most of methods). Then you can check for the user identity.
Take into account that the authorisation server and the resource server can be separated and the resource server normally don't have access to the authorisation server database.
I am using Azure Service management API and OAuth API for generating Access token. But while making the call for grant type "refresh_token", to refresh access token it returns new access token but that response does not has new refresh token. So I have to use old refresh token for refreshing access token. And the problem is after 5-6 hours, refreshing token returns error invalid_client(Error validating credentials. Invalid client secret is provided).
In other cases like Office 365 app authentication via Azure AD it returns everything.
Is there is any specific parameter or header that I have to pass with the API call ?
Below is the screenshot of my code
Please help.
Thanks in advance
If you use the v2 endpoint scopes are requested dynamically and a refresh token must be requested using "offline_access" scope. This is much different than in the v1 model, where scopes are pre-registered with the app registration and a refresh token is always returned w/o explicit scope. If you're using v1 & you don't get refresh token, it might be due to restricted security policy about refresh tokens by your ADFS provider, which is not sending back a refresh token to the API calling the OAuth authentication and authorization.
This is security enhancement/block to disable your application not to hold a lifetime refresh token that can be lived forever (if refreshed).
So if you can use v2 endpoint - use offline_access scope. Otherwise check security policies with you ADFS provider.
I run into the same problem as you & gathered most of the information that helped to answer this question from here:
https://stackoverflow.com/a/44813531/4446128.