jwt (JSON Web Token)
JSON Web Token
https://www.devglan.com/spring-security/spring-boot-jwt-auth
https://www.tutorialspoint.com/spring_boot/spring_boot_oauth2_with_jwt.htm
Overview
In authentication, when the user successfully logs in using their credentials, a JSON Web Token will be returned and must be saved locally (typically in local or session storage, but cookies can also be used), instead of the traditional approach of creating a session in the server and returning a cookie.
The tokens are designed to be compact,[2] URL-safe,[3] and usable especially in a web-browser single-sign-on (SSO) context. JWT claims can be typically used to pass identity of authenticated users between an identity provider and a service provider, or any other type of claims as required by business processes.
This is a stateless authentication mechanism as the user state is never saved in server memory. The server's protected routes will check for a valid JWT in the Authorization header, and if it is present, the user will be allowed to access protected resources. As JWTs are self-contained, all the necessary information is there, reducing the need to query the database multiple times.
Adapted tutorials point Spring boot + JWT example + OAuth2
The example in the tutorial doesn't run out of the box. It doesn't explain how to load the private key (PEM). Also it relies on Java 8. If we try to use the example with Java 11 it doesn't work due to issues with xml bind.
Structure
. ├── build_image.sh ├── connect_container.sh ├── Dockerfile ├── get_token.sh ├── jwt.pem ├── pom.xml ├── run_container.sh ├── src │ └── main │ ├── java │ │ └── com │ │ └── tutorialspoint │ │ └── websecurityapp │ │ ├── AnonymousController.java │ │ ├── CustomDetailsService.java │ │ ├── CustomUser.java │ │ ├── OAuth2Config.java │ │ ├── OAuthDao.java │ │ ├── SecurityConfiguration.java │ │ ├── UserEntity.java │ │ └── WebsecurityappApplication.java │ └── resources │ ├── application.properties │ ├── data.sql │ └── schema.sql └── stop_container.sh
run_container.sh
1 docker run -d -p 8080:8080 --name test test_image
Dockerfile
src/main/java/com/tutorialspoint/websecurityapp/SecurityConfiguration.java
1 package com.tutorialspoint.websecurityapp;
2
3 import org.springframework.beans.factory.annotation.Autowired;
4 import org.springframework.context.annotation.Bean;
5 import org.springframework.context.annotation.Configuration;
6
7 import org.springframework.security.authentication.AuthenticationManager;
8 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
9 import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
10 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
11 import org.springframework.security.config.annotation.web.builders.WebSecurity;
12 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
13 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
14 import org.springframework.security.config.http.SessionCreationPolicy;
15 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
16 import org.springframework.security.crypto.password.PasswordEncoder;
17
18 @Configuration
19 @EnableWebSecurity
20 @EnableGlobalMethodSecurity(prePostEnabled = true)
21 public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
22 @Autowired
23 private CustomDetailsService customDetailsService;
24
25 @Bean
26 public PasswordEncoder encoder() {
27 return new BCryptPasswordEncoder();
28 }
29
30 @Override
31 @Autowired
32 protected void configure(AuthenticationManagerBuilder auth) throws Exception {
33 auth.userDetailsService(customDetailsService).passwordEncoder(encoder());
34 }
35
36 @Override
37 protected void configure(HttpSecurity http) throws Exception {
38 http.authorizeRequests().anyRequest().authenticated().and().sessionManagement()
39 .sessionCreationPolicy(SessionCreationPolicy.NEVER);
40
41 }
42
43 @Override
44 public void configure(WebSecurity web) throws Exception {
45 web.ignoring().antMatchers("/anonymous/**", "/resources/**", "/static/**");
46 }
47
48 @Override
49 @Bean
50 public AuthenticationManager authenticationManagerBean() throws Exception {
51 return super.authenticationManagerBean();
52 }
53 }
src/main/java/com/tutorialspoint/websecurityapp/OAuth2Config.java
1 package com.tutorialspoint.websecurityapp;
2
3 import org.springframework.beans.factory.annotation.Autowired;
4 import org.springframework.beans.factory.annotation.Qualifier;
5 import org.springframework.context.annotation.Bean;
6 import org.springframework.context.annotation.Configuration;
7
8 import org.springframework.security.authentication.AuthenticationManager;
9 import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
10 import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
11 import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
12 import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
13 import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
14 import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
15
16 import java.io.FileReader;
17 import java.io.BufferedReader;
18
19 @Configuration
20 public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
21 private String clientid = "tutorialspoint";
22 private String clientSecret = "my-secret-key";
23
24 @Autowired
25 @Qualifier("authenticationManagerBean")
26 private AuthenticationManager authenticationManager;
27
28 private String getFileContent(String filename) {
29 String ret = "";
30 BufferedReader bufReader = null;
31 try {
32 bufReader = new BufferedReader(new FileReader(filename));
33 String line = "";
34 while (line != null) {
35 line = bufReader.readLine();
36 if (line != null) {
37 ret += line;
38 }
39 }
40 bufReader.close();
41 } catch (Exception ex) {
42 } finally {
43 }
44
45 return ret;
46 }
47
48 @Bean
49 public JwtAccessTokenConverter tokenEnhancer() {
50
51 JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
52 String pemData = getFileContent("jwt.pem");
53 converter.setSigningKey(pemData);
54 converter.setVerifierKey(pemData);
55 return converter;
56 }
57
58 @Bean
59 public JwtTokenStore tokenStore() {
60 return new JwtTokenStore(tokenEnhancer());
61 }
62
63 @Override
64 public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
65 endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore())
66 .accessTokenConverter(tokenEnhancer());
67 }
68
69 @Override
70 public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
71 security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
72 }
73
74 @Override
75 public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
76 clients.inMemory().withClient(clientid).secret(clientSecret).scopes("read", "write")
77 .authorizedGrantTypes("password", "refresh_token").accessTokenValiditySeconds(20000)
78 .refreshTokenValiditySeconds(20000);
79
80 }
81 }
src/main/java/com/tutorialspoint/websecurityapp/CustomUser.java
1 package com.tutorialspoint.websecurityapp;
2
3 import org.springframework.security.core.userdetails.User;
4
5 public class CustomUser extends User {
6 private static final long serialVersionUID = 1L;
7 public CustomUser(UserEntity user) {
8 super(user.getUsername(), user.getPassword(), user.getGrantedAuthoritiesList());
9 }
10 }
src/main/java/com/tutorialspoint/websecurityapp/UserEntity.java
1 package com.tutorialspoint.websecurityapp;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import org.springframework.security.core.GrantedAuthority;
6
7 public class UserEntity {
8 private String username;
9 private String password;
10 private String role;
11 private Collection<GrantedAuthority> grantedAuthoritiesList = new ArrayList<>();
12
13 public String getPassword() {
14 return password;
15 }
16
17 public void setPassword(String password) {
18 this.password = password;
19 }
20
21 public Collection<GrantedAuthority> getGrantedAuthoritiesList() {
22 return grantedAuthoritiesList;
23 }
24
25 public void setGrantedAuthoritiesList(Collection<GrantedAuthority> grantedAuthoritiesList) {
26 this.grantedAuthoritiesList = grantedAuthoritiesList;
27 }
28
29 public String getUsername() {
30 return username;
31 }
32
33 public void setUsername(String username) {
34 this.username = username;
35 }
36
37 public String getRole() {
38 return role;
39 }
40
41 public void setRole(String role) {
42 this.role = role;
43 }
44
45 }
src/main/java/com/tutorialspoint/websecurityapp/AnonymousController.java
1 package com.tutorialspoint.websecurityapp;
2
3 import org.springframework.stereotype.Controller;
4 import org.springframework.web.bind.annotation.RequestMapping;
5 import org.springframework.web.bind.annotation.ResponseBody;
6
7 @Controller
8 @RequestMapping("/anonymous")
9 public class AnonymousController {
10
11 @ResponseBody
12 @RequestMapping(value = "/dummy", produces = "application/json")
13 // http://localhost:8080/anonymous/dummy
14 public String getDummy() {
15 return "dummy";
16 }
17
18 }
src/main/java/com/tutorialspoint/websecurityapp/WebsecurityappApplication.java
1 package com.tutorialspoint.websecurityapp;
2
3 import org.springframework.boot.SpringApplication;
4 import org.springframework.boot.autoconfigure.SpringBootApplication;
5 import org.springframework.security.access.prepost.PreAuthorize;
6 import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
7 import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
8 import org.springframework.web.bind.annotation.RequestMapping;
9 import org.springframework.web.bind.annotation.RestController;
10
11 @SpringBootApplication
12 @EnableAuthorizationServer
13 @EnableResourceServer
14 @RestController
15 public class WebsecurityappApplication {
16 public static void main(String[] args) {
17 SpringApplication.run(WebsecurityappApplication.class, args);
18 }
19
20 @PreAuthorize("hasRole('ROLE_ADMIN')")
21 @RequestMapping(value = "/products")
22 public String getProductName() {
23 return "Honey";
24 }
25
26 @PreAuthorize("hasRole('ROLE_USER')")
27 @RequestMapping(value = "/productsuser")
28 public String getProductNameUsers() {
29 return "HoneyUser";
30 }
31
32 }
src/main/java/com/tutorialspoint/websecurityapp/CustomDetailsService.java
1 package com.tutorialspoint.websecurityapp;
2
3 import org.springframework.beans.factory.annotation.Autowired;
4 import org.springframework.security.core.userdetails.UserDetailsService;
5 import org.springframework.security.core.userdetails.UsernameNotFoundException;
6 import org.springframework.stereotype.Service;
7
8 @Service
9 public class CustomDetailsService implements UserDetailsService {
10 @Autowired
11 OAuthDao oauthDao;
12
13 @Override
14 public CustomUser loadUserByUsername(final String username) throws UsernameNotFoundException {
15 UserEntity userEntity = null;
16 try {
17 userEntity = oauthDao.getUserDetails(username);
18 CustomUser customUser = new CustomUser(userEntity);
19 return customUser;
20 } catch (Exception e) {
21 e.printStackTrace();
22 throw new UsernameNotFoundException("User " + username + " was not found in the database");
23 }
24 }
25 }
src/main/java/com/tutorialspoint/websecurityapp/OAuthDao.java
1 package com.tutorialspoint.websecurityapp;
2
3 import java.sql.ResultSet;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.List;
7
8 import org.springframework.beans.factory.annotation.Autowired;
9 import org.springframework.jdbc.core.JdbcTemplate;
10 import org.springframework.security.core.GrantedAuthority;
11 import org.springframework.security.core.authority.SimpleGrantedAuthority;
12 import org.springframework.stereotype.Repository;
13
14 @Repository
15 public class OAuthDao {
16 @Autowired
17 private JdbcTemplate jdbcTemplate;
18
19 public UserEntity getUserDetails(String username) {
20
21 String userSQLQuery = "SELECT * FROM USERS WHERE USERNAME=?";
22 List<UserEntity> list = jdbcTemplate.query(userSQLQuery, new String[] { username },
23 (ResultSet resultSet, int rowNum) -> {
24
25 UserEntity user = new UserEntity();
26 user.setUsername(username);
27 user.setPassword(resultSet.getString("PASSWORD"));
28 user.setRole(resultSet.getString("ROLE"));
29 return user;
30 });
31
32 if (list.size() > 0) {
33 Collection<GrantedAuthority> grantedAuthoritiesList = new ArrayList<>();
34 UserEntity user = list.get(0);
35 GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(user.getRole());
36 grantedAuthoritiesList.add(grantedAuthority);
37 user.setGrantedAuthoritiesList(grantedAuthoritiesList);
38 return user;
39 }
40
41 return null;
42 }
43 }
src/main/resources/schema.sql
1 CREATE TABLE USERS (ID INT PRIMARY KEY, USERNAME VARCHAR(45), PASSWORD VARCHAR(60), ROLE VARCHAR(60) );
src/main/resources/application.properties
security.oauth2.resource.filter-order=3 logging.file=/tmp/testout.log
src/main/resources/data.sql
1 INSERT INTO USERS (ID, USERNAME,PASSWORD, ROLE) VALUES (
2 1, 'tutorialspoint@gmail.com','$2a$08$fL7u5xcvsZl78su29x1ti.dxI.9rYO8t0q5wk2ROJ.1cdR53bmaVG','ROLE_ADMIN');
3
4 INSERT INTO USERS (ID, USERNAME,PASSWORD, ROLE) VALUES (
5 2, 'myemail@gmail.com','$2a$08$fL7u5xcvsZl78su29x1ti.dxI.9rYO8t0q5wk2ROJ.1cdR53bmaVG','ROLE_USER');
build_image.sh
1 docker build -t test_image .
pom.xml
1 <?xml version = "1.0" encoding = "UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
5 http://maven.apache.org/xsd/maven-4.0.0.xsd">
6
7 <modelVersion>4.0.0</modelVersion>
8 <groupId>com.tutorialspoint</groupId>
9 <artifactId>websecurityapp</artifactId>
10 <version>0.0.1-SNAPSHOT</version>
11 <packaging>jar</packaging>
12 <name>websecurityapp</name>
13 <description>Demo project for Spring Boot</description>
14
15 <parent>
16 <groupId>org.springframework.boot</groupId>
17 <artifactId>spring-boot-starter-parent</artifactId>
18 <version>1.5.9.RELEASE</version>
19 <relativePath /> <!-- lookup parent from repository -->
20 </parent>
21
22 <properties>
23 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
24 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
25 <java.version>1.8</java.version>
26 </properties>
27
28 <dependencies>
29 <!-- Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException -->
30 <!-- API, java.xml.bind module -->
31 <dependency>
32 <groupId>jakarta.xml.bind</groupId>
33 <artifactId>jakarta.xml.bind-api</artifactId>
34 <version>2.3.2</version>
35 </dependency>
36
37 <!-- Runtime, com.sun.xml.bind module -->
38 <dependency>
39 <groupId>org.glassfish.jaxb</groupId>
40 <artifactId>jaxb-runtime</artifactId>
41 <version>2.3.2</version>
42 </dependency>
43 <dependency>
44 <groupId>org.springframework.boot</groupId>
45 <artifactId>spring-boot-starter-jdbc</artifactId>
46 </dependency>
47
48 <dependency>
49 <groupId>org.springframework.boot</groupId>
50 <artifactId>spring-boot-starter-security</artifactId>
51 </dependency>
52
53 <dependency>
54 <groupId>org.springframework.boot</groupId>
55 <artifactId>spring-boot-starter-web</artifactId>
56 </dependency>
57
58 <dependency>
59 <groupId>org.springframework.security.oauth</groupId>
60 <artifactId>spring-security-oauth2</artifactId>
61 </dependency>
62
63 <dependency>
64 <groupId>org.springframework.security</groupId>
65 <artifactId>spring-security-jwt</artifactId>
66 </dependency>
67
68 <dependency>
69 <groupId>com.h2database</groupId>
70 <artifactId>h2</artifactId>
71 </dependency>
72
73 <dependency>
74 <groupId>org.springframework.boot</groupId>
75 <artifactId>spring-boot-starter-test</artifactId>
76 <scope>test</scope>
77 </dependency>
78
79 <dependency>
80 <groupId>org.springframework.security</groupId>
81 <artifactId>spring-security-test</artifactId>
82 <scope>test</scope>
83 </dependency>
84 </dependencies>
85
86 <build>
87 <plugins>
88 <plugin>
89 <groupId>org.springframework.boot</groupId>
90 <artifactId>spring-boot-maven-plugin</artifactId>
91 </plugin>
92 </plugins>
93 </build>
94
95 </project>
get_token.sh
1 ACCESS_TOKEN=$(curl -X POST --url http://localhost:8080/oauth/token --user tutorialspoint:my-secret-key --data 'grant_type=password&username=myemail@gmail.com&password=password' | jq -r '.access_token')
2 ACCESS_TOKEN_ADMIN=$(curl -X POST --url http://localhost:8080/oauth/token --user tutorialspoint:my-secret-key --data 'grant_type=password&username=tutorialspoint@gmail.com&password=password' | jq -r '.access_token')
3 #echo $ACCESS_TOKEN
4 curl -X GET http://localhost:8080/productsuser --header "Authorization: Bearer $ACCESS_TOKEN"
5 curl -X GET http://localhost:8080/products --header "Authorization: Bearer $ACCESS_TOKEN_ADMIN"
6 curl -X GET http://localhost:8080/anonymous/dummy
7
8 curl -X GET http://localhost:8080/products --header "Authorization: Bearer $ACCESS_TOKEN"
9 curl -X GET http://localhost:8080/productsuser --header "Authorization: Bearer $ACCESS_TOKEN_ADMIN"
connect_container.sh
1 docker exec -it test /bin/sh
stop_container.sh
SpringBoot 2.2.8 (resource server - Spring Security 5) + keycloak 10.0.2 (authentication server) + Java 11
1 mkdir -p ~/Documents/test-springboot-keycloak
2 cd ~/Documents/test-springboot-keycloak
3 wget https://downloads.jboss.org/keycloak/10.0.2/keycloak-10.0.2.zip
4 unzip -t keycloak-10.0.2.zip
5 unzip keycloak-10.0.2.zip
6 cd keycloak-10.0.2/bin
7 sh standalone.sh
8 http://localhost:8080/auth
9 admin admin admin create
10 http://localhost:8080/auth/admin/master/console/#/realms/master
11 Master, add realm, MyRealm , create
12 Users, add user, myuser
13 select user, credentials, mypwd mypwd, temporary off
14 Add role USER to MyRealm
15 Make user myuser have role USER
16 signout
17 http://localhost:8080/auth/realms/MyRealm/account/
18
19 realm: MyRealm
20 user pwd: myuser mypwd
21 client id: curl_confidential
22 protocol: openid-connect
23 Curl_confidential settings: access-type confidential
24 valid redirect url http://localhost:8080
25 save in MyRealm, Client, client: curl_confidential
26 tab credentials: regenerate secret 6dfe5f84-d115-4d3e-8a56-a0fcf5b2f13e
27
28 curl -d 'client_id=curl_confidential' -d 'client_secret=6dfe5f84-d115-4d3e-8a56-a0fcf5b2f13e' -d 'username=myuser' -d 'password=mypwd' -d 'grant_type=password' 'http://localhost:8080/auth/realms/MyRealm/protocol/openid-connect/token'
. ├── pom.xml └── src └── main ├── java │ └── com │ └── example │ └── demo │ └── DemoApplication.java └── resources └── application.properties
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5 <parent>
6 <groupId>org.springframework.boot</groupId>
7 <artifactId>spring-boot-starter-parent</artifactId>
8 <version>2.2.8.RELEASE</version>
9 <relativePath/> <!-- lookup parent from repository -->
10 </parent>
11 <groupId>com.example</groupId>
12 <artifactId>demo</artifactId>
13 <version>0.0.1-SNAPSHOT</version>
14 <name>demo</name>
15 <description>Demo project for Spring Boot</description>
16 <properties>
17 <java.version>11</java.version>
18 </properties>
19 <dependencies>
20 <dependency>
21 <groupId>org.springframework.boot</groupId>
22 <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
23 </dependency>
24 <dependency>
25 <groupId>org.springframework.boot</groupId>
26 <artifactId>spring-boot-starter-security</artifactId>
27 </dependency>
28 <dependency>
29 <groupId>org.springframework.boot</groupId>
30 <artifactId>spring-boot-starter-web</artifactId>
31 </dependency>
32 </dependencies>
33 <build>
34 <plugins>
35 <plugin>
36 <groupId>org.springframework.boot</groupId>
37 <artifactId>spring-boot-maven-plugin</artifactId>
38 </plugin>
39 </plugins>
40 </build>
41 </project>
src/main/resources/application.properties
server.port=8181 spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080/auth/realms/MyRealm #logging.level.root=DEBUG logging.level.root=INFO logging.file=/tmp/testout.log
src/main/java/com/example/demo/DemoApplication.java
1 package com.example.demo;
2
3 import org.springframework.boot.SpringApplication;
4 import org.springframework.boot.autoconfigure.SpringBootApplication;
5 import org.springframework.web.bind.annotation.GetMapping;
6 import org.springframework.web.bind.annotation.RestController;
7 import org.springframework.security.core.Authentication;
8 import org.springframework.security.core.GrantedAuthority;
9 import org.springframework.security.oauth2.jwt.Jwt;
10
11 @RestController
12 @SpringBootApplication
13 public class DemoApplication {
14
15 public static void main(String[] args) {
16 SpringApplication.run(DemoApplication.class, args);
17 }
18
19
20 @GetMapping("/otherhello")
21 public String otherHello(){
22 return "other hello";
23 }
24
25 @GetMapping("/hello")
26 public String hello(Authentication authentication) {
27 String s="";
28 for(int i=0; i<authentication.getAuthorities().size();i++){
29 GrantedAuthority ga = (GrantedAuthority) authentication.getAuthorities().toArray()[i];
30 s += ga.getAuthority() + " ";
31 }
32 Jwt jwt = (Jwt) authentication.getCredentials();
33
34 Object[] keys = jwt.getClaims().keySet().toArray();
35 String allkeys = "";
36
37 for(int j=0; j< keys.length ;j++){
38 allkeys = allkeys + " " + (String)keys[j] + ":" + jwt.getClaims().get( keys[j] ).toString()+ " ";
39 }
40
41 return "I am authenticated with user " + authentication.getName() + " " + s + " " + authentication.getDetails().toString() + " " + allkeys;
42 }
43
44 }
src/main/java/com/example/demo/SecurityConfiguration.java
1 package com.example.demo;
2
3 import org.springframework.beans.factory.annotation.Autowired;
4 import org.springframework.context.annotation.Bean;
5 import org.springframework.context.annotation.Configuration;
6 import org.springframework.security.authentication.AuthenticationManager;
7 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
8 import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
9 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
10 import org.springframework.security.config.annotation.web.builders.WebSecurity;
11 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
12 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
13 import org.springframework.security.config.http.SessionCreationPolicy;
14 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
15 import org.springframework.security.crypto.password.PasswordEncoder;
16
17 @Configuration
18 @EnableWebSecurity
19 public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
20
21 @Override
22 protected void configure(HttpSecurity http) throws Exception {
23 http.oauth2ResourceServer().jwt();
24 }
25
26 @Override
27 public void configure(WebSecurity web) throws Exception {
28 web.ignoring().antMatchers("/otherhello**").antMatchers("/static**");
29 }
30
31 }
src/main/webapp/static/test2.txt
test2
Invoke endpoint on resource server with access token from keycloak
1 java -jar target/demo-0.0.1-SNAPSHOT.jar
2 curl http://localhost:8181/hello -vvv
3 TOKEN=$(curl -d 'client_id=curl_confidential' -d 'client_secret=6dfe5f84-d115-4d3e-8a56-a0fcf5b2f13e' -d 'username=myuser' -d 'password=mypwd' -d 'grant_type=password' 'http://localhost:8080/auth/realms/MyRealm/protocol/openid-connect/token' | jq -r '.access_token')
4 curl -X GET http://localhost:8181/hello --header "Authorization: Bearer $TOKEN"
5
6 I am authenticated with user d7192f29-ee2f-4079-95f9-a75df61f3973 SCOPE_profile SCOPE_email org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null sub:d7192f29-ee2f-4079-95f9-a75df61f3973 resource_access:{"account":{"roles":["manage-account","manage-account-links","view-profile"]}} email_verified:false iss:http://localhost:8080/auth/realms/MyRealm typ:Bearer preferred_username:myuser aud:[account] acr:1 realm_access:{"roles":["offline_access","uma_authorization","USER"]} azp:curl_confidential scope:profile email exp:2020-06-18T23:01:09Z session_state:a3cc9c25-ae55-492f-be5a-28aafd3a6d3f iat:2020-06-18T22:56:09Z jti:bc4a4a6e-5da5-434b-9a77-cb0a88c64c4c
7
8 curl -X GET http://localhost:8181/otherhello
9 # other hello
10
11 curl -X GET http://localhost:8181/static/test2.txt -v
12 # test2
13
pyjwt
- pip install pyjwt