OpenId Access Token updating values client side - oauth-2.0

I have a claim AllowEmailNotifications which allows the user to toggle notifications on and off in their profile client side. I originally had this value in their user profile object which is stored in sessionStorage client side which is updated in the database as well as sessionStorage when they toggle this value.
Is it safe to move this value to the Access Token and update the access token client side which is also stored in Session Storage or is this considered tampering with the token? I need it server side or should I just make a call to the database to get this value in the web service?
I'm not sure what is considered best practices with updating values in the access token via the app instead of the Authorization Provider?

An access token should definitely not be updated at client side.
Your client would need the signing key, because otherwise the signature of the token would be wrong and it wouldn't be accepted anymore.
I would just keep the setting in the database and get it from there when needed.

Related

Storing and retrieving access token when using Client Credential Flow in .Net

I m using a client credential flow to access the API. I am getting the access token each time client make a call to Web API which seem to me may not be good but not sure why. I looked through web I am getting mix answer, some say Client Credential flow doesn't return refresh token some say possible but it is not clear how. I looked at the project where it seem to store the token in the cache but doesn't show how it can be use when needing to get the access token.
Even if Client Credential flow doesn't support or send refresh token. I am searching for a way to store the access token and use it until is is not expired and get a new one when it is expire. This is where I am looking for support.
Beside that I do have relevant question.
Should I just get the access token each time? what is the downfall of it?
Should I include a Test method is Web Api to validate if the token is expired and return "Unauthorize" response based on that response I get the new token? With this approach, I will calling the API each time I need to access the API for actual purpose. So wouldn't I just get the access token from the Authorization server (Microsoft Identity platform).
Have a look at these resources:
https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Client-credential-flows
https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-net-token-cache-serialization?tabs=aspnet
One possible solution is to implement internally your own solution:
Get the Token.
A Dictionary is going to hold the (API type) as a key and the corresponding token as its value.
Next call check if the token exists in your Dic(TryGetValu(ket, out param)).
Check "ExpiresOn" on the AuthenticationResult (the Token) and compare its time for validation.
Remember to maintain your Dic by Updating or adding new tokens.

How should I use the id token returned to me by Google after a successful code exchange?

I am not clear on what exactly I should do with the id token from Google after the initial verification.
I'm developing on expo/react native and get the id token locally. Then, I send it to my server and verify it using google client libraries. Once it's verified what should I do with it?
Ideally I could use it to protect my api routes (express) but id tokens expire after 1 hour and I'm not sure how to refresh them with the client library. So, I don't know how I would do this.
Is that the intended use for id tokens? Should I instead be signing my own jwt and sending that back to the client? Then, the client could send that in the auth header of each request to a protected routes.
Google says:
After you have verified the token, check if the user is already in your user database. If so, establish an authenticated session for the user. If the user isn't yet in your user database, create a new user record from the information in the ID token payload, and establish a session for the user. You can prompt the user for any additional profile information you require when you detect a newly created user in your app.
https://developers.google.com/identity/sign-in/ios/backend-auth
Do I use the id token to "establish a session for the user"?
Yes, the ID-token is only used to create the local session, perhaps also create a local entry in your local database if that is used.
The ID token also have a very short lifetime, like 5 minutes in some systems. So it has no long-term use.
The ID token is intended to authenticate the user. It gives you information about the authenticated user, it should not be used to allow access to your endpoints. Access tokens or sessions are intended to do so. So in your case, you should do exactly as your gut feeling tells you - create a session for the user basing on the data you got in the ID token.
If you have your own Authorization Server you can use the ID token to issue an access token and return the token to the frontend app, then use the access token to access your backends. Have a look at OAuth flows if you would want to go this way.

Oauth 2: why refresh tokens must be stateful?

I'm working on a SPA app based on Node, with token-based authentication using JWT. Right now, the jwt token never expires, which is not good.
I want it to expire for more security, but I don't want my users to be forced to re-log. That's why I need a refresh token.
So i'm reading about OAuth2.
I have a hard-time to understand why refresh-tokens must be stored in a database, whereas access-token are generated on the fly using a secret key.
Why refresh tokens can't be generated the same way as access tokens ?
Thank you guys !
Refresh tokens usually are generated the same way as access tokens.
An authorization server will often return a refresh and access token if requested (and you're not using the implicit grant type).
The difference is how they are used.
An access-token is usually a bearer token: whoever has it can use it against the resource server, but it is only valid for a short period of time. In which case, storing them in a database is often pointless as they are worthless once expired.
A refresh token however is like having access to a "forge" which allows you to mint a new token.
If you present the refresh token to the authorisation server (not the resource server) you will get back a new access token and possibly a new refresh token.
Providing of course that the user has not revoked/changed access permissions to your application and that the user is still a valid user.
So you would keep them in a database perhaps because your user logs in infrequently. So you may need the refresh token weeks after you got it.
Alternative to the refresh token.
If you are using the implicit grant (which is common with SPAs but not recommended). You can try and keep your end user logged in to the identity provider used by the authorisation server. This way you can keep requesting new access tokens from the auth server without the user being prompted by the auth server for credentials as a session will be persisted between the identity provider and the user's browser.

Refresh accesstoken without user credentials?

currently I'm developing a gem (in ruby), which needs to access files in google drive. The whole authorization is done by OAuth2.0. Therefore I provide the client_id and client_secret in order to get an access token along with a refresh token. I store both in a database to access them anytime in the future. After 3600 seconds the access token is expired and I need to refresh it using the refresh token. Here comes the tricky part.
Can I get a new access token with a refresh token only? I'm refering to platforms like nimble. I registered once and have access to my files. But I still have access to my files on the next day, which means that they refreshed the access token somehow. Do they store my id and secret or what is the magic behind this? Or do they use SSO? And if so how can I get an access token from SSO?
Thanks for any advices.
Best regards
P.S.: I don't want to store the client id and secret, since these is sensible information, which I don't want to get stolen. Also encrypting it is not an option (so far).

dotnetopenauth - How to add extra data in the refresh token?

I'm currently working on a project where an iPad application requires access to an existing web application. The iPad application has been developed internally and is therefore a trusted application. However the data provided by the web application is sensitive so we don't want to store client credentials on the iPad. We also want the ability to revoke iPad access without affecting regular user access.
Given the above, the OAuth2 Resource Owner Password Credentials grant/flow was a good fit for our requirements which we've implemented with DotNetOpenAuth since its an established library.
However, we now require some metadata to be added to the access and refresh tokens for the resource server. The authorization server is adding the metadata via the AuthorizationServerAccessToken.ExtraData property in our implementation of the IAuthorizationServerHost.CreateAccessToken method:
public AccessTokenResult CreateAccessToken(IAccessTokenRequest accessTokenRequestMessage)
{
var accessToken = new AuthorizationServerAccessToken();
// Add some extra data to access token
accessToken.ExtraData.Add("server_parameter1", this.ServerValue1);
accessToken.ExtraData.Add("server_parameter2", this.ServerValue2);
// Set ResourceServerEncryptionKey properties etc
return new AccessTokenResult(accessToken);
}
This does exactly what we want for the access token however the same "ExtraData" is not included in the refresh token which causes an issue when the access token expires and needs to be refreshed because we effectively lose the additional data (since the old access token is discarded).
Can anyone advise if its possible to populate the refresh tokens "ExtraData" in the current version of DotNetOpenAuth in a similar way to the access token?
No, I don't think there is currently a way to embed extra data into the refresh token. Let's talk a bit about why this is.
First off, there is no such thing as a trusted iPad app, whether you develop it or not. The problem is that apps you distribute (even internally) can't keep a secret. Any client_secret, certificate, etc., can be cracked. Therefore apps you distribute can't authenticate themselves to the server. If the server can't authenticate the client, the server can't trust the client.
Now let's look at your scenario a bit more (and if you have more feedback, it may be best to continue the discussion on dotnetopenid#googlegroups.com). The client has data that it wants to eventually end up at the resource server. You're currently trying to pass that data through the authorization server first, then via the access token to the resource server. Why is that? Why not just have the client send the data directly to the resource server along with the access token? If the answer is that the resource server shouldn't trust the client, then what you have by sending it by way of the access token is a false sense of security for the reasons given in the above paragraph. If the client could provide false info to the resource server, it could also provide false data to the authorization server.
One valid use of extra data in the access token is data that the authorization server knows for itself -- not data that came from the client. In which case, it can look up that data each time an access token is minted and doesn't therefore have to be stored in the refresh token.

Resources