diff --git a/README.md b/README.md
index d0d856a..009045e 100644
--- a/README.md
+++ b/README.md
@@ -10,8 +10,68 @@ You can have an overview of our Spring Boot Server with the diagram below:

+## Dependency
+– If you want to use PostgreSQL:
+```xml
+
+ org.postgresql
+ postgresql
+ runtime
+
+```
+– or MySQL:
+```xml
+
+ com.mysql
+ mysql-connector-j
+ runtime
+
+```
+## Configure Spring Datasource, JPA, App properties
+Open `src/main/resources/application.properties`
+- For PostgreSQL:
+```
+spring.datasource.url= jdbc:postgresql://localhost:5432/testdb
+spring.datasource.username= postgres
+spring.datasource.password= 123
+
+spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation= true
+spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.PostgreSQLDialect
+
+# Hibernate ddl auto (create, create-drop, validate, update)
+spring.jpa.hibernate.ddl-auto= update
+
+# App Properties
+bezkoder.app.jwtSecret= bezKoderSecretKey
+bezkoder.app.jwtExpirationMs= 86400000
+```
+- For MySQL
+```
+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.MySQLDialect
+spring.jpa.hibernate.ddl-auto=update
+
+# App Properties
+bezkoder.app.jwtSecret= ======================BezKoder=Spring===========================
+bezkoder.app.jwtExpirationMs=86400000
+```
+## Run Spring Boot application
+```
+mvn spring-boot:run
+```
+
+## Run following SQL insert statements
+```
+INSERT INTO roles(name) VALUES('ROLE_USER');
+INSERT INTO roles(name) VALUES('ROLE_MODERATOR');
+INSERT INTO roles(name) VALUES('ROLE_ADMIN');
+```
+
For more detail, please visit:
-> [Secure Spring Boot App with Spring Security & JWT Authentication](https://bezkoder.com/spring-boot-jwt-authentication/)
+> [Secure Spring Boot with Spring Security & JWT Authentication](https://bezkoder.com/spring-boot-jwt-authentication/)
> [For MongoDB](https://bezkoder.com/spring-boot-jwt-auth-mongodb/)
@@ -22,6 +82,8 @@ For more detail, please visit:
For instruction: [Spring Boot Refresh Token with JWT example](https://bezkoder.com/spring-boot-refresh-token-jwt/)
## More Practice:
+> [Spring Boot JWT Authentication example using HttpOnly Cookie](https://www.bezkoder.com/spring-boot-login-example-mysql/)
+
> [Spring Boot File upload example with Multipart File](https://bezkoder.com/spring-boot-file-upload/)
> [Exception handling: @RestControllerAdvice example in Spring Boot](https://bezkoder.com/spring-boot-restcontrolleradvice/)
@@ -30,6 +92,12 @@ For instruction: [Spring Boot Refresh Token with JWT example](https://bezkoder.c
> [Spring Boot Pagination & Sorting example](https://www.bezkoder.com/spring-boot-pagination-sorting-example/)
+> Validation: [Spring Boot Validate Request Body](https://www.bezkoder.com/spring-boot-validate-request-body/)
+
+> Documentation: [Spring Boot and Swagger 3 example](https://www.bezkoder.com/spring-boot-swagger-3/)
+
+> Caching: [Spring Boot Redis Cache example](https://www.bezkoder.com/spring-boot-redis-cache-example/)
+
Associations:
> [Spring Boot One To Many example with Spring JPA, Hibernate](https://www.bezkoder.com/jpa-one-to-many/)
@@ -58,6 +126,12 @@ Deployment:
> [Spring Boot + Angular 14 JWT Authentication](https://www.bezkoder.com/angular-14-spring-boot-jwt-auth/)
+> [Spring Boot + Angular 15 JWT Authentication](https://www.bezkoder.com/angular-15-spring-boot-jwt-auth/)
+
+> [Spring Boot + Angular 16 JWT Authentication](https://www.bezkoder.com/angular-16-spring-boot-jwt-auth/)
+
+> [Spring Boot + Angular 17 JWT Authentication](https://www.bezkoder.com/angular-17-spring-boot-jwt-auth/)
+
> [Spring Boot + React JWT Authentication](https://bezkoder.com/spring-boot-react-jwt-auth/)
## Fullstack CRUD App
@@ -100,75 +174,33 @@ Deployment:
> [Angular 14 + Spring Boot + PostgreSQL example](https://www.bezkoder.com/spring-boot-angular-14-postgresql/)
-> [React + Spring Boot + MySQL example](https://bezkoder.com/react-spring-boot-crud/)
+> [Angular 15 + Spring Boot + H2 Embedded Database example](https://www.bezkoder.com/spring-boot-angular-15-crud/)
-> [React + Spring Boot + PostgreSQL example](https://bezkoder.com/spring-boot-react-postgresql/)
+> [Angular 15 + Spring Boot + MySQL example](https://www.bezkoder.com/spring-boot-angular-15-mysql/)
-> [React + Spring Boot + MongoDB example](https://bezkoder.com/react-spring-boot-mongodb/)
+> [Angular 15 + Spring Boot + PostgreSQL example](https://www.bezkoder.com/spring-boot-angular-15-postgresql/)
-Run both Back-end & Front-end in one place:
-> [Integrate Angular with Spring Boot Rest API](https://bezkoder.com/integrate-angular-spring-boot/)
+> [Angular 16 + Spring Boot + H2 Embedded Database example](https://www.bezkoder.com/spring-boot-angular-16-crud/)
-> [Integrate React.js with Spring Boot Rest API](https://bezkoder.com/integrate-reactjs-spring-boot/)
+> [Angular 16 + Spring Boot + MySQL example](https://www.bezkoder.com/spring-boot-angular-16-mysql/)
-> [Integrate Vue.js with Spring Boot Rest API](https://bezkoder.com/integrate-vue-spring-boot/)
+> [Angular 16 + Spring Boot + PostgreSQL example](https://www.bezkoder.com/spring-boot-angular-16-postgresql/)
-## Dependency
-– If you want to use PostgreSQL:
-```xml
-
- org.postgresql
- postgresql
- runtime
-
-```
-– or MySQL:
-```xml
-
- mysql
- mysql-connector-java
- runtime
-
-```
-## Configure Spring Datasource, JPA, App properties
-Open `src/main/resources/application.properties`
-- For PostgreSQL:
-```
-spring.datasource.url= jdbc:postgresql://localhost:5432/testdb
-spring.datasource.username= postgres
-spring.datasource.password= 123
+> [Angular 17 + Spring Boot + H2 Embedded Database example](https://www.bezkoder.com/spring-boot-angular-17-crud/)
-spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation= true
-spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.PostgreSQLDialect
+> [Angular 17 + Spring Boot + MySQL example](https://www.bezkoder.com/spring-boot-angular-17-mysql/)
-# Hibernate ddl auto (create, create-drop, validate, update)
-spring.jpa.hibernate.ddl-auto= update
+> [Angular 17 + Spring Boot + PostgreSQL example](https://www.bezkoder.com/spring-boot-angular-17-postgresql/)
-# App Properties
-bezkoder.app.jwtSecret= bezKoderSecretKey
-bezkoder.app.jwtExpirationMs= 86400000
-```
-- For MySQL
-```
-spring.datasource.url= jdbc:mysql://localhost:3306/testdb?useSSL=false
-spring.datasource.username= root
-spring.datasource.password= 123456
+> [React + Spring Boot + MySQL example](https://bezkoder.com/react-spring-boot-crud/)
-spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect
-spring.jpa.hibernate.ddl-auto= update
+> [React + Spring Boot + PostgreSQL example](https://bezkoder.com/spring-boot-react-postgresql/)
-# App Properties
-bezkoder.app.jwtSecret= bezKoderSecretKey
-bezkoder.app.jwtExpirationMs= 86400000
-```
-## Run Spring Boot application
-```
-mvn spring-boot:run
-```
+> [React + Spring Boot + MongoDB example](https://bezkoder.com/react-spring-boot-mongodb/)
-## Run following SQL insert statements
-```
-INSERT INTO roles(name) VALUES('ROLE_USER');
-INSERT INTO roles(name) VALUES('ROLE_MODERATOR');
-INSERT INTO roles(name) VALUES('ROLE_ADMIN');
-```
+Run both Back-end & Front-end in one place:
+> [Integrate Angular with Spring Boot Rest API](https://bezkoder.com/integrate-angular-spring-boot/)
+
+> [Integrate React.js with Spring Boot Rest API](https://bezkoder.com/integrate-reactjs-spring-boot/)
+
+> [Integrate Vue.js with Spring Boot Rest API](https://bezkoder.com/integrate-vue-spring-boot/)
diff --git a/pom.xml b/pom.xml
index b39061d..23a0aba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.7.3
+ 3.1.0
com.bezkoder
@@ -16,7 +16,7 @@
Demo project for Spring Boot Security - JWT
- 1.8
+ 17
@@ -29,10 +29,10 @@
org.springframework.boot
spring-boot-starter-security
-
+
- org.springframework.boot
- spring-boot-starter-validation
+ org.springframework.boot
+ spring-boot-starter-validation
@@ -41,15 +41,29 @@
- mysql
- mysql-connector-java
+ com.mysql
+ mysql-connector-j
+ runtime
+
+
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.11.5
+
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.11.5
runtime
io.jsonwebtoken
- jjwt
- 0.9.1
+ jjwt-jackson
+ 0.11.5
+ runtime
diff --git a/src/main/java/com/bezkoder/springjwt/controllers/AuthController.java b/src/main/java/com/bezkoder/springjwt/controllers/AuthController.java
index 4287ba1..eb54879 100644
--- a/src/main/java/com/bezkoder/springjwt/controllers/AuthController.java
+++ b/src/main/java/com/bezkoder/springjwt/controllers/AuthController.java
@@ -5,7 +5,7 @@
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;
diff --git a/src/main/java/com/bezkoder/springjwt/models/Role.java b/src/main/java/com/bezkoder/springjwt/models/Role.java
index abf816e..8eb847f 100644
--- a/src/main/java/com/bezkoder/springjwt/models/Role.java
+++ b/src/main/java/com/bezkoder/springjwt/models/Role.java
@@ -1,6 +1,6 @@
package com.bezkoder.springjwt.models;
-import javax.persistence.*;
+import jakarta.persistence.*;
@Entity
@Table(name = "roles")
diff --git a/src/main/java/com/bezkoder/springjwt/models/User.java b/src/main/java/com/bezkoder/springjwt/models/User.java
index 9f03ab1..2ad0c5d 100644
--- a/src/main/java/com/bezkoder/springjwt/models/User.java
+++ b/src/main/java/com/bezkoder/springjwt/models/User.java
@@ -3,10 +3,10 @@
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;
+import jakarta.persistence.*;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Size;
@Entity
@Table(name = "users",
diff --git a/src/main/java/com/bezkoder/springjwt/payload/request/LoginRequest.java b/src/main/java/com/bezkoder/springjwt/payload/request/LoginRequest.java
index 8b6bedf..de32475 100644
--- a/src/main/java/com/bezkoder/springjwt/payload/request/LoginRequest.java
+++ b/src/main/java/com/bezkoder/springjwt/payload/request/LoginRequest.java
@@ -1,6 +1,6 @@
package com.bezkoder.springjwt.payload.request;
-import javax.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotBlank;
public class LoginRequest {
@NotBlank
diff --git a/src/main/java/com/bezkoder/springjwt/payload/request/SignupRequest.java b/src/main/java/com/bezkoder/springjwt/payload/request/SignupRequest.java
index 899f199..ccbb562 100644
--- a/src/main/java/com/bezkoder/springjwt/payload/request/SignupRequest.java
+++ b/src/main/java/com/bezkoder/springjwt/payload/request/SignupRequest.java
@@ -2,7 +2,7 @@
import java.util.Set;
-import javax.validation.constraints.*;
+import jakarta.validation.constraints.*;
public class SignupRequest {
@NotBlank
diff --git a/src/main/java/com/bezkoder/springjwt/security/WebSecurityConfig.java b/src/main/java/com/bezkoder/springjwt/security/WebSecurityConfig.java
index 3114f6b..d7565d1 100644
--- a/src/main/java/com/bezkoder/springjwt/security/WebSecurityConfig.java
+++ b/src/main/java/com/bezkoder/springjwt/security/WebSecurityConfig.java
@@ -7,7 +7,7 @@
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
//import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
-import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
//import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
//import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@@ -22,10 +22,10 @@
import com.bezkoder.springjwt.security.services.UserDetailsServiceImpl;
@Configuration
-@EnableGlobalMethodSecurity(
- // securedEnabled = true,
- // jsr250Enabled = true,
- prePostEnabled = true)
+@EnableMethodSecurity
+// (securedEnabled = true,
+// jsr250Enabled = true,
+// prePostEnabled = true) // by default
public class WebSecurityConfig { // extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsServiceImpl userDetailsService;
@@ -83,12 +83,14 @@ public PasswordEncoder passwordEncoder() {
@Bean
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()
- .anyRequest().authenticated();
+ http.csrf(csrf -> csrf.disable())
+ .exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
+ .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
+ .authorizeHttpRequests(auth ->
+ auth.requestMatchers("/api/auth/**").permitAll()
+ .requestMatchers("/api/test/**").permitAll()
+ .anyRequest().authenticated()
+ );
http.authenticationProvider(authenticationProvider());
diff --git a/src/main/java/com/bezkoder/springjwt/security/jwt/AuthEntryPointJwt.java b/src/main/java/com/bezkoder/springjwt/security/jwt/AuthEntryPointJwt.java
index 903f6a8..232ba13 100644
--- a/src/main/java/com/bezkoder/springjwt/security/jwt/AuthEntryPointJwt.java
+++ b/src/main/java/com/bezkoder/springjwt/security/jwt/AuthEntryPointJwt.java
@@ -4,9 +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;
diff --git a/src/main/java/com/bezkoder/springjwt/security/jwt/AuthTokenFilter.java b/src/main/java/com/bezkoder/springjwt/security/jwt/AuthTokenFilter.java
index 2b3b6d3..f2e31ef 100644
--- a/src/main/java/com/bezkoder/springjwt/security/jwt/AuthTokenFilter.java
+++ b/src/main/java/com/bezkoder/springjwt/security/jwt/AuthTokenFilter.java
@@ -2,10 +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;
@@ -57,7 +57,7 @@ private String parseJwt(HttpServletRequest request) {
String headerAuth = request.getHeader("Authorization");
if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) {
- return headerAuth.substring(7, headerAuth.length());
+ return headerAuth.substring(7);
}
return null;
diff --git a/src/main/java/com/bezkoder/springjwt/security/jwt/JwtUtils.java b/src/main/java/com/bezkoder/springjwt/security/jwt/JwtUtils.java
index 00c8157..a031392 100644
--- a/src/main/java/com/bezkoder/springjwt/security/jwt/JwtUtils.java
+++ b/src/main/java/com/bezkoder/springjwt/security/jwt/JwtUtils.java
@@ -1,5 +1,6 @@
package com.bezkoder.springjwt.security.jwt;
+import java.security.Key;
import java.util.Date;
import org.slf4j.Logger;
@@ -10,6 +11,8 @@
import com.bezkoder.springjwt.security.services.UserDetailsImpl;
import io.jsonwebtoken.*;
+import io.jsonwebtoken.io.Decoders;
+import io.jsonwebtoken.security.Keys;
@Component
public class JwtUtils {
@@ -29,20 +32,23 @@ public String generateJwtToken(Authentication authentication) {
.setSubject((userPrincipal.getUsername()))
.setIssuedAt(new Date())
.setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
- .signWith(SignatureAlgorithm.HS512, jwtSecret)
+ .signWith(key(), SignatureAlgorithm.HS256)
.compact();
}
+
+ private Key key() {
+ return Keys.hmacShaKeyFor(Decoders.BASE64.decode(jwtSecret));
+ }
public String getUserNameFromJwtToken(String token) {
- return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();
+ return Jwts.parserBuilder().setSigningKey(key()).build()
+ .parseClaimsJws(token).getBody().getSubject();
}
public boolean validateJwtToken(String authToken) {
try {
- Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
+ Jwts.parserBuilder().setSigningKey(key()).build().parse(authToken);
return true;
- } catch (SignatureException e) {
- logger.error("Invalid JWT signature: {}", e.getMessage());
} catch (MalformedJwtException e) {
logger.error("Invalid JWT token: {}", e.getMessage());
} catch (ExpiredJwtException e) {
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index d02fe7a..481d5ed 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,10 +1,10 @@
-spring.datasource.url= jdbc:mysql://localhost:3306/testdb?useSSL=false
-spring.datasource.username= root
-spring.datasource.password= 123456
+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.hibernate.ddl-auto= update
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
+spring.jpa.hibernate.ddl-auto=update
# App Properties
-bezkoder.app.jwtSecret= bezKoderSecretKey
-bezkoder.app.jwtExpirationMs= 86400000
\ No newline at end of file
+bezkoder.app.jwtSecret= ======================BezKoder=Spring===========================
+bezkoder.app.jwtExpirationMs=86400000
\ No newline at end of file