Why should you revoke access token? - authentication

I don't understand why should you revoke Access Token when your log out. I mean what should you gain from a security perspective, while there is a Refresh token which is used to get a new access token as soos as you browse to the application?
I don't see the profit from a security perspective when there is a Refresh token which can be used by whoever uses the computer and browse to the application.

Whilst the concept of OAuth 2.0 is based on short lived access tokens that are not revoked, there are exceptions to that rule and there's a protocol specification catering for token revocation, RFC 7009 OAuth 2.0 Token Revocation https://datatracker.ietf.org/doc/html/rfc7009.
When revoking the access token, one should also make sure to revoke the refresh token at the same time (the spec dictates that revoking a refresh token will also revoke associated access tokens). This becomes more important when tokens are long lived and there's a suspicion of some breach, unauthorised 3rd-party token access or other token leakage.

I don't understand why should you revoke Access Token when your log out.
Access tokens cant be revoked. They are used for Authorization, and grant the bearer of the access token access to the data for as long as the token has not expired.
Logging out is Authentication these are two very different concepts.
I mean what should you gain from a security perspective, while there is a Refresh token which is used to get a new access token as soon as you browse to the application?
You are again mixing Authorization (OAuth 2.0 access token refresh token) with authentication(open id connect, logging in a user).
Using OAuth 2.0 an application is granted authorization to access a users data they are granted an access token and a refresh token. The application can access the users data when ever it needs to without the user being present.
I don't see the profit from a security perspective when there is a Refresh token which can be used by whoever uses the computer and browse to the application.
This is the exact point of OAuth 2.0 it is there to grant an application access to a users data when the user is not present. It is not authentication.

When a user logs out from an OAuth2-based session, they might want to make sure that every application on the same machine can no longer do things on a users' behalf.
For example, perhaps your organization has a single-sign on system that spans several applications, some even third party. When the user logs out, you can't rely on applications to 'log themselves out'. Perhaps all they got is a a session cookie, sitting in a browsers' cookie jar waiting for the next request.
If I log out on a machine, I want the guarantee that nothing can still act on my behalf, not even for a minute.

Related

Understanding Access token expiration when using client_credentials grant type

we are using KeyCloak (version 16.0.0) as our IAM.
in our code, we are using the Admin Rest Api to handle user login.
in the first login, we are sending the user credentials and using the password grant type to get a valid access token.
but after that, whenever the access token is about to be expired (in our case 5 minutes) we are using the client_credentials grant type to generate a new access token.
I'm not an expert but it seems to me, that unlike working with refresh tokens, this way to generate a new access token can last forever and it's not bound by any value from KC configuration.
Am I right?
I tried to play around with SSO Session Idle/Max and Client Session Idle/Max values (both on realm and client level) but it seems to have no impact.
any insight will be helpful
I'm not an expert but it seems to me, that unlike working with refresh
tokens, this way to generate a new access token can last forever and
it's not bound by any value from KC configuration. Am I right?
What happens if the account of user A gets compromised? According, to your current setup you would keep that user logged in "forever", unless you would "tell" Keycloak to not omitted tokens on behalf of the client that is being used with the client_credentials grant type. But then other unrelated users would suffer. There is additional issues with this design, for example the assignment of roles to users, how would you handle user specify roles in the access token omitted by the client that is being used with the client_credentials grant type?
This seams to me to be a poor man's version of the refresh token mechanism.
in the first login, we are sending the user credentials and using the
password grant type to get a valid access token.
If possible you should use more modern workflows for user login, like for example Authorization Code Flow (i.e., standard flow in Keycloak). Otherwise, just use the direct access grants with a short access token lifespan and renew it using the refresh token mechanism.

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.

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.

What is the purpose of Resource Owner Password Credential Grant Type in OAuth 2.0?

Based on the answer to my previous question
Ok, OAuth 2.0 is an authorization protocol but when you use ROPC (Resource Owner Password Credential) Grant Type, the way I understand it, you mean to authenticate and authorize isn't it?
Is OpenID still applicable in ROPC? still a little bit confuse with OAuth 2.0 ROPC and OpenID
The Resource Owner Password Credentials grant type does authenticate users but is a non-typical OAuth 2.0 grant type that is only meant for migration purposes, as the spec says:
The resource owner password credentials grant type is often used for
legacy or migration reasons. It reduces the overall risk of storing
usernames and passwords by the client but does not eliminate the need
to expose highly privileged credentials to the client.
This grant type carries a higher risk than other grant types
because it maintains the password anti-pattern this protocol seeks
to avoid.
The Resource Owner Password Credentials grant is not prohibited with OpenID Connect (even though the OpenID Connect spec does not clearly define it beyond OAuth 2.0) but defeats the primary purpose of a federated SSO protocol that OpenID Connect is supposed to be. That is because it locks RPs in to a single authentication method whereby the user credentials are disclosed to the RP. You mileage wrt. to support across Providers may vary.
See also: Does OpenID Connect support the Resource Owner Password Credentials grant?
In my view, the power of resource owner password credentials(ROPC) is utilized properly when we use the refresh token.
Consider a mobile app where user needs to log in. Once logged in and request a token using your clientId, secret, userid and password, normally you get an access token and a refresh token. Access token is normally valid for less time(say 1 hour) and refresh token is valid for a longer time(say 24 hours). ClientId and Secret is stored in the App. UserId and Password is owned by user and never stored anywhere.
When the user tries to access the app after 1 hour, his access token is expired which means in normal scenario, he needs to log in again.
But we can avoid this tedious task of entering his userId and password again by getting a new access token(and new refresh token) by exchanging the refresh token along with the clientId and Secret(no userId and password needed). The new access token will have all the same features of the previous access token. This means as long as user is active atleast 24 hours ago, he doesn't have to log in again. After 24 hours of idle time, both refresh token and access token expires and the log in is required to get a new access token.

OAuth2 User Credentials Grant Security

I have a couple security questions on the OAuth 2.0 User Credential Grant type and possible security attacks. So from what I understand so far, when I exchange my users username password client ID and client secret for an access token over HTTPS that is completely safe. Now say for an example if I have a first party mobile application for a service that is doing the user authentication and I keep the access token on the device.
If the access token is compromised some how the compromised access token can be used to make subsequent requests to say for example the API service. Is there any way to prevent this other than just not getting the access token out there?
If your doing all API requests over HTTPS I shouldn't have to be worried what so ever about the access token being compromised over the wire or have to worry about any replay attacks?
So basically my concerns about possible security flaws with this specific type of grant. I'm pretty sure if the access token doesn't get compromised and all traffic is over SSL it should be fine.
I'd love to hear someone's expert opinion not the biggest OAuth person.
If the access token is compromised, the app that now has it CAN misuse it. Since access tokens are short lived, and are mapped to certain permissions only - the damage would be limited to say 10 minutes access to a single resource! (tokens are generated for apps that are registered for a scope, the scopes are mapped to permissions.)
If you are working on a first party app, why do you want to store the token on device? You can think of using the authorization code flow and not the implicit grant flow. That way the access token is always with the server and not on the device locally.