Blazor Client Side authentication jwt or cookies - c#

So i am experimenting with client side blazor and trying to figure correct implementation for JWT or Cookie authentication.
Suppose that i have a service that serves the tokens and refresh token on client side i will have multiple API Services that will need to use this token or cookies to create API requests.
So as i understand i will need to implement and API Service classes similarly as documented here https://learn.microsoft.com/en-us/dotnet/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests
So in order to have a consistent authentication state an Authentication service should be introduced and injected to the API Service classes. This service will have the responsibility of doing auth,getting initial token and doing a refresh token when required.
So with the latest release of Blazor there is this new component called AuthenticationStateProvider, the use of it seem to be clear but the question is would it be correct approach to use this as a global Authentication service?

So HttpClientFactory is not supported on the client. In client-side Blazor, HttpClient is added to the DI system, and you can inject it into your components or classes.
So you want to use AuthenticationStateProvider as global Authentication service ? I'm not familiar with this component, but I'm afraid, from the short read I had after reading your question, that it is not an authentication system, but a tool to provide authentication state information, such as user age, etc. You still need to configure the Jwt middle ware, create a controller responsible for issuing the Jwt token, and so on. And I guess that you can employ the AuthenticationStateProvider to provide your client app with authentication state before a user, say, logged in and after, etc. I do hope I'm not wrong about it, at least not entirely.
So hope this helps...

When using JWTs on unsecure clients like SPAs, it's a bad practice to implement refresh tokens, as those are meant to be private.
The current OIDC recommendation (for SPAs) is to implement the Authentication Code Grant strategy.
I would recommend you to take a look at Blazor-Auth0 library (author here), it implements the Authentication Code Grant strategy blacked on Auth0, so you don't need to reinvent the wheel (and it's free).
Even if you don't want to add a new dependency, you would find it as a good source of examples of how to implement JWT authentication and authorization in Blazor.
https://github.com/henalbrod/Blazor.Auth0

Related

Is there a way to secure microservice endpoints with Jwt without using an APi Gateway architecture

I am working on a spring-boot microservice application, user management module and The AuditTrail service module to be specific and I am tasked to create and Secure endpoints with jwt and other microservices (which can be .net, Django etc) are to use this token to secure endpoints. i have finished building the user management system but now i'm stuck cause I don't know how to go about validating jwt on other microservice systems and i have been instructed not to use the Api gateway architecture.
I am thinking to expose maybe an api/vi/auth/authenticate endpoint that other microservices can call but I'm not sure if there is a better way. maybe share the jwt secret and algo used to create token with the other microservices and every microservice just validates a token by it self. the later approach involves writing boilerplate code as far as I can see but I don't know if these are my only options and what flaws they might have to see if it is something I am able to manage.
As long as you sign the JWT with an asymmetric algorithm (e.g. RSA ECDSA etc.) can have the auth server save the private key to itself, and only share the public one with the services
do note that if you don't go to the server, you have a risk of a token being revoked and the service not knowing that - so you want to keep the token expiration short
To manage authentication in the microservice ecosystem you need an independent microservice authentication which could be SSO (single sign-on). The best practice and most secure way is using Oath and OpenId for this approach and To not invent the wheel from scratch, you can use some standard production like IdentityServer4 (more complicated but full-featured) of OpenIdDict(more simple) and lots of other, which provide both of authentication and authorization in a secure and standard way for you.
They provide an Access token which is JWT with lots of claims to handle your scenarios easily. Also, they have a standard URL address that exposes their URLs (for example URL/.well-known/openid-configuration which you can see here to see real result ) .
I suggest to implement a serious project following the standards of the industry.

Blazor JWT Authentication

I am trying to figure out correct way to implement JWT auth with Blazor (WASM).
After going through the docs a got an idea on how the built in components work but still the whole picture is not clear to me.
So in my scenario i have an API sever that will be used, the API server can issue JWT tokens and they can be used to authenticate against the endpoints where required.
So right now i am trying to figure out the correct role for each component.
For start we have AuthenticationStateProvider, as i understand this component has the responsibility of obtaining the JWT token either from server or if one stored locally, also it could handle token refresh when required?
Now since i will be using Typed HTTP Clients i will be using IHttpClientFactory, along with that i will have AuthorizationMessageHandler to attach tokens to desired HTTP Client instances.
Things fall apart for me when i am trying to deal with IAccessTokenProvider, as i understand the default implementation will be called once a HTTP Client is created and http request is about to be made.
What is not clear is how this IAccessTokenProvider will obtain the token.
So the question is whether i should create my own implementation of IAccessTokenProvider and if so how it should handle the tokens.
As i said i wont be using any built in authentication providers and will have my own JWT auth system instead.
Thanks.
The first three paragraphs are very clear and correct. This is how you should do that. I can post here some code snippet to demonstrate how it is done in practice...
Things fall apart for me when i am trying to deal with IAccessTokenProvider,
No wonder... The IAccessTokenProvider is not relevant here. The IAccessTokenProvider is a token provider used in the new JWT token authentication system for WebAssembly Blazor App. But if you want to implement the JWT authentication yourself, you must do that as you've described in the first three paragraphs... which I can summarize like this:
When a user makes a first access to a protected web api endpoint and he's not authenticated (or registered), he's redirected to the relevant pages, type his credentials, etc, which you pass to your Web Api end point dedicated to authenticate the user (register if necessary, etc.), after which the action method called produce the JWT token, and send it back to the WebAssembly Blazor App running on the browser. You should store the JWT Token (perhaps in the local store), and retrieve it whenever you perform HTTP calls (Adding the JWT Token to the headers of the request).
The above described process also involve the implementation of the AuthenticationStateProvider object, that is updated with the authentication state, and notifies subscribers, such as the CascadingAuthenticationState, that the authentication state has changed, at the end of which process other components and objects adapt themselves to the new situation... you know, re-rendering, etc.
So, you see, you've received a JWT Token from your Web Api, stored it a local store, read it, and use it. Reading the Jwt Token from your local store and parsing it, to great extent, is something that the IAccessTokenProvider does, but in the new authentication system, and as you do not use this system, the IAccessTokenProvider is not relevant.
What about automatic Token injection in headers of HTTP client, can i or should i still investigate custom AuthorizationMessageHandler or this component would not be usable without IAccessTokenProvider?
You may add your Jwt Token to each HTTP call as demonstrated below:
#code {
Customer[] customers;
protected override async Task OnInitializedAsync()
{
// Read the token from the local storage
var token = await TokenProvider.GetTokenAsync();
customers = await Http.GetFromJsonAsync<Customer[]>(
"api/customers",
new AuthenticationHeaderValue("Bearer", token));
}
}
which is perfectly fine. But of course you can create a custom DelegatingHandler modeled after the AuthorizationMessageHandler or still better the BaseAddressAuthorizationMessageHandler as you're going to use the IHttpClientFactory to provide your HttpClient service. Try first to attempt to use them without any modifications, and if it's not practical just emulate their functionality.
The last things that bothers me is the implementation of obtaining access token and storing it locally.The best approach i can think of so far is to have a global authentication service, this service will provide the functionality of obtaining the token, refreshing it, storing etc. Both IAccessTokenProvider and AuthenticationStateProvider will use it when token is requested plus will be notified whenever authentication state changes like user logs in or out.
Perfect... Note: The AuthenticationStateProvider should be notified of the change in the status of the Jwt Token. As for instance, when you get a new token from your Web Api endpoint, your code should add it to the local store, and then notify the CUSTOM AuthenticationStateProvider of the change. Your code also should notify the AuthenticationStateProvider in case you delete a Jwt Token, so that your user interface will reflect this changes, etc.
Good luck.
Hope this helps...

How to Authorize request from another WebApi project

There are 2 WebApi Projects on different servers. One of these servers (WebApi-A) has OAuth2 authentication workflow setup with Authorization Server and all.
The another WebApi project (WebApi-B) has an end point that I would like to Authenticate through [Authorize] attribute. I don't want have a new authorization server but to utilize (WebApi-A's) authentication process just to validate the token.
From what I understand if the machine-key is same across these server. We can essentially replicate the authentication process from WebApi-A in WebApi-B without having to call WebApi-A at all.
How do I achieve this?
You could, in theory, pass through the JWT token and if your OAuth setup uses the same client secret and data store it should just work. You would have to ensure that you add the JTW token when requesting and to use some distributed cache to verify.
I would rather ask whether or not you should rather create a gateway that can handle and authenticate the requests and delegate them to the separate APIs? This feels like an identity server (http://docs.identityserver.io/en/latest/topics/apis.html) would solve your problem. Anything you do other than moving the authentication from web api A would just be a stopgap.
Duplicating the setup could work but that will mean that you have to now maintain it in two places. So I agree that doing that is less than ideal.
This is a great article that may aid you:
https://www.scottbrady91.com/OAuth/Delegation-Patterns-for-OAuth-20
This will have a lengthy answer so I will just leave you this diagram showing multiple Resource Server, Client, and a separate Authorization Server
Taken from this article Single sign-on across multiple applications (part II) which I hope could get you started.
you can use your token when login in web api and then you add the token to the header "Authorization" with bearer "your token"

WebApi - Tokens vs Cookies

I’m working on an existing single-page application consuming data from WebAPI.
Authentication is largely handled with WebSecurity and SimpleMembership via forms authentication as the application was originally built on MVC.
I know that this is bad (CSRF), and I want to fix it either by
implementing some kind of CSRF protection (preferred)
or by reimplementing Authentication and Authorization to use tokens instead of cookies.
Would implementing header validation be an adequate solution? The API is being consumed by both web and mobile clients, in case it matters.
I’m not too skilled around security and want to make sure we’re not setting ourselves up for vulnerability by using cookies here.
Well, you would have to leave cookies anyway because otherwise you wouldn't be able to authenticate returning users (they would have to authenticate every time they open the app page). (Of course there are other exotic options like using client local storage or "Flash cookies" but this is pretty much the same approach.)
To answer your question, yes, you will need to implement CSRF protection. It doesn't matter which implementation you choose: it can be the implementation that uses custom HTTP headers or additional WebAPI request params, it can be implemented using built-in anti-forgery API (described in the article you mentioned) or you can make your own implementation.
I would probably implement custom CSRF protection mechanism because this way you can make it more suitable for your SPA (for example you can send it through WebAPI response as a result of authentication operation instead of rendering it to the HTML or JS as it was suggested in the article).

How to get started with OAuth to secure a Web API application?

I have a Web API application and I've understood OAuth would be the standard security model for APIs where an Authentication Server would become responsible to generate Authorization Tokens so that the user can send to our server and consume the services.
I'm very new to this but I understand the roles involved:
Resource Owner
Client
Resource Server
Authorization Server
But what is OAuth exactly in practice, not in theory? Is it a .NET library? Is it a service provided by a separate Company? Is it something I can configure on my local development machine and see how it works?
How to get started with OAuth to secure a Web API application?
OAuth is a protocol; the current version is OAuth 2.0. More to your question, that link lists several implementations of the protocol in various technologies. For use with the .NET Web API you're probably interested in DotNetOpenAuth which provides implementations of both OAuth 1 and OAuth 2.
I'm using DotNetOpenAuth in an app I'm working on now to secure a .NET Web API. I've got an OAuth2Handler which extends DelegatingHandler which is inserted into the Web API pipeline before incoming requests reach any controllers. OAuth2Handler does the following:
Instantiates a DotNetOpenAuth ResourceServer
Calls ResourceServer.GetPrincipal() which reads and decrypts an access
token (issued elsewhere by the AuthorizationServer and returns an
OAuthPrincipal (In my case I'm reading additional data that the DotNetOpenAuth implementation allows you to pass and creating a ClaimsPrincipal.)
Assigning the IPrincipal containing the user information read from the access token to the User property of the thread and current HTTP context so it is available from the ApiController.User property in the service controllers: httpContext.User = Thread.CurrentPrincipal = principal;
Honestly, getting this all working (e.g. setting up the authorization server, resource server, certificates, etc.) isn't trivial. Unfortunately there didn't seem to be a good guide on the DotNetOpenAuth site. Here's a few other tasks you'll have ahead of you if you go this route:
Implement IAuthorizationServer - This is the interface provided by
DotNetOpenAuth that allows you to plug in to the library and use
their implementation to issue OAuth2 access tokens. You'll also need to implement INonceStore and ICryptoKeyStore which I did using an EntityFramework context for storage.
Configure Certificates - The AuthorizationServer and ResourceServer each use certificates to encrypt/decrypt the access token ensuring they are only accessible to each other. I built some custom configuration so I could manage this configuration in the web.config files of my authorization server app and my Web API services (resource server).
Manage Refresh Token - When first requesting an access token from the authorization server you'll get back (depending on your configuration) both an OAuth2 refresh token and an access token. The services use the access token which should be short-lived. The refresh token is used to get more access tokens. The refresh token should be kept secret (whatever that means in your scenario). For me it means the refresh token is never exposed to client-side javascript in my web app.
I hope that helps give you a high level idea of how to get started with OAuth and .NET Web API. Here's a blog post demonstrating some of these steps. This SO answer gives a few more high level details of the client side of the picture.
(The DotNetOpenAuth online docs appear to be down right now... sorry for no links to them; Apparently it has happened before).

Categories