Does keycloak provide a way to distinguish between logins by the same user on different devices - keycloak

Does keycloak provide a way to distinguish between logins by the same user on different devices (a user can be logged in on mobile device/s and also on desktop browser/s).
Does keycloak provide a way to identify when a user entered their credentials (whether through keycloak login or using an identity provider flow)?
Our use case is:
a user can request to reset their pin (from our app).
the user is logged out (a /logout using the 'keycloak-connect'
middleware).
following logout, the user is redirected to login and enters
credentials (keycloak or identity provider).
on login, the user is presented with the 'enter a new pin' page (our app).
To achieve this we want to be able to determine server side when to send the 'enter a new pin' page.
Our situation is that we don't easily know (for various reasons, including active keycloak session or other token expire/active states) when an actual 'credentials entered' login occurs.
Could the session_state from the keycloak access token be used to identify which keycloak session a client request corresponds to?
Could something like the following work:
the server receives the keycloak access token (containing the
session_state) from the keycloak login,
the server passes the session_state to the client (browser/mobile
app),
the client passes this session_state back to the server along with
the user requesting the action,
the server requests the session information from keycloak (something along the lines of making the following request to the admin REST API localhost:8080/auth/admin/realms/demo/users/{{user_id}}/sessions - then checking against session_state somehow?)
if the 'start' value of the session returned by the REST API is
recent, then maybe we have 'actual' login information?
We're still using Keycloak 6.0.1
Any help is greatly appreciated.

I wanted to update with how I'm proceeding, which I believe gives me all I want in terms of solving/answering my original question.
The keycloak access token includes: "sub", "auth_time" and "session_state".
{
"sub": "ae384e77-7588-444b-9c4f-3dc920750e1f",
"auth_time": 1590555910,
"session_state": "2d735372-1a5a-43de-8a6c-1a45deebf20b",
}
I can use the sub to query the Keycloak Admin REST API with https://my-domain.com/auth/admin/realms/demo/users/{{sub}}/sessions which gives a list like:
[
{
"id": "2d735372-1a5a-43de-8a6c-1a45deebf20b",
"username": "20000",
"userId": "ae384e77-7588-444b-9c4f-3dc920750e1f",
"ipAddress": "52.62.57.52",
"start": 1590555910000,
"lastAccess": 1590555910000,
"clients": {
"4eb676c2-94c3-4bac-a423-94a7bf57ece0": "demo"
}
}
]
I can then choose from the returned sessions list matching the id to the session_state from the access token (n.b., that start from the sessions list matches auth_time from the access token.
This gives me what I need. I can pass the original session_state to the client and request from keycloak matching that session_state :)
I'll update if I encounter issues.

Related

What does it mean to "redirect with token" for single sign on?

(Background: I am trying to use my website hosted on wix as a simple identity provider so my members can access a separate sveltekit app I am creating--without logging in again--on a separate server because I do not think I can create the app on the wix platform. Basically I just need the user id, but I would like to also ensure they are in fact authenticated on my Wix hosted site before granting access).
In multiple pages explaining single sign on, it is explained that when my browser requests a protected resource from a web server, the server can (if it is configured to do so) verify my identity via a separate identity provider. This is done via a redirect to the identify provider. If I am not authenticated by the identify provider, I am asked to authenticate (by entering username and password, or whatever).
Once I am authenticated (by logging in or by verifying the presence of a valid session id on the identify provider's server from a prior login), the identify provider then "redirects with token" or a "token can be passed to the original domain by a redirect" according to these web sites I have encountered.
But what does it mean to "redirect with token"? This conflicts with other reading I have done which points out that redirects cannot have authentication or other headers or data associated with them.
How does it come to pass that (1) the web server I made my original request from gets my token from the identify provider while at the same time (2) returning my requested resource to my browser instead of back to the identity provider's server?
"Redirect with token" is a common method used in single sign-on (SSO) systems to authenticate users. In this method, when a user tries to access a protected resource on a server, the server redirects the user's browser to the SSO login page, along with a token that identifies the resource being accessed and the server that is requesting authentication.
The user then enters their login credentials on the SSO login page. If the credentials are correct, the SSO system authenticates the user and sends them back to the original server, along with a token that indicates that the user has been authenticated. The server checks the token to confirm that the user has been authenticated, and if the token is valid, the user is granted access to the protected resource.
Redirecting with a token is a secure and efficient way to authenticate users across multiple servers, as it allows the servers to rely on the SSO system to authenticate users and eliminates the need for each server to store and manage its own set of login credentials.

How can we obtain an access token for the user by only knowing the username in keycloak?

In my application, users can perform some tasks without login via the keycloak. After performing the task, I want to get an access token from keycloak by giving the username of the user to automatically log the user into application. Assume the user has a registered user account in keycloak too. is there a way to obtain an access token with username only?
In my application, users can perform some tasks without login via the
keycloak.
Unless those users are authenticated via some external IDP and you have established a trust-relationship between your external IDP and Keycloak (have a look at this SO thread for potential solution for a similar question to yours) in short I would say no.
From auth0:
Access tokens are used in token-based authentication to allow an
application to access an API. The application receives an access token
after a user successfully authenticates and authorizes access, then
passes the access token as a credential when it calls the target API.
The point is exactly that, exchanging some kind of authentication information (.e.g., username and password, or client secret) for a token that proves to your application that the user has authenticated successfully. Otherwise, someone could just enter your system as long as it had access to a username.
It sounds to me that you want to use the access token has means to pass information between Keycloak and your app, for that you have for sure better options.

Extract roles from REST API in Keycloak

At my company, we need to extract the roles of the logged in user from the REST API that Keycloak provides. We have looked through the Keycloak documentation but can't find the answers we are looking for. Let me explain the flow we want to implement: A user logs in to a client defined in Keycloak and receives a JWT which is stored in the applications web client. The user is not an admin in Keycloak. When the web client makes a request to the backend server, the backend server queries Keycloak for the user's roles. And, this is the point where we have trouble. We can't figure out the correct URL for the REST API or which token to add to the authentication header.
To summarize: we need help with the URL which is needed to query for user roles and what token to send to authorize against the API. I'm aware that the roles can be retrieved from the JWT, but we are afraid that the payload will become to big over time. A user may have multiple roles in different departments.
The roles should be in the JWT payload, this should be configured in the keycloak service. The flow should be something like this:
User is authenticated by the front end and the JWT token returned by keycloak is stored
The front end hits the back end including the token in the request header
The back end takes the token, validates it using the public key (the public key is provided by keycloak), if the token is valid, the roles are taken from the token payload and the authorization process is executed

KEYCLOAK: Obtaining Access token by 'user name' only (without password)

I have a question regarding Keycloak and obtaining an Access Token.
Our setup is as follows:
· users are created and maintained in Keycloak
· resources, policies and permissions are also maintained in Keycloak
Our use case is:
As a third party application, I want to obtain authorization information (e.g. resource- and scope-based permissions) for a specific user by only providing the username to Keycloak, so I can allow or prohibit further actions.
To be more specific:
In our application the need to validate each request to other services based on the access token.But we have only the user name with us.
The question is now:
> How can we obtain an access token for the user by only knowing the username ?
>
Is there a solution to obtain an access token for such a user?
You don't specify in your question if the current user is logged in. Are you validating user specific actions, or you want to retrieve user roles for the application instead?
The user is logged in and he is performing some action
I suppose you're using some keycloak adapter. Then just retrieve the session object and you should have the extra info somewhere in there.
If not, you can just parse the request yourself. When using OpenId Connect, the access token is always sent for each of the requests, in the Authorization header. The token is base64 encoded, you can decode the token yourself.
The application is performing some action for some registered user, without him logged in
User access tokens are meant to provide permissions for users. As you say in your question: As a third party application, I want... so here you are not acting as a logged user, but as an application, so you need to go with client credentials instead. Just give the client permissions to list all the users and their roles (probably it's enough with the view-users role, see the link below) and log in with client credentials grant. Then you can handle fine grained permissions in your application business logic.
See also:
Keycloak Client Credentials Flow Clarification
Keycloak spring security client credential grant
How to get Keycloak users via REST without admin account
For those who really needs to impersonate a user from a client, there is a new RFC for this : token-echange.
Keycloak loosely implement it at the time of this answer
See particularly https://www.keycloak.org/docs/latest/securing_apps/#direct-naked-impersonation

Login with oauth validate token

I want to create an app that will authenticate with my server using oauth.
My question is how will this work?
My client side will communicate using HTTPS with Facebook and get an Access Token. Then it should send it to my server side to authenticate? My server should save the token in the db? How it can validate the token?
how will this work. ?
When the client needs authorization to access some information about the user, the browser (user agent) redirects the resource owner to the OAuth authorization server. There, the user is faced with an authentication dialog (this dialog is not shown if the user is already authenticated), after which he or she is presented an authorization dialog explaining the permissions that the client is requesting, the information that it needs to access or the actions that it needs to do on his or her behalf.
Access Token should send it to my server side to authenticate? or server should save the token in the db?
From what you describe I'd suggest to use a server-side login flow.
-so that the token is already on your server, and doesn't need to be passed from the client. If you're using non-encrypted connections, this could be a security risk.
(after a user successfully signs in, send the user's ID token to your server using HTTPS. Then, on the server, verify the integrity of the ID token and retrieve the user's ID from the sub claim of the ID token. You can use user IDs transmitted in this way to safely identity the currently signed-in user on the backend.)
-See
https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.2#login
How to validate token ?
you can follow this link , you will get your step by step solution for an app.
Facebook access token server-side validation for iPhone app