Obtain Keycloak access token from trusted client without user password - oauth-2.0

We have a client that among other things creates and manages Keycloak accounts.
Would it be possible for that client to retrieve tokens on behalf of the users without having to create any user passwords at all? In fact, we'd like to create user accounts and not set a password to start with. None of these users will ever authenticate themselves.
None of the oauth2 flows seem to really match this, and we were wondering if there is a variation of the password grant type in which the password is not required for trusted client ID/Secret.
Some options we explored so far are offline tokens and user impersonation, but the former requires persisting secrets, and the latter relies upon proprietary Keycloak features using cookies rather than standard OIDC.

There's as of today an experimental oauth 2 token exchange grant type available in keycloak: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-token-exchange-19
As #qdivision pointed out: https://www.keycloak.org/docs/latest/securing_apps/index.html#direct-naked-impersonation
And Thomas Darimont: https://blog.softwaremill.com/who-am-i-keycloak-impersonation-api-bfe7acaf051a

Related

how can I generate a Keycloak user access token without password?

I have a legacy system that has an existing login mechanism - assume it is a custom method. We have another set of services that require an oauth2 access token and use keycloak for generating and verifying the tokens. After a user logs in we no longer have access to their password hence I can not use the password grant to get them an access token to our oauth based system. What are the recommended approaches to generate this access token. What I have looked into so far:
impersonation (token exchange)
custom keycloak userstore SPI that validates user with blank password
I guess using a client credential flow to generate a token that tries to match the users roles and attributes.
It seems to be a use case that is not well supported by oauth2?
It seems to be a use case that is not well supported by oauth2?
Your use-case seems to match those defined in the OAuth 2.0 Token Exchange specification
One common use case for an STS (as alluded to in the previous section)
is to allow a resource server A to make calls to a backend service C
on behalf of the requesting user B.
For this approach, you will need to configure in the appropriate Keycloak realm your legacy system as Identity Provider. So that you create a trust-relationship between the legacy system and Keycloak. Afterwards, you can exchange the token coming from the legacy system (resulting from the user authentication) for a token of the aforementioned realm. Depending upon your setup you might need protocol mappers that map the legacy system roles to the roles in the Keycloak realm. All of this is assuming that your legacy system is to a certain extend Oauth2 compliant.
Otherwise, another approach is for your legacy system, to call a confidential client on Keycloak and pass along some claims (e.g., the user roles). This is assuming that your legacy system can securely store the client secret. All of this, of course, depends upon the concrete characteristics of your setup.

Is there an easy way to grant yourself oauth access?

Every so often I hack up my own projects to solve my own problems. Sometimes I want to use data from a service. This access is often provided by oauth.
oAuth solves a more general problem than I want to solve. It lets a programmer request that a user provides data via a website. In my case I am the user and the programmer, and I don't really want to implement the website.
Is there an easy way for me to grant myself access to my own data without writing a website?
Resources
This diagram from this blog post [http://www.bubblecode.net/en/2016/01/22/understanding-oauth2/] gives a good overview of oauth.
Only if I understand your flow correctly, I think you should use the password grant type (see here).
Because you use google authentication server (google account) and resource server (e.g. gmail). You use the client app (maybe you write it yourself) so you sign in with username and password, so Password is your preferred grant type.
In this flow:
The resource owner password credentials (i.e., username and password) can be used directly as an authorization grant to obtain an access token.
The user’s password is accessible to the application!
Should only be used when there is a high degree of trust between the resource owner and the client (e.g., the client is part of the device operating system or a highly privileged application)
It is used for only highly-trusted clients, such as a mobile application written by the resource-server.

Support for "Personal Access Tokens" or "API keys"

Does keycloak provide a way to support Personal Access Tokens, similar to Github, when I am using Keycloak to handle authentication and using the tokens it issues to secure my API? When my application is using a web browser then logging in via OIDC flow works fine, but how can I handle login from a CLI or a headless API script for my application?
I could support a password flow where I get back a JWT token after providing a username and password, but I assume once the user has configured 2FA or if they are using SAML on the backend then all bets are off as a username and password would not get you access. This is exactly why Github offers personal access tokens. Is there some way to implement something like this using Keycloak or do we have to build it in our own application and then accept those tokens in addition to the JWT.
What I would envision is Keycloak being able to generate and store personal access tokens in its user store that a user could generate and revoke via the UI that Keycloak provides to the user. My CLI could then use this token to obtain a JWT and then proceed with calling my API the same way a web browser or other client would.
Some support for utilizing OTP during CLI scripting was added in recent Keycloak releases. I've not played with it so far, so i can't present you any recipes. Try to start at Authentication -> HTTP challenge Flow settings.
Regarding to users token you can implement required functionality as an SPI extension to Keycloak (see Server Development section in docs). From my point of view there should be two components:
User token issuer
Custom authenticator that will be used in authentication flow for your client
Here is rough example:
Let User tokens be like UUID strings, so all user tokens could be stored in user attributes (Attributes tab in user's settings Admin UI).
Some of your APIs could introduce dedicated endpoint that will accept valid Access Token< generate new UUID User Token, store it in keycloak user attributes via Admin API and return this token to user.
Then we create custom Authenticator SPI implementation that will extract user token from direct grant auth request and validate it.
And last step is to properly configure direct grant authentication flow for corresponding OIDC client. This flow should work like default if no user token presented in auth request and should validate only user token and ignore other credentials if user token presents.
Keycloak "server development" docs and keycloak sources are very helpful with such king of tasks.

OAuth2 Login (Not Authorization)

I have implemented an OAuth2 register workflow (in Java) according to rfc6749
I'm using GitLab as OAuth2 Provider.
After the user granted access to my application for his account, I get an OAuth Token (along with refresh token and other stuff), I am able to make API requests on behalf of the user, so this is working fine.
This way I can get the users e-mail adress which I use to create an internal user.
My questions are:
Is it practice to issue a token that is generated by my application for the user (along with the OAuthToken) or should I just use the token that has been issued by the OAauth Provider? (My App also has local auth with bearer tokens). This token will be used for further API - CLIENT communication (stored in Angular2 local storage as bearer)
How to do login only? When a OAuth User accesses my web service, how do I know that this user is a OAuth User and which OAuth Token belongs to him? How can the user login without providing e-mail or password? (The user has no password) I guess I have to redirect him to the OAuth Provider again, but I don't want my user to grant access everytime he logs in.
Answer 1:
Though you can use the token provided by OAuth provider, you SHOULD NOT use it considering the risk that may arise exposing it to the public.
Instead you should securely save the token provided by OAuth provider into the database and use another token for authentication of further api calls. (you could use JWT)
Answer 2:
There are two types of systems
Which always uses OAuth provider for identifying user. (Ex. Tinder)
Which provides both OAuth Login and Traditional login/signup. (Ex. Quora, Instagram)
If you want your application to follow 2nd approach, you should ask the user to create password for the first time when the user logs in using OAuth provider.
This will allow the user to log into your application by both methods, traditional as well as OAuth
To identify users of your application, you should either use HTTP session or issue your own tokens. Do not use tokens generated by the OAuth2 provider - they are meant to be used just by your backend (in role of an OAuth2 client).
To use an external authentication in your application, you probably want to use OpenID Connect, not a bare OAuth2. OpenID Connect extends OAuth2 and it's meant for authentication instead of the rights delegation. Then you use an implicit flow (instead of authentication code grant) with scope=openid, your frontend app (HTML+JavaScript) gets an ID token signed by the OAuth2 provider. After successful signature verification, your backend can trust that the client is the one described in the ID token (in its "sub" field). Then you can either keep using the ID token or generate your own token.

Why does OAuth 2 have Resource Owner Password Credentials Grant?

Why would anyone use OAuth 2 with this kind of grant? I mean, if the client already has the name and password of the Resource Owner, why not just authenticate as the Resource Owner using whatever authentication vehicle is used by the Resource Server?
I do not understand the rationale here. Can someone explain it?
As the spec mentions, the Resource Owner Password Credentials grant is for migration purposes and applicable only in scenario's where (typically) the Client and the Authorization Server are controlled by the same party, https://www.rfc-editor.org/rfc/rfc6749#section-1.3.3:
The resource owner password credentials (i.e., username and password)
can be used directly as an authorization grant to obtain an access
token. The credentials should only be used when there is a high
degree of trust between the resource owner and the client (e.g., the
client is part of the device operating system or a highly privileged
application), and when other authorization grant types are not
available (such as an authorization code).
It allows for utilizing a standard token and protocol on the leg between Client and Resource server (e.g. OAuth 2.0 Bearer Token), whilst using a "to-be-deprecated" way of getting a token between Client and Authorization Server. https://www.rfc-editor.org/rfc/rfc6749#section-10.7:
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 client could abuse the password, or the password
could unintentionally be disclosed to an attacker (e.g., via log
files or other records kept by the client).
Additionally, because the resource owner does not have control over
the authorization process (the resource owner's involvement ends when
it hands over its credentials to the client), the client can obtain
access tokens with a broader scope than desired by the resource
owner. The authorization server should consider the scope and
lifetime of access tokens issued via this grant type.
The authorization server and client SHOULD minimize use of this
grant type and utilize other grant types whenever possible.
I will provide another point of view.
OAuth 2.0 is a great protocol for common web applications. Some applications, however, use much stronger authentication / authorization mechanism. For these cases, it makes sense to allow token establishment using a strong method. An example of such application can be a banking API - it can use classic OAuth 2.0 flow on web (using bank's website) and strong data signatures using protocols like PowerAuth 2.0 (I am an author of this solution) for native mobile or desktop apps.

Resources