This post has been featured in the 7th anniversary edition of This Week in Spring – January 2n, 2018.
Important updates on March 22nd, 2018: Thanks to valid feedback from friends and colleagues Stéphane and Jochen and in the light of the high interested in this post, I have updated the demo. I basically removed all the boilerplate. With Spring Boot 2 final and Spring Security 5 final, you can use OAuth2 login from within a Boot-application agains Keycloak without the need of a key cloak starker or any boilerplate code. All you need is a sane configuration. Due to the nesting of the needed properties, I switched to YAML.
Here’s a short post how to authenticate against Keycloak from within a Spring Boot 2 application. For Spring Boot 1.5.x there’s a community adapter from the Keycloak-team that takes the burden from you, but this adapter is not yet ready for Spring Boot 2 and Spring Security 5.
I had the following requirements for the setup I am gonna present:
- Manage users outside one application (i.e. be ready for a bunch of services): Realized with Keycloak
- Full integration with Spring Security, especially method security
- Funktional with server side rendered Thymeleaf or other template systems supported by Spring Boot
Here is the fully functional demo project: keycloakdemo. I am not replicating some comments from the sources in the following paragraphs.
With Spring Boot 2 comes Spring Security 5 and the first class support for OAuth Login: New feature OAuth2-Login. That means one doesn’t need separate modules anymore. But to make this work, it’s not enough to have spring-boot-starter-security
on the class path, you’ll need two more dependencies:
I’ll spare you the details on how to setup Keycloak and how to create a realm and what a realm is. Keycloak has an excellent documentation about that and the screenshots from the one existing tutorial on how to use the Spring Boot adapter have been copied around anyway, along with that post. The realm I used in the demo is part of the repo: test-realm.json. It’s easy to import into Keycloak.
Next step, prepare your application as usual, that is: Annotate your Main-class with @SpringBootApplication
. Then configure your client registration together with Keycloak as the provider for the client as described in there in the documentation:
The first two properties are reused in the registration below so that I don’t have to copy them all over the place. This configuration creates a client registration for you. If you need more control, the documentation is there to help you: About client registration.
And now you’re ready to configure your security as usual with the added, new option .oauth2Login()
.
The following controller together with a simple Thymeleaf template is just for demoing purposes:
Assuming you have a Keycloak server running on port 8080, you can checkout the above linked project, build it with Java 9 and run it on port 8082. Open http://localhost:8082, hit login and you should be redirected to your Keycloak instance and back after a successful login.
Needless to say that this setup works well with other OAuth 2 providers.
18 comments
Hello. Thanks for the interesting post.
Could I tell you how to use it correctly to RestController. And how to make a logout.
Thank you.
There’s an example how to use a @PreAuthorize annotation in a rest controller directly at the bottom.
You can also use @RolesAllowed etc.
Those are Spring Security 101 and I highly recommend to get your self acquainted with those.
Hi,
Thanks for the article. Could you describe how can we logout the user with OAuth and KeyCloak?
Thanks
Hi,
as there is no session – at least when you didn’t explicitly configure one – you have to delete the JWT-token that authorizes you on the client side (i.e. delete the JWT cookie).
Well, that’s what I thought at first, but it does not work.
I cleared all cache and cookies from the browser dev tools (I am using Chrome, FYI), but the problem is that the server somehow still knows that I am authenticated. Its weird and I do now know how can that be but you can easily reproduce it. 🙁
Also, I don’t see a JWT token but rather a JSESSIONID and SESSION cookies.
I also tried changing the line where is says –
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
to different values without any help. STATELESS doesnt even work.
Hi Michael,
Thanks for putting together a great article.
I checked out your project and did a mvn clean install and got the following error:
[INFO] ————————————————————————
[INFO] BUILD FAILURE
[INFO] ————————————————————————
[INFO] Total time: 18.247 s
[INFO] Finished at: 2018-02-27T09:23:21-07:00
[INFO] Final Memory: 29M/97M
[INFO] ————————————————————————
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile (default-compile) on project keycloakdemo: Compilation failure: Compilation failure:
[ERROR] /Users/basil/DEVELOPMENT/michealsimons/keycloakdemo/src/main/java/ac/simons/keycloakdemo/DemoApplication.java:[21,55] cannot find symbol
[ERROR] symbol: class SecurityAutoConfiguration
[ERROR] location: package org.springframework.boot.autoconfigure.security
[ERROR] /Users/basil/DEVELOPMENT/michealsimons/keycloakdemo/src/main/java/ac/simons/keycloakdemo/DemoApplication.java:[53,34] cannot find symbol
[ERROR] symbol: class SecurityAutoConfiguration
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/conflu.....eException
Thanks a lot for that comment, Basil!
That must have been a recent change in the Spring Boot 2 Build-Snapshot.
I’ve fixed it: https://github.com/michael-simons/keycloakdemo/commit/5dcf261d527693fbf7fec1bb8bc5ba05984cec33
Can you also commit the keycloak.json file to configure easily.
Do you mean exporting the realm?
Yes you can commit the realm. So it is easy to configure for folks and to test what works and what does not.
Will this work with the Spring boot 2.0 release?
HI, I have tried to get oauth2 support with Spring Security 5, but I can not find where to get the **client secrect**?
Hantsy: The client secret is displayed in the Keycloak-admin page. You have to set “Access Type” of your realm to confidential.
I’ve updated my post and simplified the demo a lot. Also included now is the realm I’m using.
Spring Boot 2 with keycloak adapter
https://github.com/willardanuy/keycloak-springboot2-adapter
Well. I miss auto configuration, or oidc discovery.
This is a real turn-off. It’s sad that there’s no elaborate example with walkthrough for dummies.
Why is Java always extremely more complicated than everything else?
There was a keycloak adapter for spring boot <2 and life was good.
Right now I can have the same with better performance using Go and keycloak-proxy, also much less complicated than this.
Don't Java people know that genius lies in simplicity?
Why not Go, why bother with Spring Boot? Because it is lacking a proper ORM. That's the only reason.
Anyhow this: https://docs.spring.io/spring-security/site/docs/current/reference/html/jc.html#jc-oauth2login-boot-property-mappings
you have got to be kidding me.
You're like, "yo! read this bloated configuration without explanation what maps to where in keycloak" and if we don't get it, buy the book right?
That's what I hate about Java. A bunch of stuck up holier than thou exclusive club Yuppies.
This is making me sick.
Da ist eine Welt außerhalb deines Tellerrands.
I’m quite happy that I managed to not let my frustration about things getting to that level over the last years.
Here’s a link to my book: Spring Boot Buch. I heard many people find it useful.
The Spring filter bubble is IMHO one very welcoming and positive one.
Have a good day.
@dalu I do understand your frustration, but the problem seems to be many fold:
oidc may be a standard but it is not yet an _established_ standard. There are even still some features still in draft – like the logout (!).
And while you reference the keycloak adapter: it is created by the keycloak community. If there is none available for Spring Boot 2, this might be because SB2 is still to fresh. But you should give Spring Security a try – the oAuth2 functionality works quite well with oidc.
And if you still miss a feature – all of this is ooen source (which you are probably using for free) – feel free to contribute your solutions and help to give other a better experience 😎
a last hint: commercial oidc providers like okta and redhat (keycloak) are ready to help you with your project…
Post a Comment