Single Sign-On (SSO) has become an essential feature in modern web applications, enhancing both user experience and security. This comprehensive guide will walk you through implementing SSO using Keycloak and Spring Boot, providing a robust authentication and authorization solution for your applications.
Single Sign-On (SSO) is essential for streamlining authentication processes, enhancing security, and improving user experience. Here are some of the key benefits:
Centralized Authentication: SSO allows users to authenticate once and gain access to multiple applications. Keycloak provides centralized management for user identities, which is useful in environments with numerous applications.
Improved Security: With centralized identity management, security policies (like password strength, two-factor authentication, and account lockout policies) can be uniformly enforced. Keycloak’s support for protocols like OpenID Connect and OAuth 2.0 ensures robust, modern security standards.
Reduced Password Fatigue and Enhanced User Experience: By logging in only once, users avoid password fatigue and multiple credentials, leading to smoother and faster interactions across applications.
Scalability and Flexibility: Keycloak’s configuration can support large numbers of users and multiple identity providers, including social logins (Google, Facebook, etc.) and enterprise directories (LDAP, Active Directory).
Customization and Extensibility: Keycloak allows custom themes, login flows, and extensions, making it adaptable to various needs. It’s also open-source, providing flexibility for organizations to modify or extend the platform as required.
Alternatives to Single Sign-On (SSO):
Multiple Sign-On / Traditional Authentication:
Federated Identity:
Multi-Factor Authentication (MFA):
Before diving into the implementation, let's understand the SSO flow:
Create a new Spring Boot project with the following structure:
keycloak-demo/ ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── bansikah/ │ │ │ └── keycloakdemo/ │ │ │ ├── config/ │ │ │ │ └── SecurityConfig.java │ │ │ ├── controller/ │ │ │ │ └── FoodOrderingController.java │ │ │ └── KeycloakDemoApplication.java │ │ └── resources/ │ │ ├── templates/ │ │ │ ├── home.html │ │ │ └── menu.html │ │ └── application.yml ├── docker-compose.yml └── pom.xml
Note:
bansikah is my name ? so you can put yours or example anything you want...
Add the following dependencies to your pom.xml or you can just replace the dependency section to avoid conflicts:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity3 --> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity3</artifactId> <version>3.0.5.RELEASE</version> </dependency> </dependencies>
Create a docker-compose.yml file in the root directory:
version: '3' services: keycloak: image: quay.io/keycloak/keycloak:latest environment: KEYCLOAK_ADMIN: admin KEYCLOAK_ADMIN_PASSWORD: admin ports: - "8088:8080" command: - start-dev app: build: . ports: - "8082:8082" depends_on: - keycloak
Run the Keycloak server with:
docker-compose up -d
Access the Keycloak Admin Console:
Create a New Realm:
Create a New Client:
On the first screen:
On the next screen (Capability config):
http://localhost:8082/ http://localhost:8082/menu http://localhost:8082/login/oauth2/code/keycloak
and set the password:
Create application.yml in src/main/resources:
keycloak-demo/ ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── bansikah/ │ │ │ └── keycloakdemo/ │ │ │ ├── config/ │ │ │ │ └── SecurityConfig.java │ │ │ ├── controller/ │ │ │ │ └── FoodOrderingController.java │ │ │ └── KeycloakDemoApplication.java │ │ └── resources/ │ │ ├── templates/ │ │ │ ├── home.html │ │ │ └── menu.html │ │ └── application.yml ├── docker-compose.yml └── pom.xml
Replace
Note:
In production or as a good practice it will be good to keep delicate information as such in a .env file at the root of your project and use it as a variable in your configuration it will be something like ${CLIENT_SECRET} which picks it from the .env file when you start your application, this is also applicable to even the redirect, issuer-uri and the rest..
Create SecurityConfig.java in src/main/java/com/bansikah/keycloakdemo/config:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity3 --> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity3</artifactId> <version>3.0.5.RELEASE</version> </dependency> </dependencies>
Create FoodOrderingController.java in src/main/java/com/bansikah/keycloakdemo/controller:
version: '3' services: keycloak: image: quay.io/keycloak/keycloak:latest environment: KEYCLOAK_ADMIN: admin KEYCLOAK_ADMIN_PASSWORD: admin ports: - "8088:8080" command: - start-dev app: build: . ports: - "8082:8082" depends_on: - keycloak
Create home.html in src/main/resources/templates:
docker-compose up -d
Create menu.html in src/main/resources/templates:
http://localhost:8082/ http://localhost:8082/menu http://localhost:8082/login/oauth2/code/keycloak
You should be able to access the application on this url http://localhost:8082 and you should see this
and when you click the here link it takes you to the keycloak form where the user has to authenticate with username and password under the foodorder realm
and after authenticated you will see the menu page
Now with the importance of SSO, even if i logout, i won't have to login again as below
then i can click the link again and i won't be propted to enter my password and username again as below
Congratulations ?, and Thank you for following up till this time
This implementation demonstrates a robust SSO solution using Keycloak and Spring Boot. It provides a seamless authentication experience while maintaining security. The configuration allows for easy customization and extension to meet specific application needs.
If you encounter any issues or have questions about this implementation, please feel free to leave a comment below. Remember to check the Spring Security and Keycloak documentation for more advanced configurations and features.
Link to code on github
Ref:
The above is the detailed content of Keycloak and Spring Boot: The Ultimate Guide to Implementing Single Sign-On. For more information, please follow other related articles on the PHP Chinese website!