Asp.net Core with Identity server 4 - asp.net-core

I have 2 website that are using identity server Authentication (which is a third website)
if i log out from the identity server website (i am using quick start) how can i force the 2 other website to validate if the user is still log in, and this on every round trip to the server (post back).

For browser based apps you can call the session endpoint:
All applications that the user has logged into via the browser during
the user’s session can participate in the sign-out.
This will however not invalidate JWT tokens as these are self-contained and remain valid until expiration.
The only way to logout a JWT 'almost realtime', is to set the expiration to a minimum and use refresh tokens to renew the access token.
These refresh tokens can be revoked using the revocation endpoint:
This endpoint allows revoking access tokens (reference tokens only)
and refresh token.
This way you don't need a roundtrip on each call. An alternative that does is to use reference tokens:
When using reference tokens - IdentityServer will store the contents
of the token in a data store and will only issue a unique identifier
for this token back to the client. The API receiving this reference
must then open a back-channel communication to IdentityServer to
validate the token.
Using the revocation endpoint you can revoke the reference tokens at any time you like.

Related

How to invalidate or revoke jwt access token using Identity server 4 JWT authentication and Resource Owner Password grant?

We have used JWT authentication scheme and resource owner password grant type with identity server. Backend is .Net core based micro services which is providing access token to angular based front end website.
As jwt token is not revocable and business requirement is to have longer access token lifetime, it seems only option is to have track of blacklisted tokens in database or cache.
Is there any way to modify the access token on backend and make it expire immediately when user triggers log out from frontend?
JWT cannot be revoked, it is by design as it is self-contained. Revocable alternative is Reference token which is not self-contained and thus server needs to actively communicate with identity server.
The compromise and common approach is to set access token lifetime to lower value and increase refresh token lifetime. Refresh tokens are revocable - it is supported by identity server 4 as well. So it is all about trade-off between the frequency of communication with your Identity server and long access token lifetime.
The JWT tokens are stored in the browser, so you can delete the cookie of it.
But this option gives no security on the server side.
If you are worried about deleted/suspended accounts then yes, you have either to create a blacklist but you have to compare them for each request.
The other option is to reduce the expire times and rotate them. there is a post with more details here Invalidating JSON Web Tokens

How do I implement session authentication across microservices?

I'm working on a project for which I have planned the following architecture:
auth.example.com: Provides login, registration, and password-reset functionalities.
accounts.example.com: Allows users to update their account data.
example.com: Provides other services.
I have figured out the following solution for maintaining authentication across all domains:
Authenticate user on auth.example.com and set a cookie containing JWT token (signed token with shared key) which contains the user data and its domain is set to .example.com.
Once the user is authenticated, redirect them to example.com/dashboard and verify the JWT token present in the cookie. If the token is valid, present the service to the user else redirect to auth.example.com.
Now, I have the following doubts:
Suppose if a user updates his name on accounts.example.com, how do I make all other services use the updated user data?
If I want to ban a user or delete their account or terminate all active sessions, how would I let other services that the user shall not be authenticated?
Is there any better approach to solve this problem?
JWT tokens are generally stateful means they have everything to be authenticated, once issued they can be used and there is no way we can revoke them. However there are few approaches that we can use.
Normally we keep the life time (expiry) of token short (e.g. 15 mins) and refresh the access after X minutes using Refresh Token (Know the difference between Refresh and Access Token).
Say the token is about to get expired then we will re-issue the access token (refresh token will do that without user sign in again). Refresh tokens are long lived token and have to be handled carefully. If we have to revoke the access then we need to revoke Refresh token and after X mins user is not able to get access token since Refresh token is revoked already.
During the time when you revoked the refresh token , any access token issued is still valid until reaches its expiry. If you want to invalidate the token before that then you may have to blacklist the token and maintain the list of such tokens that will stop the user from login using that particular token.
I have found very nice explanation here Check Revoke Token
Club JWT token, protocols like oauth and openid and store the session in redis/memcache.
This redis/memcache will be single point of contact for all your microservices.
Say microservice m1, m2, ... are independent and using restapi gets connected to microservice called mR which checks the session in redis/memcache.

How to overcome from a security breach in Jwt tocken validation

I have used jwt token securing angular application and in the backend, we have used asp.net core API. After login successfully we have saved the token in local storage in web browser memory and we log out from the application simply remove the token from browser memory.
We can stop the user to access the application through the application but if some have the token he can access the endpoint using postman and other api test tool. How can we overcome this problem.Is there any way to remove the token or expire the token manually.
Revoke the jwt token is not easy , there is no standard way to revoke access tokens unless the Authorization Server implements custom logic which forces you to store generated access token in database and do database checks with each request.
A simply way is using short lived access tokens and refresh token , use refresh token to renew the access token , if you want to revoke the user , revoke the refresh token on server side , clear refresh token and access token on client side .
Another way is reference tokens. The basic idea is Authorization Server will store the contents of the token in a data store and will only issue a unique identifier for this token back to the client. The API receiving this reference must then open a back-channel communication to Authorization Server to validate the token , so that the server side could control whether reference token(unique identifier) is still available . Identity server 4 also provides the reference token feature :
http://docs.identityserver.io/en/latest/topics/reference_tokens.html

OpenId Connect renew access_token in SPA

Trying to implement OpenId Connect in Web Application consisting of following components
Identity Provider
Resource server
Single Page Application acting as Client.
Identity Provider and Resource Server are the same application.
SPA use Password Flow to get access_token and stores into the cookie. Storing access_token into cookie has it's security threads, but's it's a different story.
Problem
access_token issued by IdP is expired after 30 min and SPA needs to renew token without asking users for credentials again.
Solution
IdP returns refresh_token along with access_token. Whenever SPA gets 401 from Resource Server, it sends refresh_token to IdP and get's new access_token back.
Problem
Sending refresh_token to SPA is bad practice.
A Single Page Application (normally implementing Implicit Grant) should not under any circumstances get a Refresh Token. The reason for that is the sensitivity of this piece of information. You can think of it as user credentials since a Refresh Token allows a user to remain authenticated essentially forever. Therefore you cannot have this information in a browser, it must be stored securely.
Suggested solution
When the Access Token has expired, silent authentication can be used to retrieve a new one without user interaction, assuming the user's SSO session has not expired.
I think Silent Authentication is not applicable to Password Flow when IdP and Resource Server is same application. access_token issued by IdP is only piece of information which can be used to authorize against Resource Server/IdP after its expiration, how a client can convince IdP to issue new access_token? (without sending refresh_token)
Found angular-oauth2-oidc library which uses refresh_token to renew access_token.
What is best practice/solution in this case to renew access_token?
technical details
Identity Provider - ASP.NET Core + Openiddict library.
SPA - AngularJs application.
Single page applications must not receive refresh tokens. That has been established rules in OAuth 2.0 and OpenID Connect.
One good option I see here is to use Implicit Flow. This will establish a front channel session from your browser to Identity Provider. With password grant type you do a back-channel call (POST), so you don't get such session.
Usually this is a cookie which points to information about previous logged in status (these are identity provider specifics). With completion of the flow, SPA will receive the access token. As you figured out, it will expire. But once that happens, SPA can trigger another implicit flow, but this time with prompt query parameter.
prompt
Space delimited, case sensitive list of ASCII string values that
specifies whether the Authorization Server prompts the End-User for
reauthentication and consent. The defined values are: none , login, consent and select_account
If you identity provider maintain a long lived session (ex:- few hours or days) or if it maintain a remember me cookie, SPA could use prompt=none making it to skip login step from identity provider. Basically, you are getting browser based SSO behaviour with this.
Using the Resource Owner Password Credentials flow defeats the refresh token storage argument: instead of not being able to store the refresh token in a secure place, the SPA would now have to store the Resource Owner credentials in a secure place (assuming you want to avoid requesting username/password from the user frequently). The Implicit grant was designed for usage with an SPA, so it is better to stick with that.
Further to previous answers, the latest OAuth working group guidance for SPAs no longer recommends use of the implicit flow.
If you have simple, shared domain app (IdP, RS and client on a single domain) then you should consider not using OAuth at all. From the doc:
OAuth and OpenID Connect provide very little benefit in this
deployment scenario, so it is recommended to reconsider whether you
need OAuth or OpenID Connect at all in this case. Session
authentication has the benefit of having fewer moving parts and fewer
attack vectors. OAuth and OpenID Connect were created primarily for
third-party or federated access to APIs, so may not be the best
solution in a same-domain scenario.
If you are using OIDC/OAuth in a SPA, they recommend the auth code flow with PKCE.

Custom (Non-OAuth) Refresh Token Implementation

I'm working on an application that uses a token-based authentication system, where the user provides their username / password and receives a token in return (the token gets saved to the database as well). Then subsequent requests will include this token as a custom header and we can use this to identify the user. This all works fine.
Right now if the user doesn't login for 3 days, we expire the token. I was reading a little about refresh tokens in OAuth and I was wondering if I could somehow implement something similar. i.e. when providing the auth token, I also provide a refresh token which can be used later to request a new auth token. In terms of security though, it seems quite similar to just never expiring the user's auth token in the first place. Should I be sending additional information with the refresh token to validate the user?
In OAuth2, the resource server and authorization server are often not the same.
The refresh token is sent back to the client when the access token is issued and when the token is refreshed. The client needs to authenticate itself (using client id and client secret) to use the refresh token. The resource server never sees the refresh token.
Also, access tokens are not stored at the server side as they have a limited lifetime. Refresh tokens are stored and can therefore be revoked.