Part 1: Configure the Keycloak server to get the OAuth2.0 token
Step 1: Download the Keycloak server
https://www.keycloak.org/downloads
Step 2: start the Keycloak server
cd ~/downloads/keycloak-16.1.0/bin
./standalone.sh -Djboss.socket.binding.port-offset=100
Above command means the Keycloak port will be offset compared to default port
default port | offset | result port |
---|---|---|
8080 | 100 | 8180 |
8080 | 200 | 8280 |
Step 3: enter the Keycloak management console to configure
address is localhost:8180
3-1: Administration
Username, password
3-2: Enter the administration portal
Add Client, Role, User
3-3: Get the OAuth token
- get the token url
Realm / General / Enpoints / OpenID Endpoint Configuration, get token_endpoint
2. Open the Postman
Type | Oauth 2.0 |
scope | openid |
ClientID | |
Grant type | password |
Username | |
Password |
Part 2: Configure the Keycloak SpringBoot Adapter
Find this offical link for Keycloak SpringBoot Adapter
https://www.keycloak.org/docs/latest/securing_apps/#_spring_boot_adapter
Step 1: Add dependencies at pom.xml
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>16.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Step 2: Keycloak config
keycloak.realm = master
# 127.0.0.1 is different from localhost
keycloak.auth-server-url = http://localhost:8180/auth
keycloak.ssl-required = external
# client-id
keycloak.resource = pte
#keycloak.credentials.secret = 11111111-1111-1111-1111-1x11111111111
keycloak.use-resource-role-mappings = true
Step 3: SecurityConfig.java
@KeycloakConfiguration
@Import(KeycloakSpringBootConfigResolver.class)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter
{
/**
* Registers the KeycloakAuthenticationProvider with the authentication manager.
*/
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
KeycloakAuthenticationProvider provider = keycloakAuthenticationProvider();
provider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(provider);
}
/**
* Defines the session authentication strategy.
*/
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(buildSessionRegistry());
}
@Bean
protected SessionRegistry buildSessionRegistry() {
return new SessionRegistryImpl();
}
@Override
protected void configure(HttpSecurity http) throws Exception
{
super.configure(http);
http
.csrf().disable() // otherwise will have 403 error for all methods except GET
.authorizeRequests()
.antMatchers("/employees*").hasRole("pte-admin")
.anyRequest().permitAll();
}
}
Part 3: Configure the SpringBoot Resource Server
Employee.java
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity // This tells Hibernate to make a table out of this class
@Table
public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String department;
}
EmployeeController.java
@RestController
@RequestMapping(path="/employees")
public class EmployeeController {
@Autowired
private EmployeeRepository employeeRepository;
@PostMapping(path="/")
public ResponseEntity<Employee> save (@RequestBody Employee employee) {
return ResponseEntity.ok(employeeRepository.save(employee));
}
@GetMapping(path="/")
public ResponseEntity<List<Employee>> findAll () {
return ResponseEntity.ok((List<Employee>) employeeRepository.findAll());
}
}
EmployeeRepository.java
import org.springframework.data.repository.CrudRepository;
/**
* @description
*/
public interface EmployeeRepository extends CrudRepository<Employee, Integer> {
}
Part 4: set Mysql Server for Keycloak
Step 1: Create mysql schema for Keycloak
$ mysql -uroot -p
mysql> CREATE USER 'keycloak'@'%' IDENTIFIED BY 'keycloak';
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE DATABASE keycloak CHARACTER SET utf8 COLLATE utf8_unicode_ci;
Query OK, 1 row affected (0.00 sec)
mysql> GRANT ALL PRIVILEGES ON keycloak.* TO 'keycloak'@'%';
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
Step 2: JDBC setup
download the mysql connector jar https://dev.mysql.com/downloads/connector/j/. My version is mysql-connector-java-8.0.27.jar
Put the jar under keycloak/modules/system/layers/keycloak/com/mysql/main
$ sudo mkdir -p ~/Downloads/keycloak/modules/system/layers/keycloak/com/mysql/main
$ sudo cd ~/Downloads/keycloak/modules/system/layers/keycloak/com/mysql/main
$ sudo cp ~/Downloads/mysql-connector-java-5.1.42/mysql-connector-java-5.1.42-bin.jar .
$ sudo touch module.xml
module.xml
<?xml version="1.0" ?>
<module xmlns="urn:jboss:module:1.3" name="com.mysql">
<resources>
<resource-root path="mysql-connector-java-5.1.42-bin.jar" />
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>
Step 3: Declare and Load JDBC Driver
standalone.xml
~/Downloads/keycloak-16.1.0/standalone/configuration/standalone.xml
<subsystem xmlns="urn:jboss:domain:datasources:4.0">
<datasources>
...
<drivers>
<!-- new -->
<driver name="mysql" module="com.mysql">
<driver-class>com.mysql.cj.jdbc.Driver</driver-class>
</driver>
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
</drivers>
</datasources>
</subsystem>
Note:
name
is set tomysql
, but can be everything we want- we specify the
module
the attribute which points to themodule
the package we created earlier for the driver JAR - finally, we specify the driver’s Java class, which in case of MySQL is
com.mysql.cj.jdbc.Driver
Step 4: Datasource setup
We are going to change KeycloakDS
bloak
<datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}">
<connection-url>jdbc:mysql://localhost:3306/keycloak</connection-url>
<driver>mysql</driver>
<pool>
<min-pool-size>5</min-pool-size>
<max-pool-size>15</max-pool-size>
</pool>
<security>
<user-name>keycloak</user-name>
<password>keycloak</password>
</security>
</datasource>
Note
- we’ve searched for
datasource
definition forKeycloakDS
. - we modified the
connection-url
to point to the MySQL server - we defined the
driver
we use for the connection; this is the logical name of the JDBC driver we declared in the previous section (mysql
) - it is expensive to open a new connection to a database every time you want to perform a transaction. To compensate, the datasource implementation maintains a pool of open connections. The
max-pool-size
specifies the maximum number of connections it will pool. We may want to change the value of this depending on the load of the system. - finally, we need to define the database
user-name
andpassword
, that is needed to connect to the database.
Step 5: Load module for MySQL Driver
$ cd ~/downloads/keycloak-16.1.0/bin
$ ./jboss-cli.sh
You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
[disconnected /] module add --name=com.mysql --resources=~/Downloads/keycloak-16.1.0/modules/system/layers/keycloak/com/mysql/main/mysql-connector-java-8.0.27.jar --dependencies=javax.api,javax.transaction.api
[disconnected /]
Step 6: Booting up Keycloak
./standalone.sh -Djboss.socket.binding.port-offset=100
Part 5: Test
GET http://localhost:8081/employees/
References:
https://medium.com/@pratik.dandavate/setting-up-keycloak-standalone-with-mysql-database-7ebb614cc229