I am trying to build an API on ASP.NET Core 5. My authorization is implemented using JWT and refresh tokens.
As I understood, when the user registers, we provide him an access token (that expires in ~5 minutes, usually) and a refresh token (long-lasting one). We store refresh tokens in our database.
My struggle comes into play with login requests. In all of the tutorials we must decalre a method with the name like "GenerateAuthResultAsync()" that gets called on registration and on login and writes a refresh token object data to our DB. As a result, on login a new refresh token gets generated, as well as on registration. It is possible, that there would be 2 valid refresh tokens available for a single user. Is it normal?
Related
I have an application to save Azure Active Directory users to SQL Server. For this I am using MSAL authentication to get the users.
But sometimes my access token will get expired and I will get 401 unauthorized error from Graph. So I need to add the logic of validating the expiry in my code itself. I searched a lot but couldn't find a good solution.
Could anybody help me how to achieve this?
The default lifetime of an access token is variable. When issued, an access token's default lifetime is assigned a random value ranging between 60-90 minutes (75 minutes on average). I suggest you save the Refresh token instead and then obtain the access token any time you want to query the users resource.
The reason for that is that the Refresh tokens have a longer lifetime than access tokens. The default lifetime for the tokens is 90 days and they replace themselves with a fresh token upon every use. As such, whenever a refresh token is used to acquire a new access token, a new refresh token is also issued. The Microsoft identity platform doesn't revoke old refresh tokens when used to fetch new access tokens. Securely delete the old refresh token after acquiring a new one. Refresh tokens need to be stored safely like access tokens or application credentials.
More about Refresh token in Microsoft identity platform can be found here - https://learn.microsoft.com/en-us/azure/active-directory/develop/refresh-tokens
I've searched a lot and I've read a lot about this thing, but all the solutions were to get the access token by copy it manually.
is there a way to get the access token automatically by an API request?
It is possible. First of all, you have to integrate the facebook login to generate a user access token.
Look here to get started with the facebook login
The problem with this token is, it expires really fast:
Default User and Page access tokens are short-lived, expiring in hours, however, you can exchange a short-lived token for a long-lived token.
However you can use this to generate a long lives access token which expires normally in 60 days. Additionally it will get refreshed when the user uses your app within this 60 days.
This is the URL to generate the Long-Lives Access Token. You have to enter your app-id, app-secret and access-token. All three can be found inside the app you created on the facebook developer page.
"https://graph.facebook.com/{graph-api-version}/oauth/access_token?
grant_type=fb_exchange_token&
client_id={app-id}&
client_secret={app-secret}&
fb_exchange_token={your-access-token}"
Offical documentation to generate a Long-Lives Access Tokens
Hint: You can test all commands through your browser. Just replace the placeholders in the url with your data and put them into the URL-bar. Then you will get an JSON-response from the facebook graph API.
I have a Web API that provides the user all the data that needs to be shown on my mobile application.
OWIN JWT Authentication is implemented and it's working properly. There's an endpoint /oauth2/token which provides the user a token and all the endpoints has [Authorize] attribute filter to validate it.
The token expiration is set to 5 minutes.
Login session is maintained through a separated SESSION-ID which is stored into the Keychain and also server-side to check the active session. Everytime a user login inside the application a new token is generated and the user can access API methods to get data.
The question
What if the user leave the application opened for more than 5 minutes (Token expiration time)? The token will not be available since it has expired, how can I refresh it? And when should I refresh it?
I read about refresh tokens but not sure how to handle them (Is thist the right choice?), since the [Authorize] attribute will just reject my call if the token has expired, without providing an expiration message, I can't understand when it is an expired token or an invalid one.
What if the user leave the application opened for more than 5 minutes
(Token expiration time)? The token will not be available since it has
expired, how can I refresh it?
If I understand right, you set The token expiration to 5 minutes, that means if the user leave the application opened for more than 5 minutes, the token is no longer valid. Actually the user has to relogin to get the new token.
So back to your question, at the moment the token is expired, my advice is you can present the loginPage and tell user that he has to login again to use the app.
I don't know if there is another way to get a new token, if there is one, use may not have to relogin,.
Also, I found a thread that may help: webapi-2-0-how-to-implement-refresh-jwt-token-when-access-token-expired
I am using resource owner password flow and i got successfully access token and refresh token and i did not persist any token in database and everything works fine locally.
But when i deploy identity server in production refresh token is not working as expected.
i have set access token expired time 20 minutes and refresh token expiry time 7 days.
if i refresh access token within 20 minutes or before expiry of access token then refresh token refresh access token and work as expected but after expiry of access token refresh token does not refresh access token and throw invalid_grant error.
As i did not save refresh token in database and i searched on google but answers are confusion.
So can anyone tell me :
Do i need to store refresh token while it is working fine locally without storing ? if yes any implementation reference i am using mysql as database.
or something else i need to look.
Thank you.
Your response is valuable for me.
When running IdentityServer4 locally and "out of the box", things like refresh tokens aren't persisted and that's usually fine in the early stages of development.
When planning to deploy your Identity Provider to a server however, you'll need an operational store anyway (for storing grants, user consent, etc.).
This operational store can also store refresh tokens and reference tokens (read up on it in the IdentityServer4 docs).
Setting up token storage on the IdP is a good idea. Storing tokens opens the door to clean token revocation. A cleanly implemented sign-out in a client application would call the token revocation endpoint on your IdP. That's because when a user logs out, neither the access token nor the refresh token is needed any longer.
You can also revoke tokens from your end, making subsequent API calls fail for that access token and there are some compelling use cases for that as well.
I have a work flow that works like this:
User on mobile device uses a login with Google work flow and gets a token back.
User passes id_token to my WebAPI endpoint.
WebAPI validates the token via google endpoint, saves user data to a database, and generates refresh and access tokens.
When user needs to use my api, they provide access token via bearer authentication header.
If access token has expired or is going to expired, app provides refresh token and receives a new access token.
This is a pretty standard workflow I believe. Where I am currently stuck is how to generate a secure refresh token. I'm using ASP.NET MVC 5 and would love a little direction in how to generate this refresh token. I'm actually having a hard time even finding the refresh token format as well. I can generate an access token fairly easily using the JwtSecurityToken, JwtSecurityTokenHandler and SecurityTokenDescriptor classes.
Could this be as simple as using a symmetrical encryption algorithm on a json string and sending it over the wire?