Where to store Access and Refresh tokens when consuming external APIs using IHttpClientFactory. Net Core - asp.net-core

I am using IHttpClientFactory for sending requests and receiving HTTP responses from my Web API to an external APIs using Net Core 2.2.
The access token and the refresh tokens used to send the request to the API have been stored in the appsettings.json. When a request returns 403 or 401 errors, I get a new token dynamically and add it to the header of the request.
But How Can I update appsettings.json with the new access and refresh token in order to use it for subsequent requests.
Is It there a much better approach to store access and refresh tokens than the appsettings.json?

Since you are using IHttpClinetFactory (and assuming you are using Typed Client as well), you can create your own HttpMessageHandler which would be triggered before any request made by your Typed Client and link it with your typed client via DI like this:
services.AddHttpClient<IServiceContract, ServiceImplementation>()
.AddHttpMessageHandler<TokenHandler>();
Inside that TokenHandler you can check if the request has a token in the headers or not. If not check the cache (Memory Cache) for available tokens, then validate the lifetime of the token.
If the token is expired or there is no such a token in the cache, issue a new one and store it in the cache.
I am sure there are better ways, but that what I would do.
Note: If your application is distributed on multiple servers, then use Distributed Cache instead of the Memory Cache. You can add either easily via DI.
Update:
You can register your handler like this:
services.AddTransient<TokenHandler>();

Giving the hypothesis your client WEB API connects automatically to your external APIs (and also, ask automatically the tokens), you don't need to store tokens and refresh tokens.
Your webservice needs to keep the tokens in memory (in a singleton) and use it whenever needed.
When the external API wants a new token (e.g. after token expiratoin), you just need to ask a new one and update your singleton.
We use this way of working for several projects and it's reliable.

In general, you should store the token in database for permanent save by EF Core or any other data provider.
If you insist on saving in the appsettings.json, you need to implement the custom feature.
For a demo, check Manually trigger IOptionsMonitor<>.OnChange

Related

What are the benefits of implementing OAuth (JWT access tokens with refresh tokens)

Current Setup
I'm currently building an application, and have just finished implementing an OAuth authentication server. This is my first "real" attempt at a project that has a legitimate user authentication and management component, so much of this is new to me.
I've implemented the OAuth specification. This means the following:
The authentication is deployed on a separate webserver with a separate DB than the application server.
The auth server logs in a user, and issues them two tokens. One is a JWT access token that contains information about their user identity. This has a short-lived 15 minutes expiry. The second token is a refresh-token. This is a single-use token with a 7 day expiry. It is used to fetch another access token with the application server returns a 401 (the access token has expired).
The application server shares a secret key with the auth server, and has middleware that verifies the JWT access token.
Concerns
My concern is that I've over-engineered a project that didn't need this much complexity. Since the auth/app are distinct, this means that my client code needs to be aware of, and handle refresh token rotation. It needs to interpret 401s, and fetch another access token.
As far as I can tell from my reading, this wouldn't be necessary with simple session cookies that persist. The cookie is just included in requests to my domain. If I killed this approach, and just had my server do a DB lookup on a signed session cookie - I would avoid a lot of this client complexity.
One consideration is that I’m using a React SPA frontend client. This is also new territory for me, so I’m not sure whether or not this changes the situation.
As I said above, I'm new to a lot of this so could use some advice from people who have worked in this space for longer and have the experience. Is OAuth worth the hassle?
Options
OAuth with access tokens (JWTs) and refresh tokens:
Pros: Provides a secure and scalable way to handle user sessions.
Cons: Client needs to be aware of refresh token rotation procedure and handle 401 responses by using the refresh token to request a new access token, which can add complexity to the client-side code. Also adds complexity (and cost) to the AWS infra stuff. I need to know how to get the auth server and app server on the same base URI. Also makes my local dev environment a little more involved.
Server-side sessions using signed cookies:
Pros: Simpler for the client, as it does not need to handle refresh tokens or 401 responses.
Cons: Server needs to manage session state, which can be more resource-intensive. This means a DB call on every request.

Blazor Server, API with OpenIdDict and using introspection - What to do with the access token?

I have an API that is also hosting an OpenIdDict token endpoint. The API does not have any web pages with login forms but instead returns an access token in a response as a result of receiving a form post.
I previously had an old AngularJS frontend which talked to the API to get the token and stored those on the client. Angular was responsible for adding the token to every request to the server.
I am now planning on rebuilding the frontend using Blazor Server. I want the new Blazor Server client/frontend to use introspection against the APIs token endpoint.
My plan was to build a custom Login page that on post would, server-side, talk to the API and get an access token, refresh token, etc. But I have no idea where to put the access token afterwards so that it's used by Blazor through introspection whenever I use the Authorize attribute. I could just return the tokens and maybe write some javascript that saves it somewhere and adds it to any subsequent http requests, but that does not feel like a Blazor Server solution?
My latest discovery is that the tokens could be stored "in session" on the server and a "session identifier" cookie is created on the client? Might be completely off here...
When I played around with the Identity support in Blazor Server a cookie with the name ".AspNetCore.Identity.Application" was always created after a successful login.
Another less desirable solution, or workaround, I have been thinking about is copying the API's OpenIdDict-setup code over to the Blazor Server project and point them to the same database.
Any help here would be greatly appreciated!
My plan was to build a custom Login page that on post would, server-side, talk to the API and get an access token, refresh token, etc. But I have no idea where to put the access token afterwards so that it's used by Blazor through introspection whenever I use the Authorize attribute. I could just return the tokens and maybe write some javascript that saves it somewhere and adds it to any subsequent http requests, but that does not feel like a Blazor Server solution?
You can store the Access Token in the local storage, and retrieve its value whenever you want to use it. Yes, it is Blazor Server solution. That is how you should do it.
When I played around with the Identity support in Blazor Server a cookie with the name ".AspNetCore.Identity.Application" was always created after a successful login.
This is true. Is this a statement or you're asking a question here ?
Anyhow, I guess this cookie will be automatically removed when its life time ends. But in your case, you'll have to do it manually; you'll have to write code that checks whether the access token has expired. If you do not do so, your app will have issues when you try to access a Wep Api endpoint. There is also the authorization components and objects in Blazor that will wrongly perform if you do not manage the stored access token, as for instance, the AuthorizeView embedded in the LoginDisplay component will show the name of an authenticated user (because the claims you extract from the access token constitutes the data from which the AuthenticationSateProvider creates the AuthenticationState object), but no checking of the validity of the access token is perform. But
accessing your web api with the current access token will result in an exception as the access token is not valid.
I've described above something that should be explained by text of hundreds of pages. Hope you're not much confused.
Here's the best place for you to start your investigation Customizing the AuthenticationStateProvider in Blazor Server App with Jwt Token Authentication
Hope this helps...

How are you supposed to store access tokens?

We are building an application with a React/Redux frontend and a NodeJS/Express Backend. I, not being a security expert, opted to go with Auth0 to handle Authentication.
Auth0 returns an ID Token and an Access Token when a user logs in, this access token is used to authenticate and access our backend API.
We've seen this Access token stored before in Local Storage but Auth0 then contradicts that here. Furthermore, in this answer it seems that some recommend storing in Local Storage, as does this one.
This has me terribly confused. How can we store and persist the token without storing it in memory? We could store it in Redux only but it'll clear on refresh which isn't a solution.
Here they show that the User Signs in and the Access Token is returned and that later it is to be sent along with API Requests, which I understand, but where is it to be stored in the meantime?
How are we supposed to store the access tokens so our application can access our API? Or are we not supposed to store it at all?
We decided to store access tokens in a React Context Provider. Looks like Auth0 has updated their quickstart guide to do the same.
The best way to store AT/RT is by using a distibuted cache memory for your client backend servers. By this way, you make sure that all API calls must transite by your backend application. In your frontend, you pass only the ID_Token witch has to be used to identify your end users.
User sends ID_Token --> Client (backend web app) checks the Id_Token and Get AT from cache memory --> Call the APIs with AT.

Web API security using tokens

I have built a Web API and now I am trying to determine the best approach to secure it.
I would like to use tokens along with credentials and thus, once the user is validated, on future requests a token can be passed with the http request. This API will always be called by one particular account and the username/password will always remain the same.
I am working with an already existing site backend, which has its own login implemented and stores user data. So I would like to stay away from creating new database tables to store user records. For that reason, I think implementing .Net Identity is maybe a overkill.
One of the options I am thinking of is grabbing the credentials from the http request and attempting the SQL connection with it. If the connection passes, then the user is legit. If it does not, it means I have to return access denied. Is this a good way of going about it? If yes, what can I use for token generation and validation?
Check out this guide which is specific for Oauth tokens with .NET:
OAuth with JSON Web Tokens In .NET
Also, make sure to follow the guideliness, because tokens must expire and be renewed after a while, for security reasons. You shoudn't use a permanent token, of course.

Can't modify user private data with Client Credential Flow by Spotify Web API

Is there any method to modify i.e. playlist by Web API by with console based application in Client Credential Flow ?
https://developer.spotify.com/web-api/authorization-guide/#client-credentials-flow
Propably not, but maybe I am wrong ? I want to modify only my user's data.
Here I created issue at API specification
https://github.com/spotify/web-api/issues/165
One of the benefits with the Client Credentials oAuth 2.0 flow is that applications can make authenticated requests to a web service without a need to involve an end user. Since a user isn't involved, the requests that can be made from the application is limited. For example, using Spotify's API, you can still make requests to retrieve track metadata, playlist contents, and search for albums. Any endpoint that requires a scope can't be used since it requires user interaction.
So using Client Credentials simply doesn't make sense if you're interested in making requests on behalf of a user, or if you want to access private data since the user needs to give you permission first.
You need to use Implicit Grant or Authentication Code Flow for this. I advise that you read further about the supported oAuth 2.0 flows in the Authorization Guide. One of the benefits of using the Authorization Code flow is that you'll also retrieve a new refresh token, which you can use to retrieve access tokens indefinitely. It however requires you to write a web service that accepts an authorization code and exchanges it for the tokens. The Implicit Grant flow doesn't return a refresh token, so it's only possible to use for one hour until the access token has expired.