adding claims accesstoken validation identityserver3 - asp.net-web-api2

I'm using Idsrv3 as my Authentication provider. My Api is validating the token and creating the correct principal etc, just as it should. Now I wish to add application specific claims to the principal after the validation is done and the principal is created but before anything else in the WebApi pipeline is executed.
I could write my own DelegatingHandler I suppose to handle this, but is there a cleaner way?

You can put middleware in the pipeline after the Bearer token authentication middleware, but before your web api framework. In this custom middleware you can inspect the incoming claims, and change or replace them with whatever else you want.

Related

Asp.Net Core API OpenId-Connect authentication with JWT token using IdentityModel

I have an ASP.NET Core API as back-end for an Angular SPA front-end. I am using Cognito as an Identity provider and want to create an OpenId-Connect authentication using authorization code flow which would mean that all the secret credentials will be stored in back-end.
The authorization flow should be like this (standard OpenID Connect flow):
FE application calls /authorize endpoint and is redirected to Cognito hosted UI.
After entering credentials FE receives an authorization code.
FE calls BE with authorization code.
BE calls /token endpoint and receives accessToken and refreshToken.
BE Returns accessToken to FE and sets refreshToken as httpOnly cookie(for this not sure, I may store it in Redis cache).
Then, FE with each request will add Bearer AccessToken to authenticate. When AccessToken is close to expiration, it will be updated using refreshToken.
I was experimenting with this example but here application used an Asp.Net Core cookie for authentication and ignored accessToken and refreshToken. I was authenticated even after accessToken was expired. Also, there's not much documentation on how ASP.NET cookie works.
So, now I am thinking about having my custom BE endpoints and use IdentityModel helper methods but not sure if it is a good practice to handle authentication like this.
/Login - gets AccessToken and RefreshToken
/Refresh - updates AccessToken using RefreshToken. FE will call it manually when accessToken will be close to expiration.
So, is there a "recommended" way to handle this scenario nicely with IdentityModel without writing custom implementation?
Also, as far as I know, it is quite common to store refreshToken in httpOnly cookie which will be added to each request sent to BE but then I don't see the point of having an accessToken when I already have refreshToken added with each request.
Isn't it better to store refreshToken inside BE for performance and security reasons?
Authentication is a part of every application so I believe there should be some in-built framework functionality for authorization code flow as well.
You are describing a Backend for Frontend approach, which is a good architecture. Make sure you separate the specialist API that deals with OAuth from general business APIs.
RECOMMENDED WAY
Curity have an approach that provides state-of-the-art security for SPAs, here are some links:
Token Handler Blog Post
Code Example
Code Example Doc
We may add a .Net token handler at some point, but it should not matter what tech is used, since the idea is for the specialist API to be something you plug in rather than code.
STORING REFRESH TOKENS
My personal preference for SPAs is to use AES256 encrypted HTTP only cookies. This fits nicely with goals of avoiding OAuth plumbing in applications and enables the token handler to be stateless and easier to deploy + manage.

Authentication for hybrid flow for ASP.NET MVC client

I'm learning identityserver4 and can't understand some stuff.
Shortly: I want to authorize end-users with email and password on ASP.NET MVC client side (it will send user credentials to the token server to get tokens), and I don't want third-party clients to retrieve data from my API resources.
As I understood from the documentation:
implicit flow is used for SPA (js clients) and uses id_token to authorize users. I can store id_token in my browser.
client credentials flow is used for trusted apps (like ASP.NET MVC client) to authorize clients and uses access_code. I can store access_code inside my app.
So looks like I need a hybrid flow.
In the documentation I read that I need to use AddOpenIdConnect() method and
Technically the tokens are stored inside the properties section of the cookie.
So my questions:
If the id_token can be stored in the browser, why is it not safe to store the access_token there too ?
As the docs state, the tokens are stored inside the properties section of the cookie. It's confusing, because some guides says, that it's not safe to store access_token there. So where I should store access token in my ASP.NET MVC client?
Am I right, that AddOpenIdConnect() configures my ASP.NET MVC app to retrieve access_token automatically from the token server? And if yes - in which moment should I authorize users with email/password and how to combine all tokens inside one JWT on my ASP.NET MVC client's backend when I will send requests to api resources ?
Today you should not use the Implicit Flow and it has been deprecated as of Oauth 2.1. What you should use is the authorization code flow with PKCE. PKCE is a security enhancement for the authorization code flow.
So as of OAuth 2.1 you only have two main flows:
Authorization code flow, for a MVC client to login a user to the client
Client credentials flow, for API->API communication where no human is involved.
To answer your questions:
If the id_token can be stored in browser, why it's not safe to store access_token there too ?*
The ID-Token is only used to create the initial user session and after that you can throw it away. It also only have a short life time of 5 minutes by default in IdentityServer.
As the docs state, the tokens are stored inside the properties section of the cookie. It's confusing, because some guides says, that it's not safe to store access_token there. So where I should store access token in my ASP.NET MVC client?
The tokens can be stored in your session cookie in ASP.NET Core and that's secure. It's protected / encrypted using the Data Protection API. However, the cookies can grow in size quite a lot if you do that.
Am I right, that AddOpenIdConnect() configures my mvc app to retrieve access_token automatically from the token server? And if yes - In which moment I should authorize users with email/password and how to combine all tokens inside one JWT on my ASP.NET MVC client's backend when I will send requests to api resources?
AddOpenIdConnect only handles the initial login and retrieving the first ID and access token. It does not handle refreshing of the access token using refresh tokens. For that you can add the IdentityModel library.
Today when you use the auth code flow, you redirect the user to IdentityServer and you let the user login there instead of passing the username/pwd from you browser to identityserver.

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.

JWT authentication in SignalR (.NET Core) without passing token in Query String

I am using JWT authentication tokens in an ASP .NET Core Web API application. The tokens are generated by the API itself, not by a third party.
I added SignalR sucessfully to the stack, but now I need to authenticate the users that are trying to execute server (Hub) methods.
Someone suggested to pass the token in the "qs" property in JavaScript. This will not work for me as our tokens are really large (they contain lots of claims).
I tried writing a custom middleware for reading the token from the payload and auto-authenticating the user. The problem is that, when using WebSockets, the middleware is not executed.
Any ideas will help.
Have a look at article that suggests to use query string Authenticate against a ASP.NET Core 1.0 (vNext) SignalR application using JWT. I know that your token is too long, but author explains how to use middleware to authenticate the request.
Here is the summary from the article:
SignalR does not have any special authentication mechanism built in, it is using the standard ASP.NET authentication.
JWT is typically sent in the Authorization header of a request
The SignalR JavaScript client library does not include the means to send headers in the requests, it does however allow you to pass a query string
If we pass the token in the query string we can write a middleware that adds a authorization header with the token as its value. This must be done before the Jwt middleware in the pipeline
Be aware of the “Bearer ” format
I have highlighted the key point that your custom middleware should be registered before Jwt middleware.
From this answer you can create a WebSocket connection and pass your token as basic auth parameter:
var ws = new WebSocket($"ws://{token}#example.com/service");

Can ServiceStack validate JWT OOTB

I'm looking over the auth docs
https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization
Basically what I would LOOOVE to do is simplify our service auth. Basically say "If this is being run in the context of an authenticated CMS user (in the API) use that person, if user is ANON, check for a JWT in the header, and run in the context of that user"
So I assume this would all be some sort of custom attribute? (I mean ideally I'd like an attribute or something). Right now we just have a method that lives at the top of every call to do this validation... would love to abstract it all out if possible somehow.
Anyone have any suggestions?
Steve
It's not included in the framework itself however there are a couple of external projects that enable token-based authentication with ServiceStack:
StatelessAuthentication
Using IdentityServer 4 with ServiceStack and Angular
Auth0 ServiceStack Integration
ServiceStack JWT Token validation for Auth0