Get refresh token with Azure AD V2.0 (MSAL) and Asp .Net Core 2.0 - asp.net-core

I've got access_token from Azure Ad V2.0 endpoint to call Graph Api. But I have to do some actions in the api on behalf of user. So I need refresh_token to renew my access_token when it'll expire.
Is there any way to get Refresh token using MSAL in ASP .Net Core?
In microsoft documentaion they're telling it's possible to do by requesting /token endpoint. But I couldn't find how to do it using MSAL.

MSAL .NET does not expose the refresh token, but rather keeps it internal and handles all token refresh and caching logic on the app's behalf.
The docs you're referring to are referencing the protocol itself that MSAL is completing on your behalf. It goes to the /token endpoint with an authorization code (after the end user signs in), and is issued an Access and Refresh token. The Access Token is valid for 1 hour, and when it's expired, AcquireTokenSilent will automatically use the refresh token against the /token endpoint to get a new access token.

I got a bit topsy-turvy on this, as well. Explaining a bit more based on my understanding.
For context, OAuth 2.0 code grant flow mentions the following steps:
authorization, which returns auth_code
using auth_code, to fetch access_token (usually valid for 1 hr) and refresh_token
access_token is used to gain access to relevant resources
after access_token expires, refresh_token is used to get new access_token
MSAL.NET abstracts this concept of refresh_token via TokenCache.
There is an option to serialize TokenCache. See Token cache serialization in MSAL.NET. This is how to preserve sign-in info b/w desktop application sessions, and avoid those sign-in windows.
AcquireTokenSilentAsync is the process by which refresh_token is used to get new access_token, but, this is internally done. See AcquireTokenSilentAsync using a cached token for more details and other access patterns.
Hope this clarifies on why TokenCache is the 'new' refresh_token in MSAL.NET, and TokenCache is what you would need to serialize and save. There are libraries like Microsoft.Identity.Client.Extensions.Msal that aid in this.

TokenCache is basically a JSON object which is served as byte array when you call SerializeMsalV3(). When you convert byte array to string, you will see both access token and refresh token. Then you can make a HTTP request to \token endpoint with this refresh token and grant_type: "refresh_token" body parameters.
IConfidentialClientApplication capp =
ConfidentialClientApplicationBuilder.Create(myClientId)
.WithClientSecret(myclientSecret)
.Build();
capp.UserTokenCache.SetAfterAccess((TokenCacheNotificationArgs args) =>
{
exchangeTokenCacheV3Bytes = args.TokenCache.SerializeMsalV3();
string jsonString = System.Text.Encoding.UTF8.GetString(exchangeTokenCacheV3Bytes);
});

Related

Cookie-based JWT token refresh: is a separate call to the `/refresh` API endpoint really necessary?

I'm using .NET 6 with HttpOnly cookie-based JWT authentication in my WebAPI, and I'm now implementing token refresh.
I store the JWT and a Refresh Token in cookies, e.g.:
X-Access-Token: eyJhbGciO...
X-Refresh-Token: d8085ec8-d0bc-4e5c-b6b6-cd76146c419f
Most flows I've found for token refresh look like this, with the client calling the /refresh endpoint to get a new JWT:
client sends request to server
server rejects request with a 401 Unauthorized
client requests new JWT (expired JWT and Refresh Token automatically sent to server in cookie)
server validates cookie Refresh Token, generates new JWT and Refresh Token, assigns to cookies
client sends original request to server, with the new JWT and Refresh Token in the cookie
My question is:
When the initial request with the expired JWT is received by the server, since the server already has the refresh token (sent in the X-Refresh-Token cookie), can't the server issue a new JWT and Refresh Token at that time and successfully complete the request? This completely eliminates the need for a separate request and response to refresh the tokens. This is the flow:
client sends request to server
JWT is expired, but Refresh Token is valid
server creates new JWT and Refresh Token, assigns to cookies
server successfully completes the request
Is there a vulnerability or security risk implementing the refresh this way? I cannot think of one, but I could not find any examples with this flow.
Thanks!
Why are you using JWT access tokens? If the server could respond with an updated access token by looking at the refresh token, then why wouldn't the server just look at refresh tokens every time, and then the JWT access tokens aren't needed?
The point of using JWTs, and access tokens in general, is that it allows stateless authentication with services that have no access to the refresh token store. Usually, you will have an authentication service, it stores the refresh tokens, and calls to /refresh get routed to it, and it will validate the refresh token, and issue the access token. Then, calls to other services are able to validate the access token, without needing to make any calls on the authentication service. So, the reason why they don't just reply with a new access token when authentication fails is because those services are incapable of checking the refresh token, they don't have access to the refresh token store, only the authentication service does.
If however your application is one big monolith, where every endpoint is hosted by the same server and therefore is capable of checking refresh tokens and issuing access tokens, then there is absolutely no reason for you to be using access tokens or JWTs in general. You should just use refresh tokens, which, in this case, would be better called a session token.

JWT auth flow using access token and refresh token

I'm working on a project (nothing production-level, only for leveling up my skills) and I'm using JWT to handle authentication.
From what I've read, using a JWT only as an access token is quite unsafe, and hence we need refresh tokens. So, on login, the server returns an access token and a refresh token (which I will be storing in an httpOnly cookie). The access token expires in a short time, but the refresh token is used to get a new one when it does.
My question is, when do we use the refresh token to get a new access token? Is it when the user wants to get a protected resource and finds that the access token is expired (and the refresh token has not) or do we send a new access token each time the user wants to get the protected resource? I'm confused about when and where the refresh token comes into play.
(I'm using React for the frontend and Nodejs for the server)
You're using some security token so it mean that your system has some protected resources. Those resources can only be accessible on successful validation of the token. As you're using the JWT Token (usually for stateless authentication) and your system is granting both access_token and refresh_token to the client, so on server side you can use some authentication interceptor to validate the access_token in the each private request and return some error code on token expiration. On the client side you could also use some filter which should capture the error code and by utilizing the available refresh_token it should request for new access_token from the server. In case of refresh_token expiration your system should follow the route of fresh authentication.
The refresh token can be used at any time to request a new access token. Checking the validity of the access token before he request is one way of accomplishing that. Another common practice is to refresh the access token if it is within a certain timeframe of the current token expiring. A simple cronjob can work in this case. If you assume the access token is not used in multiple places (which it shouldn't be) then the current access token can be invalidated when the new access token is created. Also, for maximum security, the refresh token should be replaced with the access token. This limits security risk around a long-living refresh token becoming compromised.

Getting refresh_token server-side (sessionToken) with Okta

We wish to use our own httponly strict cookie with access and refresh token in it for our microservices architectures.
We are primary using OKTA Authentication API to log users with our own custom Sign-in page.
We were able to get the access_token on the authorize endpoint using the responsetype=token with sessionToken and redirecting the result as a form_post on our back-end endpoint.
I was unable to retrieve the refresh_token despite adding the offline_access in the scope even if it is checked in my okta application setting.
I don’t want to use resource password flow since we prefer using sessionToken which will work with multi factor if needed in the future.
I also try using the code flow and redirecting the result on our back-end but since the code flow is client-side it’s return this error "PKCE code verifier is required when the token endpoint authentication method is ‘NONE’." This error occur even if we choose a .NET application
How can we retrieve the refresh_token server-side with Okta?
Responded to your post here https://devforum.okta.com/t/getting-refresh-token-server-side-sessiontoken/12419/3.
Aside from making a call directly to /token with your access token you can also check our Early Access feature called Refresh Token Rotation. Let us know if this helps!
I was able to use the CODE flow and redirect from server-side to the authorized endpoint like so:
https://{YOUROKTADOMAIN}/oauth2/default/v1/authorize?client_id={YOURCLIENTID}&response_type=code&scope=openid%20offline_access&response_mode=query&redirect_uri={YOURSERVERSIDEGETURI}&state={Guid.NewGuid()}&sessionToken={SessionToken From Auth API}
This call will post back to my same server, so i can handle token myself and create my own cookie.

Oauth + SPA + API backend

I'm setting up a service which needs to authorize against an existing Gitlab as OAuth Provider.
The service is a SPA which gets served by a webpack dev server in dev mode and a nginx server in production mode.
I'm also setting up an external API which should handle the Database and make request to the given gitlab instance (for example pull repos).
My SPA is authorizing against the Gitlab OAuth with the implicit_grant flow and is getting an access token. Currently I pass the access_token after the redirect to my API backend and there I get the Gitlab userid and username via a request to the gitlab instance with the access_token. With these I generate a jwt and send it to the client (SPA) and save it there so I can authorize my API with this JWT.
How would I handle the initial access_token in my backend (cause I need the token to make gitlab calls)?
Currently I'm thinking about writing it to the user in the database and get the user everytime he makes a request (normal passport flow), so I also have the token. But what if the token gets invalid or expires?
Should I use an interceptor in the backend and if the token is invalid (gitlab would give me a 401) redirect the 401 to my client, let him get a new token and pass it back to the backend, generate a new JWT, send this again to the client and let him do the same request as original reuested(via interceptor, too)?
Or should I just redirect the 401 to my client, let him get a new token, let him post this token to for example /renewToken and save the token to the database and use the old JWT?
Hope someone can help me unserstand this flow.
The Credential Management API should be what your looking for on the client. That will retrieve the id and access tokens to that you can compare access tokens with your server/ap and then validate the id token.
Haven't seen a Git example but there are Google and Facebook examples.
You could let the user send the initial access token and your backend API will just act based on the initial access token. Seems to me that it is not necessary to produce another JWT token in this case.

Why don't APIs use access token instead of refresh token?

I've already seen
Why Does OAuth v2 Have Both Access and Refresh Tokens?
https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/
As per my understanding, this is how OAuth v2 works:
1) user sends his credentials to the server which validates it and returns an access_token and a refresh_token
2) user sends this acsess_token along with further requests to identify himself
3) when the access_token expires, the user sends another request to the server with refresh_token and other required parameters asking for a new access_token and refresh_token
Here's my question:
What's the need of a separate refresh_token ? Why not send the old access_token ( which is about to be expired anyway ), for a new one ??
What's the additional advantage of using a refresh_token ?
The access token is, in theory, more in play. It could be in a browser, on the server-side of a client, on the authorization server or on a resource server. The access token will be attached to every API request whereas the refresh token should be used much less frequently.
A couple quotations from the web...
Unlike access tokens, refresh tokens are intended for use only with authorization servers and are never sent to resource servers.
https://www.rfc-editor.org/rfc/rfc6749#section-10.4
[Refresh tokens] are usually subject to strict storage requirements to ensure they are not leaked.
https://auth0.com/learn/refresh-tokens/
Basically, if we only had access token, the attack surface would be greater.