We use Keycloak to secure our Spring Boot based Java Backend Services. Every endpoint is secured and a bearer token is expected inside the authorization header for each request. Keycloak then validates and verifies the token. So far so good.
During the registration process inside Keycloak (we use the authorization code flow), we have different use cases in which Keycloak have to approach our Java Backend for instance to validate an access code. I would love to use the same mechanism to secure those endpoints that are exclusively approached by Keycloak. I am wondering if it is a bad idea to use a keycloak user to send an http from a keycloak spi to our spring boot backend and then ask keycloak if the given JWT is valid. This feels like a chicken egg problem.
This feels like a common problem. What is the recommended authentication/authorization process for this kind of service to service communication? I was thinking about a technical keycloak user, that is managed inside keycloak for this purpose. I am aware of the Keycloak REST API that provides an endpoint to retrieve a token for credentials. Since I am implementing custom SPIs in keycloak, I am looking for a way to generate a token programmatically. I was able to find the right Keycloak library. Does someone know how to do that?
Here are my question:
How can I secure requests that I would like to send from keycloak to our backend?
How can I generate a Token inside Keycloak without using the Keycloak REST API (since I am implementing custom Keycloak SPIs)
Is there another way to secure my backend for technical users without using keycloak?
Best regards
Michel
Related
I started playing with Keycloak, but I have a question. While reading articles, I always found examples where a client (let's say Angular) is logging in on Keycloak, it gets a bearer and then it send the bearer to the SpringBoot application. The backend, so, validates that the bearer is valid and, if so, it allows you accessing the desired endpoint.
But it's not enough in my opinion. I don't need just to login, I would need the entire functionality - let's say I have a backend application and I need a user. I could have a basic todo-application, how do I know for which backend user I am actually accesing an endpoint?
Straight question: how can I bind my own backend user (stored in the DB from backend) to the one from Keycloak?
What is the best way to do it? The only thing that I found online and into the Keycloack documenation is that I could move the logic of logging in from client (Angular) to backend (SpringBoot). Is this the way to go?
Imagine like I'm creating my manual /login endpoint on backend on which I would then call the Keycloak server (Keycloak REST client?) and I would pass myself (as a backend) the bearer to the client.
Please help me with an explanation if I'm right or wrong, what's the best practice, maybe help me with an online example, because I just found out the too easy ones.
OpenID tokens are rich
Keycloak is an OpenID provider and emits JWTs. You already have the standard OpenID info about user identity in the token (matching requested scopes), plus some Keycloak specific stuff like roles plus whatever you add with "mappers".
All the data required for User Authentication (identity) and Authorization (access-control) should be embedded in access-tokens.
How to bind user data between Keycloak and your backend
In my opinion, the best option is to leave user management to Keycloak (do not duplicate what is already provided by Keycloak). An exception is if you already have a large user database, then you should read the doc or blog posts to bind Keycloak to this DB instead of using its own.
Spring clients and resource-servers configuration
I have detailed that for Spring Boot 3 in this other answer: Use Keycloak Spring Adapter with Spring Boot 3
In addition to explaining configuration with Spring Boot client and resource-server starters, it links to alternate Spring Boot starters which are probably easier to use and more portable (while building on top of spring-boot-starter-oauth2-resource-server).
I Also have a set of tutorials from most basic RBAC to advanced access-control involving the accessed resource itself as well as standard and private OpenID claims from the token (user details) there.
Tokens private claims
For performance reason, it is a waste to query a DB (or call a web-service) when evaluating access-control rules after decoding a JWT: this happens for each request.
It is much more efficient to put this data in the tokens as private claims: this happens only once for each access-token issuance.
Keycloak provides with quite a few "mappers" you can configure to enrich tokens and also allows you to write your own. Sample project with a custom Keycloak mapper here. This is a multi-module maven project composed of:
a custom "mapper" responsible for adding a private claim to the tokens
a web-service which exposes the data used to set the value of this claim
a resource-server reading this private claim to take access-control decisions
The simplest way to do it is to consider that the job of storing users will be delegated to your Keycloak server. But you can implement some roles and checks manually with in-memory or any database of your preference too.
I invite you to follow some documentation about OAuth 2 and Keycloak, to make requests to get a valid token for a time period and to make others request inside that time period to get datas. You can use CURL to make requests or web/software tools like Postman.
Be careful, a lot of Keycloak Adapters are deprecated ones since some months.
I would echo BendaThierry's comments. Look into OAuth2 and Keycloak. The Bearer token you receive from Keycloak will have user information in it (typically in the Claims). This way you can have user preferences or features in your backend without needing to manage the authorization and authentication that Keycloak does.
There are lots of great resource include Spring's website tutorials (like https://spring.io/guides/tutorials/spring-boot-oauth2/) and Baeldung (https://www.baeldung.com/).
I'm developing a backend server for my applications. Actually, I'm using Keycloak as Identity Provider exploiting the OpenID Connect protocol. The frontend redirects users to Keycloak Login Page, so a token is returned to it. The frontend makes an authentication request to the backend using the returned token. Backend asks the IDP to validate the token and retrieve user info and roles.
Then I want to generate a JWT from the backend in order to easily authenticate the frontend requests.
Is this architecture fine? Or am I missing something important? Can I implement this architecture using Spring Security? Where can I learn more about it?
Thanks for any advice and support.
I need to secure my spring REST APIs with access token obtain from Keycloak and validation done by Spring security adapter.
I have my mobile client which will be calling APIs from my server which needs to be validated with access token obtained from Keycloak
You can find an example with what you need wright here:
https://github.com/iuliazidaru/keycloak-spring-boot-rest-angular-demo
We have a Java 8 backend application using SprintBoot with an embedded Jetty server.
The UI for the application is a Single Page Application built using React.
Currently I have enabled authentication by integrating with Okta using the spring security SAML extension. When the assertion is posted by Okta to my app, I create a session and the JSESSIONID is sent in the cookie.
This was fine until now when we had a very simple UI serving few UI components.
However, now we have several REST endpoints in our backend and we would want them to be authenticated as well. REST endpoints themselves are developed using Jersey.
If I understand correctly, SAML is clearly not the choice for pure REST based endpoints as SAML is mainly a browser based protocol. These REST endpoints will be called by our UI as well we want them to be independently called via Postman or something for testing.
When a client would call these REST APIs, I am guessing the client should send an Authorization header which should be checked by one of the authentication filters in the backend. After validating the client and the user, the filter should inject the user information in the SecurityContext because Jersey injects SecurityContext in all of the REST endpoints. Then it becomes easier to fetch the user from this SecurityContext.
Upon reading, it seems Okta OpenID Connect can be one choice which issues a JWT. However I am not clear on how to use this. That is, when Okta issues a JWT should our UI or any client for that matter keep sending the JWT in the Authorization header to our APIs and then our APIs in turn should send the JWT to Okta to validate it?
Question is what is the best choice to serve both, a login for the UI and a session and authenticating REST endpoints? Not to mention the REST APIs will be stateless in nature.
When a client would call these REST APIs, I am guessing the client
should send an Authorization header which should be checked by one of
the authentication filters in the backend
In OpendID Connect (OIDC), that value in the Authorization header is id_token which can be in JWT format. This id_token is issued by the OIDC server as the last step for whichever OIDC grant type you choose and applicable to your case.
Upon reading, it seems Okta OpenID Connect can be one choice which
issues a JWT. However I am not clear on how to use this. That is, when
Okta issues a JWT should our UI or any client for that matter keep
sending the JWT in the Authorization header to our APIs and then our
APIs in turn should send the JWT to Okta to validate it?
Think that you have 3 components in this architecture. Relying Party (client), Identity Server / Authorization Server / OIDC Provider and Resource Server (your backend and it's data). When Authorization Server issues and id_token to Relying Party, your Resource Server also knows this token. So when you request for data in resource server, you will present your id_token to Resource Server and it knows if it is valid id_token or not
Question is what is the best choice to serve both, a login for the UI
and a session and authenticating REST endpoints?
OIDC Provider (or Identity Server if you need more complex operation), since OIDC is Authorization (OAuth 2.0 at core) and Authentication.
I'm trying to set up a SSO between a webapp and a REST API, to do this I'm using Apache Shiro + Jasig CAS but now I'm having a problem related to the authentication of the REST API.
I'm using CASRealm + CASFilter in the Webapp and trying to use the session created there to access the REST API, I've tried 2 approaches:
propagating the CAS service ticket from the webapp to the REST API through the request header (does not work, it says the service ticket is invalid because it belongs to another app, maybe the TGT would work)
store the username and password in the webapp and use them in http basic authentication (this might be a big security flaw, I'm trying to avoid it)
What other approach can I use to authenticate the user in the REST API?
I guess this is mainly an architecture issue.
Please ask questions if you didn't understand my question (or my english)
It looks like you want to use the first CAS service as a proxy for your REST API: you could use the CAS proxy mechanism: https://wiki.jasig.org/display/CAS/Proxy+CAS+Walkthrough. Though, the proxy support is not available in the Shiro CAS module, you should use the buji-pac4j extension, here is a good discussion on this topic: http://shiro-user.582556.n2.nabble.com/Shiro-cas-proxying-td7579694.html.
You can enable the OAuth2.0 configuration on CAS and then u can secure your REST services with the oauth2.0. For example u can have a rest service with oauth for user authentication. Here some usefull links.
OAuth configuration
Securing REST
OAuth and REST