Can someone suggest how to configure a Spring Boot application to authenticate via KeyCloak, and then use Redis as the session store? I've spent a day googling and banging my head on this, and I just don't feel like I'm getting anywhere.
I know how to configure each one independently - i.e. I can make a boot app that auths via KeyCloak, and I can also make a boot app that keeps session in Redis, but I'm not getting them to work together. Is this possible? It seems like it should be. Or is this just not how its supposed to work?
I think my working POC would behave something like this:
start my app
access some resource that forces a login via KeyCloak - access to resource is granted
restart my app
access that same resource but now no login is needed (since session is persisted in Redis)
Thanks for any suggestions.
OK - turns out I'm just not paying attention. I was not using the access/bearer token correctly. There is no need to keep the Spring session around when the bearer token is properly provided in requests.
Related
We are experiencing an issue in production which seems identical to when we restart our dev boxes and try to authenticate using the token that was generated with the previous instance of our SSO Spring Boot App and powered by Spring Authorization Server.
The error is: Wrong nonce
In production, it looks to occur when our SSO app scales up due to a user spike. We could see this happening at a point with high user activity and we would continually get logged out.
Now, of course we do not want all our active users to suddenly have invalid tokens just because a new instances of SSO is added.
This questions also relates to the currently unanswered, but much older question here: Can Spring Security OAuth2 Authorization Server scale horizontally?
Please advise. It is the number 1 most frustrating issue we are having in production right now and we are not quite sure how to proceed. We are not using any In-Memory implementations of classes.
2022-07-12 - Update: The question was asked "How are we storing the session?"
We are storing OAuth2 authorizations, authorization consents and registered clients in MongoDb.
We implemented OAuth2AuthorizationService, OAuth2AuthorizationConsentService and RegisteredClientRepository
Spring Authorization Server is built on Spring Security (see docs Overview) and does require knowledge of Spring Security (see Getting Help).
In particular, you'll want to review the Authentication chapter of Spring Security documentation. Session management falls under this topic, and if you're using (for example) form login or something similar, you'll almost certainly want to add Spring Session to your server to manage distributed sessions.
You are also likely running into an issue on the client side if you are not managing sessions in a database, so once again looking into Spring Session for the client will help alleviate issues such as the nonce error you mentioned. You will also want to look into the OAuth2 Client documentation and review the core interfaces as you will need to be storing your client authorizations in a database as well.
Steve writes a great response above already and I marked it as the answer.
To answer the title of this question:
Yes, Spring Authorization Server can easily be scaled to include multiple instances without suffering from the original misconfiguration issue we were experiencing.
Spring Authorization Server does not have any magic tools to persist a session across instances. It is reliant on session management being configured correctly. We use Spring Session backed by MongoDb for our purpose.
Session validity best practices is probably something that should be addressed and whether some of them should have the same timeout values.
Servlet session timeout
Spring Session timeout (this overrides 1 when present)
Remember me timeout
Token timeout
We are still figuring out / playing with what these values should be and have found no document or article that speak of one best way of doing things.
What is the best way to integrate my Spring Boot app with OAuth2? It already has login functionality with issuing a JWT token. What I want to achieve: perform login using OAuth2 and issue the same JWT to access my app.
What should I use:
Keycloak auth server + make my app a resource server
Write my own auth server using spring-security-oauth2-autoconfigure and spring-boot-starter-oauth2-client + make my app a resource server?
Any other approach you can suggest...
Maybe, this link can help you: https://stackshare.io/stackups/keycloak-vs-spring-security
It really depends on your scenario.
But, in my opinion, the first option has more advantages. The main one is the maintenance effort. With your own oauth server, you must maintain one more service. Keycloak is mature and open source, with many developers maintaining it.
I've been attempting to setup springboot2.5+ with the new saml2login implementation, but I'm finding it very difficult (due to lack of documentation and old documentation from the spring-security-saml extension) to do it in a stateless manner.
Has anyone been able to get springboot saml2 working stateless? I can't seem to figure out how to get my ACS (Assertion Consumer Service) filter from spring security to return a custom cookie with a redirect instead of a jsessionid.
Any help or insight would be awesome. Right now, I have a hack-y work around where I'm leaving sessions on, but attempting to kill the session right after SSO via SecurityContextHolder.clearContext(), but this is causing other issues.
I have a single grails (3.3.5) web server, and I am interested in improving the availability and I'd like to add another server and put a load balancer in front of it.
Rather than share sessions between servers, or use sticky sessions, i'd like to know if there is a good way to have a session-less front-end server. I don't use sessions for anything other than using spring-security to validate the session token that it is using to identify the user.
I'd like to find a token based authentication system suitable for the front-end such that the token is safe and sufficient for identifying the current user.
I've seen the grails-spring-security-rest plugin which looks promising, but it seems like everyone is using it for back-end rest api calls. Is it also suitable for front-end authentication when you aren't storing application data in the webapp session?
If you don't use the session objects in your controller then tomcat will not create any sessions for you.
Also you can define your controllers to be
static singleton = true
then they will be instantiated not on per-request basis.
Now, if you still want to use sessions, you can use something like Cookie Sessions and keep your data inside the cookies instead of tomcat's memory.
I haven't used the grails-spring-security-rest, but you should be able to tweak spring-security-core to be session-less. You should set scr.allowSessionCreation to false and use remember-me.
Since Grails is built on Spring Boot, you can access all the features of Spring Session (https://docs.spring.io/spring-session/docs/2.0.x/reference/html5/), which includes the ability to share session data between server instances with some data store instead of keeping it in memory.
In those docs you'll find this pointer to a guide with a Grails 3.1 example that uses Redis as the store. https://github.com/spring-projects/spring-session/tree/2.0.3.RELEASE/samples/misc/grails3
Is it also suitable for front-end authentication when you aren't storing application data in the webapp session?
Yes, you can use JWT tokens in your front-end. You need to properly configure the security filters of your controllers so that they are not using cookie for authentication but they are looking for JWT.
See : http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/#_plugin_configuration for configuration of endpoints that should validate JWT tokens.
Have a look at https://github.com/hantsy/angularjs-grails-sample/wiki/3-basic-auth for a stateless example with Angular.
We're using the Camunda RestAPI to communicate with the camunda-engine in the backend, so far so good, but we haven't been able to enable the Camunda authentication service so that users/rolls can only instanciate/claim/complete/see (when requesting via http) the tasks and processes which are assigned to them or their groups.
We're also using the spring boot implementation of the configuration, we have tried several things, but non has work so far as anyone can do anything and it's not even asking for credentials, so I was thinking I may be doing something wrong considering how complicated it has been.
So the question is, what are the standard steps we need to take to make these services work?
Thanks in advance.
Camunda is running bundled with a Tomcat server which allows LDAP, so one way might be to let your Tomcat do the permission management. In other words, you might limit the user access via the hosting web server.