From ede7234b54fb414967af284742bbefd6917edb32 Mon Sep 17 00:00:00 2001 From: Do Nhu Vy Date: Sun, 4 Dec 2022 18:50:23 +0700 Subject: [PATCH] Upgrade to Spring Boot 3.0.0 . --- README.md | 11 +- notes/JWT.postman_collection.json | 100 ++++++++++++ pom.xml | 143 +++++++++--------- .../jwt/controllers/AuthController.java | 2 +- .../security/jwt/models/RefreshToken.java | 10 +- .../spring/security/jwt/models/Role.java | 10 +- .../spring/security/jwt/models/User.java | 25 ++- .../jwt/payload/request/LoginRequest.java | 2 +- .../jwt/payload/request/SignupRequest.java | 6 +- .../payload/request/TokenRefreshRequest.java | 3 +- .../jwt/security/WebSecurityConfig.java | 4 +- .../jwt/security/jwt/AuthEntryPointJwt.java | 7 +- .../jwt/security/jwt/AuthTokenFilter.java | 9 +- src/main/resources/application.properties | 2 +- 14 files changed, 238 insertions(+), 96 deletions(-) create mode 100644 notes/JWT.postman_collection.json diff --git a/README.md b/README.md index f2ab7a4..8af568a 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,11 @@ You can have an overview of our Spring Boot Server with the diagram below: Open `src/main/resources/application.properties` ```properties -spring.datasource.url= jdbc:mysql://localhost:3306/testdb?useSSL=false +spring.datasource.url= jdbc:mysql://localhost:3306/testdb_spring?useSSL=false spring.datasource.username= root spring.datasource.password= 123456 -spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect +spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQLDialect spring.jpa.hibernate.ddl-auto= update # App Properties @@ -35,6 +35,10 @@ bezkoder.app.jwtSecret= bezKoderSecretKey bezkoder.app.jwtExpirationMs= 3600000 bezkoder.app.jwtRefreshExpirationMs= 86400000 ``` +## Run MySQL 8 +``` +docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:latest +``` ## Run Spring Boot application ``` @@ -43,6 +47,9 @@ mvn spring-boot:run ## Run following SQL insert statements ``` +create database testdb_spring; +use testdb_spring; + INSERT INTO roles(name) VALUES('ROLE_USER'); INSERT INTO roles(name) VALUES('ROLE_MODERATOR'); INSERT INTO roles(name) VALUES('ROLE_ADMIN'); diff --git a/notes/JWT.postman_collection.json b/notes/JWT.postman_collection.json new file mode 100644 index 0000000..2b16e2e --- /dev/null +++ b/notes/JWT.postman_collection.json @@ -0,0 +1,100 @@ +{ + "info": { + "_postman_id": "d7edbb04-bb72-4a58-aa3a-8539ea5c8bac", + "name": "JWT", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "16859724" + }, + "item": [ + { + "name": "sign_up", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"username\": \"donhuvy\",\r\n \"email\": \"donhuvy@hotmail.com\",\r\n \"password\": \"123456\",\r\n \"role\": [\"ROLE_USER\", \"ROLE_ADMIN\"]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/api/auth/signup", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "auth", + "signup" + ] + } + }, + "response": [] + }, + { + "name": "sign_in", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"username\": \"donhuvy\",\r\n \"password\": \"123456\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/api/auth/signin", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "auth", + "signin" + ] + } + }, + "response": [] + }, + { + "name": "refresh_token", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"refreshToken\": \"89132309-d900-4ab0-8162-f083d4893793\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/api/auth/refreshtoken", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "api", + "auth", + "refreshtoken" + ] + } + }, + "response": [] + } + ] +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 1c03de6..1fab892 100644 --- a/pom.xml +++ b/pom.xml @@ -1,76 +1,83 @@ - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.7.3 - - - com.bezkoder - spring-boot-security-jwt - 0.0.1-SNAPSHOT - spring-boot-security-jwt - Spring Boot, Spring Security: JWT Authentication & Authorization with Refresh Token example + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.0.0 + + + com.bezkoder + spring-boot-security-jwt + 0.0.1-SNAPSHOT + spring-boot-security-jwt + Spring Boot, Spring Security: JWT Authentication & Authorization with Refresh Token example + - - 1.8 - + + 17 + - - - org.springframework.boot - spring-boot-starter-data-jpa - - - - org.springframework.boot - spring-boot-starter-security - - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.boot - spring-boot-starter-validation - + + + org.springframework.boot + spring-boot-starter-data-jpa + - - mysql - mysql-connector-java - runtime - - - - io.jsonwebtoken - jjwt - 0.9.1 - - - - org.springframework.boot - spring-boot-starter-test - test - - - - org.springframework.security - spring-security-test - test - - + + org.springframework.boot + spring-boot-starter-security + - - - - org.springframework.boot - spring-boot-maven-plugin - - - + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-validation + + + + javax.xml.bind + jaxb-api + 2.3.1 + + + + mysql + mysql-connector-java + runtime + + + + io.jsonwebtoken + jjwt + 0.9.1 + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.security + spring-security-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + diff --git a/src/main/java/com/bezkoder/spring/security/jwt/controllers/AuthController.java b/src/main/java/com/bezkoder/spring/security/jwt/controllers/AuthController.java index 62f70aa..dbfa8d3 100644 --- a/src/main/java/com/bezkoder/spring/security/jwt/controllers/AuthController.java +++ b/src/main/java/com/bezkoder/spring/security/jwt/controllers/AuthController.java @@ -5,8 +5,8 @@ import java.util.Set; import java.util.stream.Collectors; -import javax.validation.Valid; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationManager; diff --git a/src/main/java/com/bezkoder/spring/security/jwt/models/RefreshToken.java b/src/main/java/com/bezkoder/spring/security/jwt/models/RefreshToken.java index 1f89bac..1c5c316 100644 --- a/src/main/java/com/bezkoder/spring/security/jwt/models/RefreshToken.java +++ b/src/main/java/com/bezkoder/spring/security/jwt/models/RefreshToken.java @@ -1,8 +1,16 @@ package com.bezkoder.spring.security.jwt.models; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; + import java.time.Instant; -import javax.persistence.*; + @Entity(name = "refreshtoken") public class RefreshToken { diff --git a/src/main/java/com/bezkoder/spring/security/jwt/models/Role.java b/src/main/java/com/bezkoder/spring/security/jwt/models/Role.java index dca406f..cc030a6 100644 --- a/src/main/java/com/bezkoder/spring/security/jwt/models/Role.java +++ b/src/main/java/com/bezkoder/spring/security/jwt/models/Role.java @@ -1,6 +1,14 @@ package com.bezkoder.spring.security.jwt.models; -import javax.persistence.*; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity @Table(name = "roles") diff --git a/src/main/java/com/bezkoder/spring/security/jwt/models/User.java b/src/main/java/com/bezkoder/spring/security/jwt/models/User.java index 0a977b7..003533a 100644 --- a/src/main/java/com/bezkoder/spring/security/jwt/models/User.java +++ b/src/main/java/com/bezkoder/spring/security/jwt/models/User.java @@ -1,15 +1,26 @@ package com.bezkoder.spring.security.jwt.models; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; + import java.util.HashSet; import java.util.Set; -import javax.persistence.*; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; + @Entity -@Table( name = "users", +@Table( name = "users", uniqueConstraints = { @UniqueConstraint(columnNames = "username"), @UniqueConstraint(columnNames = "email") @@ -33,8 +44,8 @@ public class User { private String password; @ManyToMany(fetch = FetchType.LAZY) - @JoinTable( name = "user_roles", - joinColumns = @JoinColumn(name = "user_id"), + @JoinTable( name = "user_roles", + joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id")) private Set roles = new HashSet<>(); diff --git a/src/main/java/com/bezkoder/spring/security/jwt/payload/request/LoginRequest.java b/src/main/java/com/bezkoder/spring/security/jwt/payload/request/LoginRequest.java index 76bdd03..68e0df1 100644 --- a/src/main/java/com/bezkoder/spring/security/jwt/payload/request/LoginRequest.java +++ b/src/main/java/com/bezkoder/spring/security/jwt/payload/request/LoginRequest.java @@ -1,6 +1,6 @@ package com.bezkoder.spring.security.jwt.payload.request; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; public class LoginRequest { @NotBlank diff --git a/src/main/java/com/bezkoder/spring/security/jwt/payload/request/SignupRequest.java b/src/main/java/com/bezkoder/spring/security/jwt/payload/request/SignupRequest.java index 6436415..7c80062 100644 --- a/src/main/java/com/bezkoder/spring/security/jwt/payload/request/SignupRequest.java +++ b/src/main/java/com/bezkoder/spring/security/jwt/payload/request/SignupRequest.java @@ -1,8 +1,10 @@ package com.bezkoder.spring.security.jwt.payload.request; -import java.util.Set; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; -import javax.validation.constraints.*; +import java.util.Set; public class SignupRequest { @NotBlank diff --git a/src/main/java/com/bezkoder/spring/security/jwt/payload/request/TokenRefreshRequest.java b/src/main/java/com/bezkoder/spring/security/jwt/payload/request/TokenRefreshRequest.java index 1bdc867..b293f86 100644 --- a/src/main/java/com/bezkoder/spring/security/jwt/payload/request/TokenRefreshRequest.java +++ b/src/main/java/com/bezkoder/spring/security/jwt/payload/request/TokenRefreshRequest.java @@ -1,6 +1,7 @@ package com.bezkoder.spring.security.jwt.payload.request; -import javax.validation.constraints.NotBlank; + +import jakarta.validation.constraints.NotBlank; public class TokenRefreshRequest { @NotBlank diff --git a/src/main/java/com/bezkoder/spring/security/jwt/security/WebSecurityConfig.java b/src/main/java/com/bezkoder/spring/security/jwt/security/WebSecurityConfig.java index 513093c..2ee1271 100644 --- a/src/main/java/com/bezkoder/spring/security/jwt/security/WebSecurityConfig.java +++ b/src/main/java/com/bezkoder/spring/security/jwt/security/WebSecurityConfig.java @@ -87,8 +87,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.cors().and().csrf().disable() .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() - .authorizeRequests().antMatchers("/api/auth/**").permitAll() - .antMatchers("/api/test/**").permitAll() + .authorizeRequests().requestMatchers("/api/auth/**").permitAll() + .requestMatchers("/api/test/**").permitAll() .anyRequest().authenticated(); http.authenticationProvider(authenticationProvider()); diff --git a/src/main/java/com/bezkoder/spring/security/jwt/security/jwt/AuthEntryPointJwt.java b/src/main/java/com/bezkoder/spring/security/jwt/security/jwt/AuthEntryPointJwt.java index f929736..6ec252c 100644 --- a/src/main/java/com/bezkoder/spring/security/jwt/security/jwt/AuthEntryPointJwt.java +++ b/src/main/java/com/bezkoder/spring/security/jwt/security/jwt/AuthEntryPointJwt.java @@ -4,10 +4,9 @@ import java.util.HashMap; import java.util.Map; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; diff --git a/src/main/java/com/bezkoder/spring/security/jwt/security/jwt/AuthTokenFilter.java b/src/main/java/com/bezkoder/spring/security/jwt/security/jwt/AuthTokenFilter.java index c484414..b305c43 100644 --- a/src/main/java/com/bezkoder/spring/security/jwt/security/jwt/AuthTokenFilter.java +++ b/src/main/java/com/bezkoder/spring/security/jwt/security/jwt/AuthTokenFilter.java @@ -2,11 +2,10 @@ import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index aa2cfad..09e61c2 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -2,7 +2,7 @@ spring.datasource.url= jdbc:mysql://localhost:3306/testdb_spring?useSSL=false spring.datasource.username= root spring.datasource.password= 123456 -spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect +spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQLDialect spring.jpa.hibernate.ddl-auto= update # App Properties