SlideShare a Scribd company logo
1 of 14
Download to read offline
Ravi Yasas
Keycloak SSO
SINGLE SIGN ON WITH KEYCLOAK
Page 1 of 13
Content
Get started with Keycloak.……………………………………….………..02
Integrate Keycloak with Spring Boot and Spring Security……………..02
Sample property file…………………………………………………………………….03
Sample Security configuration file………………………………………03
Using Public access type……………………………………………………………….04
Project structure – Application one………………………………………………04
Project structure – Application two………………………………………………07
Using bearer-only access type………………………………………………………10
Page 2 of 13
Get started with Keycloak
• Apache Keycloak is an opensource identity and access management provider. Learn more
• You can download the Keycloak server from here You can download the stable latest release.
• Once you download just extract it. It may look like the above image.
• You can change the server port and other configuration data by changing standalone.xml file which is in
standalone -> configuration directory.
• If you need to start the Keycloak server go to the bin directory.
o Windows – run standalone.bat
o Linux – run standalone.sh
• Now Keycloak server will start on port 8080 if you did not change it.
• You can go to Administration Console from here http://localhost:8080/auth/
• The very first time you may need to create an admin user.
• Once you provide admin credentials you created, you can login to the admin panel.
Integrate Keycloak with Spring Boot and Spring Security
• Keycloak can be used with Spring Security. If you want, you can do it without integrating Spring Security.
• Apache Keycloak can be very easily integrated with Spring Boot and Spring Security. You need to do a few
things.
o Create a new Security configuration file.
o Add some properties to the property file.
Here I am going to create two small Spring Boot applications which are running on port 8090 and port 8092. I am using
another Spring Boot application which is running on port 8091 as a service for the application running on port 8090.
Page 3 of 13
Sample property file
keycloak.auth-server-url=http://localhost:8080/auth
keycloak.realm=api
keycloak.resource=app1
keycloak.public-client=true
Server.port= 8090
Sample Security configuration file
package com.example.productapp.security;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.client.KeycloakClientRequestFactory;
import org.keycloak.adapters.springsecurity.client.KeycloakRestTemplate;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
@KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Bean
public KeycloakConfigResolver keycloakConfigResolver(){
return new KeycloakSpringBootConfigResolver();
}
@Autowired
public KeycloakClientRequestFactory keycloakClientRequestFactory;
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public KeycloakRestTemplate keycloakRestTemplate(){
return new KeycloakRestTemplate(keycloakClientRequestFactory);
}
@Override
protected void configure(HttpSecurity http) throws Exception{
super.configure(http);
http.authorizeRequests()
.antMatchers("/products*").hasRole("user")
.anyRequest().permitAll();
}
}
Page 4 of 13
In Keycloak client configuration, there are three types of Access types.
1. Public – This is used for clients who need a browser login.
2. Confidential – This is used for clients who need browser login with a client secret.
3. Bearer only – This access type means it only allows bearer token requests not browser login
Using Public access type
Here I described two applications with public access type. Both applications look same. Here are some details of those
application.
Configuration Application one Application two
server.port 8090 8092
keycloak.auth-server-url http://localhost:8080/auth http://localhost:8080/auth
keycloak.realm api api
keycloak.resource client1 client2
keycloak.public-client true true
As you can see each application uses same realm (api), but different keycloak resources (client1 and client2)
Project structure – Application one
Page 5 of 13
ProductController.java
package com.example.productapp.controller;
import com.example.productapp.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@Controller
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping(path = "/products")
public String getProducts(Model model){
model.addAttribute("products", productService.getProducts());
return "products";
}
@GetMapping(path = "/logout")
public String logout(HttpServletRequest request) throws ServletException {
request.logout();
return "/";
}
}
ProductService.java
package com.example.productapp.service;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@Service
public class ProductService{
public List<String> getProducts(){
return Arrays.asList("Mazda","Toyota","Audi");
}
}
application.properties
server.port=8090
keycloak.enabled=true
keycloak.auth-server-url=http://localhost:8080/auth
keycloak.realm=api
keycloak.resource=client1
keycloak.public-client=true
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../../../favicon.ico">
<title>Home</title>
Page 6 of 13
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-
WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
</head>
<body class="text-center">
<div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
<main role="main" class="inner cover">
<h1 class="cover-heading">Apache Keycloak SSO demonstration</h1>
<p class="lead">
</p>
<p class="lead">
<a href="/products" class="btn btn-lg btn-secondary">Search products</a>
</p>
</main>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-
q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-
ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-
smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
</body>
</html>
Products.ftl
<#import "/spring.ftl" as spring>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../../../favicon.ico">
<title>Keycloak</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css"
integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB"
crossorigin="anonymous">
</head>
<body class="text-center">
<div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
<main role="main" class="inner cover">
<h1 class="cover-heading">Apache Keycloak SSO demonstration</h1>
<div style="width: 18rem; padding: 10px; display: block; margin-left: auto;margin-right: auto">
<ul class="list-group">
<#list products as product>
<li class="list-group-item">${product}</li>
</#list>
</ul>
</div>
<p class="lead">
<a href="/logout" class="btn btn-lg btn-secondary">Logout</a>
</p>
</main>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"
integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"
integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T"
crossorigin="anonymous"></script>
</body>
</html>
Page 7 of 13
SecurityConfig.java
This is same as Sample security config file above mentioned.
Project structure – Application two
Everything is same except application.properties file and ProductService file.
ProductService.java
package com.example.productapp.service;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@Service
public class ProductService{
public List<String> getProducts(){
return Arrays.asList("Apple", "Sony","Nokia", "Mi");
}
}
application.properties
server.port=8092
keycloak.auth-server-url=http://localhost:8080/auth
keycloak.realm=api
keycloak.public-client=true
keycloak.resource=client2
I created two Keycloak clients called client1 and client2 for these applications in Realm called “api”. Both clients have
same Access Type which is “public”
Page 8 of 13
Both clients are same but Client ID and Valid Redirect URLs are different.
• Client1 - http://localhost:8090*
• Client2 - http://localhost:8092*
Now you can run both applications on port 8090 and 8092. Then you can try as follows.
Just go to http://localhost:8090
Once you click on Search products button, you will be redirect to the Keycloak login page.
Page 9 of 13
Once you have logged in successfully, you will be redirected to secure page http://localhost:8090/products
Same time you can check the second service which is running on port 8092. Go to http://localhost:8090/products
Then it will not redirect you to Keycloak login page and directly it will redirect to the secure page. Because You already
login the Keycloak secure service.
Page 10 of 13
Using confidential and bearer-only access type
Here I’m going to create two REST web applications which are running on port 8090 and 8092. Please look at the project
details.
ProductController.java
package com.example.productapp.controller;
import com.example.productapp.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@RestController
public class ProductController {
@Autowired
private ProductService productService;
@PostMapping(path = "/products")
public List<String> getProducts(){
return productService.getProducts();
}
@GetMapping(path = "/logout")
public String logout(HttpServletRequest request) throws ServletException {
request.logout();
return "/";
}
}
ProductService.java
package com.example.productapp.service;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@Service
public class ProductService{
public List<String> getProducts(){
return Arrays.asList("Nokia","Sony");
}
}
application.properties
server.port=8090
keycloak.enabled=true
keycloak.auth-server-url=http://localhost:8080/auth
keycloak.realm=api
keycloak.resource=client3
keycloak.bearer-only=true
SecurityConfig.java
SecurityConfig.java file is same as Sample Security configuration file which I mentioned above.
Page 11 of 13
Here are the details of Keycloak client.
Since this is a REST web application I am going to use Postman to send the request.
Page 12 of 13
As you can see, you cannot access the source. Because it is secured by Keycloak and you need Authorization header
and with a Bearer token.
The bearer token can be received by following Keycloak API.
http://localhost:8080/auth/realms/{realm_name}/protocol/openid-connect/token
You must provide client_id, username, password, grant_type and client_secret to get the token.
• client_id – client name
• username – username of the user
• password – password of the user
• grant_type – this should be “password”
• client_secret – this can be found from Keycloak admin panel related to client
Once you provide related data, you will be able to get the token and some other details. Please check this screenshot.
Page 13 of 13
Then you can use this token in header to access the secured API.
This token will be saved by the front-end client (React, Angular…etc.) and it can be used in future requests.

More Related Content

What's hot

Oracle application express ppt
Oracle application express pptOracle application express ppt
Oracle application express ppt
Abhinaw Kumar
 

What's hot (20)

Hashicorp Vault ppt
Hashicorp Vault pptHashicorp Vault ppt
Hashicorp Vault ppt
 
Keycloak theme customization
Keycloak theme customizationKeycloak theme customization
Keycloak theme customization
 
Implementing WebAuthn & FAPI supports on Keycloak
Implementing WebAuthn & FAPI supports on KeycloakImplementing WebAuthn & FAPI supports on Keycloak
Implementing WebAuthn & FAPI supports on Keycloak
 
Spring security oauth2
Spring security oauth2Spring security oauth2
Spring security oauth2
 
OAuth 2.0
OAuth 2.0OAuth 2.0
OAuth 2.0
 
Keycloak for Science Gateways - SGCI Technology Sampler Webinar
Keycloak for Science Gateways - SGCI Technology Sampler WebinarKeycloak for Science Gateways - SGCI Technology Sampler Webinar
Keycloak for Science Gateways - SGCI Technology Sampler Webinar
 
HashiCorp's Vault - The Examples
HashiCorp's Vault - The ExamplesHashiCorp's Vault - The Examples
HashiCorp's Vault - The Examples
 
Secret Management with Hashicorp’s Vault
Secret Management with Hashicorp’s VaultSecret Management with Hashicorp’s Vault
Secret Management with Hashicorp’s Vault
 
OpenId Connect Protocol
OpenId Connect ProtocolOpenId Connect Protocol
OpenId Connect Protocol
 
OAuth 2.0 and OpenId Connect
OAuth 2.0 and OpenId ConnectOAuth 2.0 and OpenId Connect
OAuth 2.0 and OpenId Connect
 
Understanding JWT Exploitation
Understanding JWT ExploitationUnderstanding JWT Exploitation
Understanding JWT Exploitation
 
Vault - Secret and Key Management
Vault - Secret and Key ManagementVault - Secret and Key Management
Vault - Secret and Key Management
 
Spring Security 5
Spring Security 5Spring Security 5
Spring Security 5
 
Introduction to Vault
Introduction to VaultIntroduction to Vault
Introduction to Vault
 
Oracle application express ppt
Oracle application express pptOracle application express ppt
Oracle application express ppt
 
Identity management and single sign on - how much flexibility
Identity management and single sign on - how much flexibilityIdentity management and single sign on - how much flexibility
Identity management and single sign on - how much flexibility
 
Spring security
Spring securitySpring security
Spring security
 
Hashicorp Vault Open Source vs Enterprise
Hashicorp Vault Open Source vs EnterpriseHashicorp Vault Open Source vs Enterprise
Hashicorp Vault Open Source vs Enterprise
 
An Introduction to OAuth 2
An Introduction to OAuth 2An Introduction to OAuth 2
An Introduction to OAuth 2
 
Token, token... From SAML to OIDC
Token, token... From SAML to OIDCToken, token... From SAML to OIDC
Token, token... From SAML to OIDC
 

Similar to Keycloak Single Sign-On

Spring Live Sample Chapter
Spring Live Sample ChapterSpring Live Sample Chapter
Spring Live Sample Chapter
Syed Shahul
 
ScrumDesk API Getting Started
ScrumDesk API  Getting StartedScrumDesk API  Getting Started
ScrumDesk API Getting Started
ScrumDesk
 
Swift configurator installation-manual
Swift configurator installation-manualSwift configurator installation-manual
Swift configurator installation-manual
Pramod Sharma
 

Similar to Keycloak Single Sign-On (20)

Asset Model Import FlexConnector Developer's Guide
Asset Model Import FlexConnector Developer's GuideAsset Model Import FlexConnector Developer's Guide
Asset Model Import FlexConnector Developer's Guide
 
Spring Live Sample Chapter
Spring Live Sample ChapterSpring Live Sample Chapter
Spring Live Sample Chapter
 
A Detailed Guide to Securing React applications with Keycloak - WalkingTree ...
A Detailed Guide to Securing React applications with Keycloak  - WalkingTree ...A Detailed Guide to Securing React applications with Keycloak  - WalkingTree ...
A Detailed Guide to Securing React applications with Keycloak - WalkingTree ...
 
ScrumDesk API Getting Started
ScrumDesk API  Getting StartedScrumDesk API  Getting Started
ScrumDesk API Getting Started
 
Masterless Puppet Using AWS S3 Buckets and IAM Roles
Masterless Puppet Using AWS S3 Buckets and IAM RolesMasterless Puppet Using AWS S3 Buckets and IAM Roles
Masterless Puppet Using AWS S3 Buckets and IAM Roles
 
Actor Model Import Connector for Microsoft Active Directory
Actor Model Import Connector for Microsoft Active DirectoryActor Model Import Connector for Microsoft Active Directory
Actor Model Import Connector for Microsoft Active Directory
 
Ibm
IbmIbm
Ibm
 
Introducción a Wiremock
Introducción a WiremockIntroducción a Wiremock
Introducción a Wiremock
 
Swift configurator installation-manual
Swift configurator installation-manualSwift configurator installation-manual
Swift configurator installation-manual
 
Java EE Services
Java EE ServicesJava EE Services
Java EE Services
 
Microsoft Windows Server AppFabric
Microsoft Windows Server AppFabricMicrosoft Windows Server AppFabric
Microsoft Windows Server AppFabric
 
Spring boot microservice metrics monitoring
Spring boot   microservice metrics monitoringSpring boot   microservice metrics monitoring
Spring boot microservice metrics monitoring
 
Spring Boot - Microservice Metrics Monitoring
Spring Boot - Microservice Metrics MonitoringSpring Boot - Microservice Metrics Monitoring
Spring Boot - Microservice Metrics Monitoring
 
Defcon23 from zero to secure in 1 minute - nir valtman and moshe ferber
Defcon23   from zero to secure in 1 minute - nir valtman and moshe ferberDefcon23   from zero to secure in 1 minute - nir valtman and moshe ferber
Defcon23 from zero to secure in 1 minute - nir valtman and moshe ferber
 
jfx
jfxjfx
jfx
 
Asset modelimportconn devguide_5.2.1.6190.0
Asset modelimportconn devguide_5.2.1.6190.0Asset modelimportconn devguide_5.2.1.6190.0
Asset modelimportconn devguide_5.2.1.6190.0
 
Asset modelimportconn devguide_5.2.1.6190.0
Asset modelimportconn devguide_5.2.1.6190.0Asset modelimportconn devguide_5.2.1.6190.0
Asset modelimportconn devguide_5.2.1.6190.0
 
Integrating Ansible Tower with security orchestration and cloud management
Integrating Ansible Tower with security orchestration and cloud managementIntegrating Ansible Tower with security orchestration and cloud management
Integrating Ansible Tower with security orchestration and cloud management
 
Scale Your Data Tier With Windows Server App Fabric
Scale Your Data Tier With Windows Server App FabricScale Your Data Tier With Windows Server App Fabric
Scale Your Data Tier With Windows Server App Fabric
 
Adding User Management to Node.js
Adding User Management to Node.jsAdding User Management to Node.js
Adding User Management to Node.js
 

More from Ravi Yasas

CCNA Exam 640-802 Version 9.3
CCNA Exam 640-802 Version 9.3CCNA Exam 640-802 Version 9.3
CCNA Exam 640-802 Version 9.3
Ravi Yasas
 

More from Ravi Yasas (13)

Redis clustering
Redis clusteringRedis clustering
Redis clustering
 
Android OS
Android OSAndroid OS
Android OS
 
Distributed systems
Distributed systemsDistributed systems
Distributed systems
 
Display types (LED, LCD, Plasma, Plotter, Virtual Reality)
Display types (LED, LCD, Plasma, Plotter, Virtual Reality)Display types (LED, LCD, Plasma, Plotter, Virtual Reality)
Display types (LED, LCD, Plasma, Plotter, Virtual Reality)
 
Modern Management Thoughts
Modern Management ThoughtsModern Management Thoughts
Modern Management Thoughts
 
Intel 8086 microprocessor
Intel 8086 microprocessorIntel 8086 microprocessor
Intel 8086 microprocessor
 
Cubic robots
Cubic robotsCubic robots
Cubic robots
 
Software requirement specification
Software requirement specificationSoftware requirement specification
Software requirement specification
 
Example for SDS document in Software engineering
Example for SDS document in Software engineeringExample for SDS document in Software engineering
Example for SDS document in Software engineering
 
Fiber optic cables
Fiber optic cablesFiber optic cables
Fiber optic cables
 
NTFS file system
NTFS file systemNTFS file system
NTFS file system
 
CCNA Exam 640-802 Version 9.3
CCNA Exam 640-802 Version 9.3CCNA Exam 640-802 Version 9.3
CCNA Exam 640-802 Version 9.3
 
Windows network administration Basic theories
Windows network administration Basic theoriesWindows network administration Basic theories
Windows network administration Basic theories
 

Recently uploaded

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
anilsa9823
 

Recently uploaded (20)

5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 

Keycloak Single Sign-On

  • 1. Ravi Yasas Keycloak SSO SINGLE SIGN ON WITH KEYCLOAK
  • 2. Page 1 of 13 Content Get started with Keycloak.……………………………………….………..02 Integrate Keycloak with Spring Boot and Spring Security……………..02 Sample property file…………………………………………………………………….03 Sample Security configuration file………………………………………03 Using Public access type……………………………………………………………….04 Project structure – Application one………………………………………………04 Project structure – Application two………………………………………………07 Using bearer-only access type………………………………………………………10
  • 3. Page 2 of 13 Get started with Keycloak • Apache Keycloak is an opensource identity and access management provider. Learn more • You can download the Keycloak server from here You can download the stable latest release. • Once you download just extract it. It may look like the above image. • You can change the server port and other configuration data by changing standalone.xml file which is in standalone -> configuration directory. • If you need to start the Keycloak server go to the bin directory. o Windows – run standalone.bat o Linux – run standalone.sh • Now Keycloak server will start on port 8080 if you did not change it. • You can go to Administration Console from here http://localhost:8080/auth/ • The very first time you may need to create an admin user. • Once you provide admin credentials you created, you can login to the admin panel. Integrate Keycloak with Spring Boot and Spring Security • Keycloak can be used with Spring Security. If you want, you can do it without integrating Spring Security. • Apache Keycloak can be very easily integrated with Spring Boot and Spring Security. You need to do a few things. o Create a new Security configuration file. o Add some properties to the property file. Here I am going to create two small Spring Boot applications which are running on port 8090 and port 8092. I am using another Spring Boot application which is running on port 8091 as a service for the application running on port 8090.
  • 4. Page 3 of 13 Sample property file keycloak.auth-server-url=http://localhost:8080/auth keycloak.realm=api keycloak.resource=app1 keycloak.public-client=true Server.port= 8090 Sample Security configuration file package com.example.productapp.security; import org.keycloak.adapters.KeycloakConfigResolver; import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; import org.keycloak.adapters.springsecurity.KeycloakConfiguration; import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; import org.keycloak.adapters.springsecurity.client.KeycloakClientRequestFactory; import org.keycloak.adapters.springsecurity.client.KeycloakRestTemplate; import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Scope; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; import org.springframework.security.core.session.SessionRegistryImpl; import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; @KeycloakConfiguration public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{ KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider(); keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); auth.authenticationProvider(keycloakAuthenticationProvider); } @Bean @Override protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); } @Bean public KeycloakConfigResolver keycloakConfigResolver(){ return new KeycloakSpringBootConfigResolver(); } @Autowired public KeycloakClientRequestFactory keycloakClientRequestFactory; @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public KeycloakRestTemplate keycloakRestTemplate(){ return new KeycloakRestTemplate(keycloakClientRequestFactory); } @Override protected void configure(HttpSecurity http) throws Exception{ super.configure(http); http.authorizeRequests() .antMatchers("/products*").hasRole("user") .anyRequest().permitAll(); } }
  • 5. Page 4 of 13 In Keycloak client configuration, there are three types of Access types. 1. Public – This is used for clients who need a browser login. 2. Confidential – This is used for clients who need browser login with a client secret. 3. Bearer only – This access type means it only allows bearer token requests not browser login Using Public access type Here I described two applications with public access type. Both applications look same. Here are some details of those application. Configuration Application one Application two server.port 8090 8092 keycloak.auth-server-url http://localhost:8080/auth http://localhost:8080/auth keycloak.realm api api keycloak.resource client1 client2 keycloak.public-client true true As you can see each application uses same realm (api), but different keycloak resources (client1 and client2) Project structure – Application one
  • 6. Page 5 of 13 ProductController.java package com.example.productapp.controller; import com.example.productapp.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @Controller public class ProductController { @Autowired private ProductService productService; @GetMapping(path = "/products") public String getProducts(Model model){ model.addAttribute("products", productService.getProducts()); return "products"; } @GetMapping(path = "/logout") public String logout(HttpServletRequest request) throws ServletException { request.logout(); return "/"; } } ProductService.java package com.example.productapp.service; import org.springframework.stereotype.Service; import java.util.Arrays; import java.util.List; @Service public class ProductService{ public List<String> getProducts(){ return Arrays.asList("Mazda","Toyota","Audi"); } } application.properties server.port=8090 keycloak.enabled=true keycloak.auth-server-url=http://localhost:8080/auth keycloak.realm=api keycloak.resource=client1 keycloak.public-client=true index.html <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <link rel="icon" href="../../../../favicon.ico"> <title>Home</title>
  • 7. Page 6 of 13 <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384- WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous"> </head> <body class="text-center"> <div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column"> <main role="main" class="inner cover"> <h1 class="cover-heading">Apache Keycloak SSO demonstration</h1> <p class="lead"> </p> <p class="lead"> <a href="/products" class="btn btn-lg btn-secondary">Search products</a> </p> </main> </div> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384- q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384- ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384- smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script> </body> </html> Products.ftl <#import "/spring.ftl" as spring> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <link rel="icon" href="../../../../favicon.ico"> <title>Keycloak</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous"> </head> <body class="text-center"> <div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column"> <main role="main" class="inner cover"> <h1 class="cover-heading">Apache Keycloak SSO demonstration</h1> <div style="width: 18rem; padding: 10px; display: block; margin-left: auto;margin-right: auto"> <ul class="list-group"> <#list products as product> <li class="list-group-item">${product}</li> </#list> </ul> </div> <p class="lead"> <a href="/logout" class="btn btn-lg btn-secondary">Logout</a> </p> </main> </div> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script> </body> </html>
  • 8. Page 7 of 13 SecurityConfig.java This is same as Sample security config file above mentioned. Project structure – Application two Everything is same except application.properties file and ProductService file. ProductService.java package com.example.productapp.service; import org.springframework.stereotype.Service; import java.util.Arrays; import java.util.List; @Service public class ProductService{ public List<String> getProducts(){ return Arrays.asList("Apple", "Sony","Nokia", "Mi"); } } application.properties server.port=8092 keycloak.auth-server-url=http://localhost:8080/auth keycloak.realm=api keycloak.public-client=true keycloak.resource=client2 I created two Keycloak clients called client1 and client2 for these applications in Realm called “api”. Both clients have same Access Type which is “public”
  • 9. Page 8 of 13 Both clients are same but Client ID and Valid Redirect URLs are different. • Client1 - http://localhost:8090* • Client2 - http://localhost:8092* Now you can run both applications on port 8090 and 8092. Then you can try as follows. Just go to http://localhost:8090 Once you click on Search products button, you will be redirect to the Keycloak login page.
  • 10. Page 9 of 13 Once you have logged in successfully, you will be redirected to secure page http://localhost:8090/products Same time you can check the second service which is running on port 8092. Go to http://localhost:8090/products Then it will not redirect you to Keycloak login page and directly it will redirect to the secure page. Because You already login the Keycloak secure service.
  • 11. Page 10 of 13 Using confidential and bearer-only access type Here I’m going to create two REST web applications which are running on port 8090 and 8092. Please look at the project details. ProductController.java package com.example.productapp.controller; import com.example.productapp.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import java.util.List; @RestController public class ProductController { @Autowired private ProductService productService; @PostMapping(path = "/products") public List<String> getProducts(){ return productService.getProducts(); } @GetMapping(path = "/logout") public String logout(HttpServletRequest request) throws ServletException { request.logout(); return "/"; } } ProductService.java package com.example.productapp.service; import org.springframework.stereotype.Service; import java.util.Arrays; import java.util.List; @Service public class ProductService{ public List<String> getProducts(){ return Arrays.asList("Nokia","Sony"); } } application.properties server.port=8090 keycloak.enabled=true keycloak.auth-server-url=http://localhost:8080/auth keycloak.realm=api keycloak.resource=client3 keycloak.bearer-only=true SecurityConfig.java SecurityConfig.java file is same as Sample Security configuration file which I mentioned above.
  • 12. Page 11 of 13 Here are the details of Keycloak client. Since this is a REST web application I am going to use Postman to send the request.
  • 13. Page 12 of 13 As you can see, you cannot access the source. Because it is secured by Keycloak and you need Authorization header and with a Bearer token. The bearer token can be received by following Keycloak API. http://localhost:8080/auth/realms/{realm_name}/protocol/openid-connect/token You must provide client_id, username, password, grant_type and client_secret to get the token. • client_id – client name • username – username of the user • password – password of the user • grant_type – this should be “password” • client_secret – this can be found from Keycloak admin panel related to client Once you provide related data, you will be able to get the token and some other details. Please check this screenshot.
  • 14. Page 13 of 13 Then you can use this token in header to access the secured API. This token will be saved by the front-end client (React, Angular…etc.) and it can be used in future requests.