diff --git a/README.md b/README.md
index 245d368..009045e 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,14 @@
# Spring Boot JWT Authentication example with Spring Security & Spring Data JPA
-For more detail, please visit:
-> [Secure Spring Boot App with Spring Security & JWT Authentication](https://bezkoder.com/spring-boot-jwt-authentication/)
-
-> [For MongoDB](https://bezkoder.com/spring-boot-jwt-auth-mongodb/)
+## User Registration, User Login and Authorization process.
+The diagram shows flow of how we implement User Registration, User Login and Authorization process.
-# Fullstack
-
-> [Spring Boot + Vue.js JWT Authentication](https://bezkoder.com/spring-boot-vue-js-authentication-jwt-spring-security/)
+
-> [Spring Boot + Angular 8 JWT Authentication](https://bezkoder.com/angular-spring-boot-jwt-auth/)
+## Spring Boot Server Architecture with Spring Security
+You can have an overview of our Spring Boot Server with the diagram below:
-> [Spring Boot + React JWT Authentication](https://bezkoder.com/spring-boot-react-jwt-auth/)
+
## Dependency
– If you want to use PostgreSQL:
@@ -25,8 +22,8 @@ For more detail, please visit:
– or MySQL:
```xml
- mysql
- mysql-connector-java
+ com.mysql
+ mysql-connector-j
runtime
```
@@ -50,16 +47,16 @@ bezkoder.app.jwtExpirationMs= 86400000
```
- For MySQL
```
-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
+bezkoder.app.jwtSecret= ======================BezKoder=Spring===========================
+bezkoder.app.jwtExpirationMs=86400000
```
## Run Spring Boot application
```
@@ -72,3 +69,138 @@ 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 with Spring Security & JWT Authentication](https://bezkoder.com/spring-boot-jwt-authentication/)
+
+> [For MongoDB](https://bezkoder.com/spring-boot-jwt-auth-mongodb/)
+
+## Refresh Token
+
+
+
+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/)
+
+> [Spring Boot Repository Unit Test with @DataJpaTest](https://bezkoder.com/spring-boot-unit-test-jpa-repo-datajpatest/)
+
+> [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/)
+
+> [Spring Boot Many To Many example with Spring JPA, Hibernate](https://www.bezkoder.com/jpa-many-to-many/)
+
+> [JPA One To One example with Spring Boot](https://www.bezkoder.com/jpa-one-to-one/)
+
+Deployment:
+> [Deploy Spring Boot App on AWS – Elastic Beanstalk](https://www.bezkoder.com/deploy-spring-boot-aws-eb/)
+
+> [Docker Compose Spring Boot and MySQL example](https://www.bezkoder.com/docker-compose-spring-boot-mysql/)
+
+## Fullstack Authentication
+
+> [Spring Boot + Vue.js JWT Authentication](https://bezkoder.com/spring-boot-vue-js-authentication-jwt-spring-security/)
+
+> [Spring Boot + Angular 8 JWT Authentication](https://bezkoder.com/angular-spring-boot-jwt-auth/)
+
+> [Spring Boot + Angular 10 JWT Authentication](https://bezkoder.com/angular-10-spring-boot-jwt-auth/)
+
+> [Spring Boot + Angular 11 JWT Authentication](https://bezkoder.com/angular-11-spring-boot-jwt-auth/)
+
+> [Spring Boot + Angular 12 JWT Authentication](https://www.bezkoder.com/angular-12-spring-boot-jwt-auth/)
+
+> [Spring Boot + Angular 13 JWT Authentication](https://www.bezkoder.com/angular-13-spring-boot-jwt-auth/)
+
+> [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
+
+> [Vue.js + Spring Boot + H2 Embedded database example](https://www.bezkoder.com/spring-boot-vue-js-crud-example/)
+
+> [Vue.js + Spring Boot + MySQL example](https://www.bezkoder.com/spring-boot-vue-js-mysql/)
+
+> [Vue.js + Spring Boot + PostgreSQL example](https://www.bezkoder.com/spring-boot-vue-js-postgresql/)
+
+> [Angular 8 + Spring Boot + Embedded database example](https://www.bezkoder.com/angular-spring-boot-crud/)
+
+> [Angular 8 + Spring Boot + MySQL example](https://bezkoder.com/angular-spring-boot-crud/)
+
+> [Angular 8 + Spring Boot + PostgreSQL example](https://bezkoder.com/angular-spring-boot-postgresql/)
+
+> [Angular 10 + Spring Boot + MySQL example](https://bezkoder.com/angular-10-spring-boot-crud/)
+
+> [Angular 10 + Spring Boot + PostgreSQL example](https://bezkoder.com/angular-10-spring-boot-postgresql/)
+
+> [Angular 11 + Spring Boot + MySQL example](https://bezkoder.com/angular-11-spring-boot-crud/)
+
+> [Angular 11 + Spring Boot + PostgreSQL example](https://bezkoder.com/angular-11-spring-boot-postgresql/)
+
+> [Angular 12 + Spring Boot + Embedded database example](https://www.bezkoder.com/angular-12-spring-boot-crud/)
+
+> [Angular 12 + Spring Boot + MySQL example](https://www.bezkoder.com/angular-12-spring-boot-mysql/)
+
+> [Angular 12 + Spring Boot + PostgreSQL example](https://www.bezkoder.com/angular-12-spring-boot-postgresql/)
+
+> [Angular 13 + Spring Boot + H2 Embedded Database example](https://www.bezkoder.com/spring-boot-angular-13-crud/)
+
+> [Angular 13 + Spring Boot + MySQL example](https://www.bezkoder.com/spring-boot-angular-13-mysql/)
+
+> [Angular 13 + Spring Boot + PostgreSQL example](https://www.bezkoder.com/spring-boot-angular-13-postgresql/)
+
+> [Angular 14 + Spring Boot + H2 Embedded Database example](https://www.bezkoder.com/spring-boot-angular-14-crud/)
+
+> [Angular 14 + Spring Boot + MySQL example](https://www.bezkoder.com/spring-boot-angular-14-mysql/)
+
+> [Angular 14 + Spring Boot + PostgreSQL example](https://www.bezkoder.com/spring-boot-angular-14-postgresql/)
+
+> [Angular 15 + Spring Boot + H2 Embedded Database example](https://www.bezkoder.com/spring-boot-angular-15-crud/)
+
+> [Angular 15 + Spring Boot + MySQL example](https://www.bezkoder.com/spring-boot-angular-15-mysql/)
+
+> [Angular 15 + Spring Boot + PostgreSQL example](https://www.bezkoder.com/spring-boot-angular-15-postgresql/)
+
+> [Angular 16 + Spring Boot + H2 Embedded Database example](https://www.bezkoder.com/spring-boot-angular-16-crud/)
+
+> [Angular 16 + Spring Boot + MySQL example](https://www.bezkoder.com/spring-boot-angular-16-mysql/)
+
+> [Angular 16 + Spring Boot + PostgreSQL example](https://www.bezkoder.com/spring-boot-angular-16-postgresql/)
+
+> [Angular 17 + Spring Boot + H2 Embedded Database example](https://www.bezkoder.com/spring-boot-angular-17-crud/)
+
+> [Angular 17 + Spring Boot + MySQL example](https://www.bezkoder.com/spring-boot-angular-17-mysql/)
+
+> [Angular 17 + Spring Boot + PostgreSQL example](https://www.bezkoder.com/spring-boot-angular-17-postgresql/)
+
+> [React + Spring Boot + MySQL example](https://bezkoder.com/react-spring-boot-crud/)
+
+> [React + Spring Boot + PostgreSQL example](https://bezkoder.com/spring-boot-react-postgresql/)
+
+> [React + Spring Boot + MongoDB example](https://bezkoder.com/react-spring-boot-mongodb/)
+
+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 048d6d3..23a0aba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.1.8.RELEASE
+ 3.1.0
com.bezkoder
@@ -16,7 +16,7 @@
Demo project for Spring Boot Security - JWT
- 1.8
+ 17
@@ -30,21 +30,40 @@
spring-boot-starter-security
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
org.springframework.boot
spring-boot-starter-web
- org.postgresql
- postgresql
+ com.mysql
+ mysql-connector-j
runtime
io.jsonwebtoken
- jjwt
- 0.9.1
+ jjwt-api
+ 0.11.5
+
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.11.5
+ runtime
+
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.11.5
+ runtime
@@ -52,7 +71,7 @@
spring-boot-starter-test
test
-
+
org.springframework.security
spring-security-test
diff --git a/spring-boot-jwt-authentication-spring-security-architecture.png b/spring-boot-jwt-authentication-spring-security-architecture.png
new file mode 100644
index 0000000..b238cb3
Binary files /dev/null and b/spring-boot-jwt-authentication-spring-security-architecture.png differ
diff --git a/spring-boot-jwt-authentication-spring-security-flow.png b/spring-boot-jwt-authentication-spring-security-flow.png
new file mode 100644
index 0000000..95b5608
Binary files /dev/null and b/spring-boot-jwt-authentication-spring-security-flow.png differ
diff --git a/spring-boot-refresh-token-jwt-example-flow.png b/spring-boot-refresh-token-jwt-example-flow.png
new file mode 100644
index 0000000..5f3d258
Binary files /dev/null and b/spring-boot-refresh-token-jwt-example-flow.png differ
diff --git a/src/main/java/com/bezkoder/springjwt/SpringBootSecurityJwtApplication.java b/src/main/java/com/bezkoder/springjwt/SpringBootSecurityJwtApplication.java
index d13abd7..c723518 100644
--- a/src/main/java/com/bezkoder/springjwt/SpringBootSecurityJwtApplication.java
+++ b/src/main/java/com/bezkoder/springjwt/SpringBootSecurityJwtApplication.java
@@ -7,7 +7,7 @@
public class SpringBootSecurityJwtApplication {
public static void main(String[] args) {
- SpringApplication.run(SpringBootSecurityJwtApplication.class, args);
+ SpringApplication.run(SpringBootSecurityJwtApplication.class, args);
}
}
diff --git a/src/main/java/com/bezkoder/springjwt/controllers/AuthController.java b/src/main/java/com/bezkoder/springjwt/controllers/AuthController.java
index e598702..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;
@@ -36,94 +36,94 @@
@RestController
@RequestMapping("/api/auth")
public class AuthController {
- @Autowired
- AuthenticationManager authenticationManager;
-
- @Autowired
- UserRepository userRepository;
-
- @Autowired
- RoleRepository roleRepository;
-
- @Autowired
- PasswordEncoder encoder;
-
- @Autowired
- JwtUtils jwtUtils;
-
- @PostMapping("/signin")
- public ResponseEntity> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
-
- Authentication authentication = authenticationManager.authenticate(
- new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
-
- SecurityContextHolder.getContext().setAuthentication(authentication);
- String jwt = jwtUtils.generateJwtToken(authentication);
-
- UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
- List roles = userDetails.getAuthorities().stream()
- .map(item -> item.getAuthority())
- .collect(Collectors.toList());
-
- return ResponseEntity.ok(new JwtResponse(jwt,
- userDetails.getId(),
- userDetails.getUsername(),
- userDetails.getEmail(),
- roles));
- }
-
- @PostMapping("/signup")
- public ResponseEntity> registerUser(@Valid @RequestBody SignupRequest signUpRequest) {
- if (userRepository.existsByUsername(signUpRequest.getUsername())) {
- return ResponseEntity
- .badRequest()
- .body(new MessageResponse("Error: Username is already taken!"));
- }
-
- if (userRepository.existsByEmail(signUpRequest.getEmail())) {
- return ResponseEntity
- .badRequest()
- .body(new MessageResponse("Error: Email is already in use!"));
- }
-
- // Create new user's account
- User user = new User(signUpRequest.getUsername(),
- signUpRequest.getEmail(),
- encoder.encode(signUpRequest.getPassword()));
-
- Set strRoles = signUpRequest.getRole();
- Set roles = new HashSet<>();
-
- if (strRoles == null) {
- Role userRole = roleRepository.findByName(ERole.ROLE_USER)
- .orElseThrow(() -> new RuntimeException("Error: Role is not found."));
- roles.add(userRole);
- } else {
- strRoles.forEach(role -> {
- switch (role) {
- case "admin":
- Role adminRole = roleRepository.findByName(ERole.ROLE_ADMIN)
- .orElseThrow(() -> new RuntimeException("Error: Role is not found."));
- roles.add(adminRole);
-
- break;
- case "mod":
- Role modRole = roleRepository.findByName(ERole.ROLE_MODERATOR)
- .orElseThrow(() -> new RuntimeException("Error: Role is not found."));
- roles.add(modRole);
-
- break;
- default:
- Role userRole = roleRepository.findByName(ERole.ROLE_USER)
- .orElseThrow(() -> new RuntimeException("Error: Role is not found."));
- roles.add(userRole);
- }
- });
- }
-
- user.setRoles(roles);
- userRepository.save(user);
-
- return ResponseEntity.ok(new MessageResponse("User registered successfully!"));
- }
+ @Autowired
+ AuthenticationManager authenticationManager;
+
+ @Autowired
+ UserRepository userRepository;
+
+ @Autowired
+ RoleRepository roleRepository;
+
+ @Autowired
+ PasswordEncoder encoder;
+
+ @Autowired
+ JwtUtils jwtUtils;
+
+ @PostMapping("/signin")
+ public ResponseEntity> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
+
+ Authentication authentication = authenticationManager.authenticate(
+ new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
+
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ String jwt = jwtUtils.generateJwtToken(authentication);
+
+ UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
+ List roles = userDetails.getAuthorities().stream()
+ .map(item -> item.getAuthority())
+ .collect(Collectors.toList());
+
+ return ResponseEntity.ok(new JwtResponse(jwt,
+ userDetails.getId(),
+ userDetails.getUsername(),
+ userDetails.getEmail(),
+ roles));
+ }
+
+ @PostMapping("/signup")
+ public ResponseEntity> registerUser(@Valid @RequestBody SignupRequest signUpRequest) {
+ if (userRepository.existsByUsername(signUpRequest.getUsername())) {
+ return ResponseEntity
+ .badRequest()
+ .body(new MessageResponse("Error: Username is already taken!"));
+ }
+
+ if (userRepository.existsByEmail(signUpRequest.getEmail())) {
+ return ResponseEntity
+ .badRequest()
+ .body(new MessageResponse("Error: Email is already in use!"));
+ }
+
+ // Create new user's account
+ User user = new User(signUpRequest.getUsername(),
+ signUpRequest.getEmail(),
+ encoder.encode(signUpRequest.getPassword()));
+
+ Set strRoles = signUpRequest.getRole();
+ Set roles = new HashSet<>();
+
+ if (strRoles == null) {
+ Role userRole = roleRepository.findByName(ERole.ROLE_USER)
+ .orElseThrow(() -> new RuntimeException("Error: Role is not found."));
+ roles.add(userRole);
+ } else {
+ strRoles.forEach(role -> {
+ switch (role) {
+ case "admin":
+ Role adminRole = roleRepository.findByName(ERole.ROLE_ADMIN)
+ .orElseThrow(() -> new RuntimeException("Error: Role is not found."));
+ roles.add(adminRole);
+
+ break;
+ case "mod":
+ Role modRole = roleRepository.findByName(ERole.ROLE_MODERATOR)
+ .orElseThrow(() -> new RuntimeException("Error: Role is not found."));
+ roles.add(modRole);
+
+ break;
+ default:
+ Role userRole = roleRepository.findByName(ERole.ROLE_USER)
+ .orElseThrow(() -> new RuntimeException("Error: Role is not found."));
+ roles.add(userRole);
+ }
+ });
+ }
+
+ user.setRoles(roles);
+ userRepository.save(user);
+
+ return ResponseEntity.ok(new MessageResponse("User registered successfully!"));
+ }
}
diff --git a/src/main/java/com/bezkoder/springjwt/controllers/TestController.java b/src/main/java/com/bezkoder/springjwt/controllers/TestController.java
index 298a7ea..e03b5cb 100644
--- a/src/main/java/com/bezkoder/springjwt/controllers/TestController.java
+++ b/src/main/java/com/bezkoder/springjwt/controllers/TestController.java
@@ -10,26 +10,26 @@
@RestController
@RequestMapping("/api/test")
public class TestController {
- @GetMapping("/all")
- public String allAccess() {
- return "Public Content.";
- }
-
- @GetMapping("/user")
- @PreAuthorize("hasRole('USER') or hasRole('MODERATOR') or hasRole('ADMIN')")
- public String userAccess() {
- return "User Content.";
- }
+ @GetMapping("/all")
+ public String allAccess() {
+ return "Public Content.";
+ }
- @GetMapping("/mod")
- @PreAuthorize("hasRole('MODERATOR')")
- public String moderatorAccess() {
- return "Moderator Board.";
- }
+ @GetMapping("/user")
+ @PreAuthorize("hasRole('USER') or hasRole('MODERATOR') or hasRole('ADMIN')")
+ public String userAccess() {
+ return "User Content.";
+ }
- @GetMapping("/admin")
- @PreAuthorize("hasRole('ADMIN')")
- public String adminAccess() {
- return "Admin Board.";
- }
+ @GetMapping("/mod")
+ @PreAuthorize("hasRole('MODERATOR')")
+ public String moderatorAccess() {
+ return "Moderator Board.";
+ }
+
+ @GetMapping("/admin")
+ @PreAuthorize("hasRole('ADMIN')")
+ public String adminAccess() {
+ return "Admin Board.";
+ }
}
diff --git a/src/main/java/com/bezkoder/springjwt/models/ERole.java b/src/main/java/com/bezkoder/springjwt/models/ERole.java
index 9acf4a4..a113c68 100644
--- a/src/main/java/com/bezkoder/springjwt/models/ERole.java
+++ b/src/main/java/com/bezkoder/springjwt/models/ERole.java
@@ -1,7 +1,7 @@
package com.bezkoder.springjwt.models;
public enum ERole {
- ROLE_USER,
- ROLE_MODERATOR,
- ROLE_ADMIN
+ ROLE_USER,
+ ROLE_MODERATOR,
+ ROLE_ADMIN
}
diff --git a/src/main/java/com/bezkoder/springjwt/models/Role.java b/src/main/java/com/bezkoder/springjwt/models/Role.java
index 44b82ad..8eb847f 100644
--- a/src/main/java/com/bezkoder/springjwt/models/Role.java
+++ b/src/main/java/com/bezkoder/springjwt/models/Role.java
@@ -1,39 +1,39 @@
package com.bezkoder.springjwt.models;
-import javax.persistence.*;
+import jakarta.persistence.*;
@Entity
@Table(name = "roles")
public class Role {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Integer id;
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
- @Enumerated(EnumType.STRING)
- @Column(length = 20)
- private ERole name;
+ @Enumerated(EnumType.STRING)
+ @Column(length = 20)
+ private ERole name;
- public Role() {
+ public Role() {
- }
+ }
- public Role(ERole name) {
- this.name = name;
- }
+ public Role(ERole name) {
+ this.name = name;
+ }
- public Integer getId() {
- return id;
- }
+ public Integer getId() {
+ return id;
+ }
- public void setId(Integer id) {
- this.id = id;
- }
+ public void setId(Integer id) {
+ this.id = id;
+ }
- public ERole getName() {
- return name;
- }
+ public ERole getName() {
+ return name;
+ }
- public void setName(ERole name) {
- this.name = name;
- }
+ public void setName(ERole name) {
+ this.name = name;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/bezkoder/springjwt/models/User.java b/src/main/java/com/bezkoder/springjwt/models/User.java
index 6e3eaa2..2ad0c5d 100644
--- a/src/main/java/com/bezkoder/springjwt/models/User.java
+++ b/src/main/java/com/bezkoder/springjwt/models/User.java
@@ -3,87 +3,87 @@
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",
- uniqueConstraints = {
- @UniqueConstraint(columnNames = "username"),
- @UniqueConstraint(columnNames = "email")
- })
+@Table(name = "users",
+ uniqueConstraints = {
+ @UniqueConstraint(columnNames = "username"),
+ @UniqueConstraint(columnNames = "email")
+ })
public class User {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
-
- @NotBlank
- @Size(max = 20)
- private String username;
-
- @NotBlank
- @Size(max = 50)
- @Email
- private String email;
-
- @NotBlank
- @Size(max = 120)
- private String password;
-
- @ManyToMany(fetch = FetchType.LAZY)
- @JoinTable( name = "user_roles",
- joinColumns = @JoinColumn(name = "user_id"),
- inverseJoinColumns = @JoinColumn(name = "role_id"))
- private Set roles = new HashSet<>();
-
- public User() {
- }
-
- public User(String username, String email, String password) {
- this.username = username;
- this.email = email;
- this.password = password;
- }
-
- public Long getId() {
- return id;
- }
-
- public void setId(Long id) {
- this.id = id;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getEmail() {
- return email;
- }
-
- public void setEmail(String email) {
- this.email = email;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public Set getRoles() {
- return roles;
- }
-
- public void setRoles(Set roles) {
- this.roles = roles;
- }
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @NotBlank
+ @Size(max = 20)
+ private String username;
+
+ @NotBlank
+ @Size(max = 50)
+ @Email
+ private String email;
+
+ @NotBlank
+ @Size(max = 120)
+ private String password;
+
+ @ManyToMany(fetch = FetchType.LAZY)
+ @JoinTable( name = "user_roles",
+ joinColumns = @JoinColumn(name = "user_id"),
+ inverseJoinColumns = @JoinColumn(name = "role_id"))
+ private Set roles = new HashSet<>();
+
+ public User() {
+ }
+
+ public User(String username, String email, String password) {
+ this.username = username;
+ this.email = email;
+ this.password = password;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public Set getRoles() {
+ return roles;
+ }
+
+ public void setRoles(Set roles) {
+ this.roles = roles;
+ }
}
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 e0e7f9f..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,10 +1,10 @@
package com.bezkoder.springjwt.payload.request;
-import javax.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotBlank;
public class LoginRequest {
@NotBlank
- private String username;
+ private String username;
@NotBlank
private String password;
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 515e0a5..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,53 +2,53 @@
import java.util.Set;
-import javax.validation.constraints.*;
-
+import jakarta.validation.constraints.*;
+
public class SignupRequest {
- @NotBlank
- @Size(min = 3, max = 20)
- private String username;
-
- @NotBlank
- @Size(max = 50)
- @Email
- private String email;
-
- private Set role;
-
- @NotBlank
- @Size(min = 6, max = 40)
- private String password;
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getEmail() {
- return email;
- }
-
- public void setEmail(String email) {
- this.email = email;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public Set getRole() {
- return this.role;
- }
-
- public void setRole(Set role) {
- this.role = role;
- }
+ @NotBlank
+ @Size(min = 3, max = 20)
+ private String username;
+
+ @NotBlank
+ @Size(max = 50)
+ @Email
+ private String email;
+
+ private Set role;
+
+ @NotBlank
+ @Size(min = 6, max = 40)
+ private String password;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public Set getRole() {
+ return this.role;
+ }
+
+ public void setRole(Set role) {
+ this.role = role;
+ }
}
diff --git a/src/main/java/com/bezkoder/springjwt/payload/response/JwtResponse.java b/src/main/java/com/bezkoder/springjwt/payload/response/JwtResponse.java
index 35ae5a4..ac387f0 100644
--- a/src/main/java/com/bezkoder/springjwt/payload/response/JwtResponse.java
+++ b/src/main/java/com/bezkoder/springjwt/payload/response/JwtResponse.java
@@ -3,62 +3,62 @@
import java.util.List;
public class JwtResponse {
- private String token;
- private String type = "Bearer";
- private Long id;
- private String username;
- private String email;
- private List roles;
+ private String token;
+ private String type = "Bearer";
+ private Long id;
+ private String username;
+ private String email;
+ private List roles;
- public JwtResponse(String accessToken, Long id, String username, String email, List roles) {
- this.token = accessToken;
- this.id = id;
- this.username = username;
- this.email = email;
- this.roles = roles;
- }
+ public JwtResponse(String accessToken, Long id, String username, String email, List roles) {
+ this.token = accessToken;
+ this.id = id;
+ this.username = username;
+ this.email = email;
+ this.roles = roles;
+ }
- public String getAccessToken() {
- return token;
- }
+ public String getAccessToken() {
+ return token;
+ }
- public void setAccessToken(String accessToken) {
- this.token = accessToken;
- }
+ public void setAccessToken(String accessToken) {
+ this.token = accessToken;
+ }
- public String getTokenType() {
- return type;
- }
+ public String getTokenType() {
+ return type;
+ }
- public void setTokenType(String tokenType) {
- this.type = tokenType;
- }
+ public void setTokenType(String tokenType) {
+ this.type = tokenType;
+ }
- public Long getId() {
- return id;
- }
+ public Long getId() {
+ return id;
+ }
- public void setId(Long id) {
- this.id = id;
- }
+ public void setId(Long id) {
+ this.id = id;
+ }
- public String getEmail() {
- return email;
- }
+ public String getEmail() {
+ return email;
+ }
- public void setEmail(String email) {
- this.email = email;
- }
+ public void setEmail(String email) {
+ this.email = email;
+ }
- public String getUsername() {
- return username;
- }
+ public String getUsername() {
+ return username;
+ }
- public void setUsername(String username) {
- this.username = username;
- }
+ public void setUsername(String username) {
+ this.username = username;
+ }
- public List getRoles() {
- return roles;
- }
+ public List getRoles() {
+ return roles;
+ }
}
diff --git a/src/main/java/com/bezkoder/springjwt/payload/response/MessageResponse.java b/src/main/java/com/bezkoder/springjwt/payload/response/MessageResponse.java
index 4a3a59f..068e179 100644
--- a/src/main/java/com/bezkoder/springjwt/payload/response/MessageResponse.java
+++ b/src/main/java/com/bezkoder/springjwt/payload/response/MessageResponse.java
@@ -1,17 +1,17 @@
package com.bezkoder.springjwt.payload.response;
public class MessageResponse {
- private String message;
+ private String message;
- public MessageResponse(String message) {
- this.message = message;
- }
+ public MessageResponse(String message) {
+ this.message = message;
+ }
- public String getMessage() {
- return message;
- }
+ public String getMessage() {
+ return message;
+ }
- public void setMessage(String message) {
- this.message = message;
- }
+ public void setMessage(String message) {
+ this.message = message;
+ }
}
diff --git a/src/main/java/com/bezkoder/springjwt/repository/RoleRepository.java b/src/main/java/com/bezkoder/springjwt/repository/RoleRepository.java
index 06aa459..a1882d0 100644
--- a/src/main/java/com/bezkoder/springjwt/repository/RoleRepository.java
+++ b/src/main/java/com/bezkoder/springjwt/repository/RoleRepository.java
@@ -10,5 +10,5 @@
@Repository
public interface RoleRepository extends JpaRepository {
- Optional findByName(ERole name);
+ Optional findByName(ERole name);
}
diff --git a/src/main/java/com/bezkoder/springjwt/repository/UserRepository.java b/src/main/java/com/bezkoder/springjwt/repository/UserRepository.java
index 74f2df9..d48a98c 100644
--- a/src/main/java/com/bezkoder/springjwt/repository/UserRepository.java
+++ b/src/main/java/com/bezkoder/springjwt/repository/UserRepository.java
@@ -9,9 +9,9 @@
@Repository
public interface UserRepository extends JpaRepository {
- Optional findByUsername(String username);
+ Optional findByUsername(String username);
- Boolean existsByUsername(String username);
+ Boolean existsByUsername(String username);
- Boolean existsByEmail(String email);
+ Boolean existsByEmail(String email);
}
diff --git a/src/main/java/com/bezkoder/springjwt/security/WebSecurityConfig.java b/src/main/java/com/bezkoder/springjwt/security/WebSecurityConfig.java
index 405cf6b..d7565d1 100644
--- a/src/main/java/com/bezkoder/springjwt/security/WebSecurityConfig.java
+++ b/src/main/java/com/bezkoder/springjwt/security/WebSecurityConfig.java
@@ -4,14 +4,17 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+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.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;
+//import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+//import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.bezkoder.springjwt.security.jwt.AuthEntryPointJwt;
@@ -19,48 +22,80 @@
import com.bezkoder.springjwt.security.services.UserDetailsServiceImpl;
@Configuration
-@EnableWebSecurity
-@EnableGlobalMethodSecurity(
- // securedEnabled = true,
- // jsr250Enabled = true,
- prePostEnabled = true)
-public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
- @Autowired
- UserDetailsServiceImpl userDetailsService;
+@EnableMethodSecurity
+// (securedEnabled = true,
+// jsr250Enabled = true,
+// prePostEnabled = true) // by default
+public class WebSecurityConfig { // extends WebSecurityConfigurerAdapter {
+ @Autowired
+ UserDetailsServiceImpl userDetailsService;
- @Autowired
- private AuthEntryPointJwt unauthorizedHandler;
+ @Autowired
+ private AuthEntryPointJwt unauthorizedHandler;
- @Bean
- public AuthTokenFilter authenticationJwtTokenFilter() {
- return new AuthTokenFilter();
- }
+ @Bean
+ public AuthTokenFilter authenticationJwtTokenFilter() {
+ return new AuthTokenFilter();
+ }
- @Override
- public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
- authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
- }
+// @Override
+// public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
+// authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
+// }
+
+ @Bean
+ public DaoAuthenticationProvider authenticationProvider() {
+ DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
+
+ authProvider.setUserDetailsService(userDetailsService);
+ authProvider.setPasswordEncoder(passwordEncoder());
+
+ return authProvider;
+ }
- @Bean
- @Override
- public AuthenticationManager authenticationManagerBean() throws Exception {
- return super.authenticationManagerBean();
- }
+// @Bean
+// @Override
+// public AuthenticationManager authenticationManagerBean() throws Exception {
+// return super.authenticationManagerBean();
+// }
+
+ @Bean
+ public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
+ return authConfig.getAuthenticationManager();
+ }
- @Bean
- public PasswordEncoder passwordEncoder() {
- return new BCryptPasswordEncoder();
- }
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new BCryptPasswordEncoder();
+ }
- @Override
- protected void configure(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();
+// @Override
+// protected void configure(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.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
+// }
+
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+ 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());
- http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
- }
+ http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
+
+ return http.build();
+ }
}
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 b7e2647..232ba13 100644
--- a/src/main/java/com/bezkoder/springjwt/security/jwt/AuthEntryPointJwt.java
+++ b/src/main/java/com/bezkoder/springjwt/security/jwt/AuthEntryPointJwt.java
@@ -1,27 +1,43 @@
package com.bezkoder.springjwt.security.jwt;
import java.io.IOException;
+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;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
@Component
public class AuthEntryPointJwt implements AuthenticationEntryPoint {
- private static final Logger logger = LoggerFactory.getLogger(AuthEntryPointJwt.class);
+ private static final Logger logger = LoggerFactory.getLogger(AuthEntryPointJwt.class);
+
+ @Override
+ public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
+ throws IOException, ServletException {
+ logger.error("Unauthorized error: {}", authException.getMessage());
+
+ response.setContentType(MediaType.APPLICATION_JSON_VALUE);
+ response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+
+ final Map body = new HashMap<>();
+ body.put("status", HttpServletResponse.SC_UNAUTHORIZED);
+ body.put("error", "Unauthorized");
+ body.put("message", authException.getMessage());
+ body.put("path", request.getServletPath());
- @Override
- public void commence(HttpServletRequest request, HttpServletResponse response,
- AuthenticationException authException) throws IOException, ServletException {
- logger.error("Unauthorized error: {}", authException.getMessage());
- response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error: Unauthorized");
- }
+ final ObjectMapper mapper = new ObjectMapper();
+ mapper.writeValue(response.getOutputStream(), body);
+ }
}
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 4a906a8..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;
@@ -20,43 +20,46 @@
import com.bezkoder.springjwt.security.services.UserDetailsServiceImpl;
public class AuthTokenFilter extends OncePerRequestFilter {
- @Autowired
- private JwtUtils jwtUtils;
+ @Autowired
+ private JwtUtils jwtUtils;
- @Autowired
- private UserDetailsServiceImpl userDetailsService;
+ @Autowired
+ private UserDetailsServiceImpl userDetailsService;
- private static final Logger logger = LoggerFactory.getLogger(AuthTokenFilter.class);
+ private static final Logger logger = LoggerFactory.getLogger(AuthTokenFilter.class);
- @Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
- throws ServletException, IOException {
- try {
- String jwt = parseJwt(request);
- if (jwt != null && jwtUtils.validateJwtToken(jwt)) {
- String username = jwtUtils.getUserNameFromJwtToken(jwt);
+ @Override
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
+ throws ServletException, IOException {
+ try {
+ String jwt = parseJwt(request);
+ if (jwt != null && jwtUtils.validateJwtToken(jwt)) {
+ String username = jwtUtils.getUserNameFromJwtToken(jwt);
- UserDetails userDetails = userDetailsService.loadUserByUsername(username);
- UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
- userDetails, null, userDetails.getAuthorities());
- authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+ UserDetails userDetails = userDetailsService.loadUserByUsername(username);
+ UsernamePasswordAuthenticationToken authentication =
+ new UsernamePasswordAuthenticationToken(
+ userDetails,
+ null,
+ userDetails.getAuthorities());
+ authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
- SecurityContextHolder.getContext().setAuthentication(authentication);
- }
- } catch (Exception e) {
- logger.error("Cannot set user authentication: {}", e);
- }
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ }
+ } catch (Exception e) {
+ logger.error("Cannot set user authentication: {}", e);
+ }
- filterChain.doFilter(request, response);
- }
+ filterChain.doFilter(request, response);
+ }
- private String parseJwt(HttpServletRequest request) {
- String headerAuth = request.getHeader("Authorization");
+ private String parseJwt(HttpServletRequest request) {
+ String headerAuth = request.getHeader("Authorization");
- if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) {
- return headerAuth.substring(7, headerAuth.length());
- }
+ if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) {
+ return headerAuth.substring(7);
+ }
- return null;
- }
+ 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 400b563..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,49 +11,54 @@
import com.bezkoder.springjwt.security.services.UserDetailsImpl;
import io.jsonwebtoken.*;
+import io.jsonwebtoken.io.Decoders;
+import io.jsonwebtoken.security.Keys;
@Component
public class JwtUtils {
- private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);
-
- @Value("${bezkoder.app.jwtSecret}")
- private String jwtSecret;
-
- @Value("${bezkoder.app.jwtExpirationMs}")
- private int jwtExpirationMs;
-
- public String generateJwtToken(Authentication authentication) {
-
- UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
-
- return Jwts.builder()
- .setSubject((userPrincipal.getUsername()))
- .setIssuedAt(new Date())
- .setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
- .signWith(SignatureAlgorithm.HS512, jwtSecret)
- .compact();
- }
-
- public String getUserNameFromJwtToken(String token) {
- return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();
- }
-
- public boolean validateJwtToken(String authToken) {
- try {
- Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(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) {
- logger.error("JWT token is expired: {}", e.getMessage());
- } catch (UnsupportedJwtException e) {
- logger.error("JWT token is unsupported: {}", e.getMessage());
- } catch (IllegalArgumentException e) {
- logger.error("JWT claims string is empty: {}", e.getMessage());
- }
-
- return false;
- }
+ private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);
+
+ @Value("${bezkoder.app.jwtSecret}")
+ private String jwtSecret;
+
+ @Value("${bezkoder.app.jwtExpirationMs}")
+ private int jwtExpirationMs;
+
+ public String generateJwtToken(Authentication authentication) {
+
+ UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
+
+ return Jwts.builder()
+ .setSubject((userPrincipal.getUsername()))
+ .setIssuedAt(new Date())
+ .setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
+ .signWith(key(), SignatureAlgorithm.HS256)
+ .compact();
+ }
+
+ private Key key() {
+ return Keys.hmacShaKeyFor(Decoders.BASE64.decode(jwtSecret));
+ }
+
+ public String getUserNameFromJwtToken(String token) {
+ return Jwts.parserBuilder().setSigningKey(key()).build()
+ .parseClaimsJws(token).getBody().getSubject();
+ }
+
+ public boolean validateJwtToken(String authToken) {
+ try {
+ Jwts.parserBuilder().setSigningKey(key()).build().parse(authToken);
+ return true;
+ } catch (MalformedJwtException e) {
+ logger.error("Invalid JWT token: {}", e.getMessage());
+ } catch (ExpiredJwtException e) {
+ logger.error("JWT token is expired: {}", e.getMessage());
+ } catch (UnsupportedJwtException e) {
+ logger.error("JWT token is unsupported: {}", e.getMessage());
+ } catch (IllegalArgumentException e) {
+ logger.error("JWT claims string is empty: {}", e.getMessage());
+ }
+
+ return false;
+ }
}
diff --git a/src/main/java/com/bezkoder/springjwt/security/services/UserDetailsImpl.java b/src/main/java/com/bezkoder/springjwt/security/services/UserDetailsImpl.java
index fafc5a9..6452f34 100644
--- a/src/main/java/com/bezkoder/springjwt/security/services/UserDetailsImpl.java
+++ b/src/main/java/com/bezkoder/springjwt/security/services/UserDetailsImpl.java
@@ -13,91 +13,91 @@
import com.fasterxml.jackson.annotation.JsonIgnore;
public class UserDetailsImpl implements UserDetails {
- private static final long serialVersionUID = 1L;
-
- private Long id;
-
- private String username;
-
- private String email;
-
- @JsonIgnore
- private String password;
-
- private Collection extends GrantedAuthority> authorities;
-
- public UserDetailsImpl(Long id, String username, String email, String password,
- Collection extends GrantedAuthority> authorities) {
- this.id = id;
- this.username = username;
- this.email = email;
- this.password = password;
- this.authorities = authorities;
- }
-
- public static UserDetailsImpl build(User user) {
- List authorities = user.getRoles().stream()
- .map(role -> new SimpleGrantedAuthority(role.getName().name()))
- .collect(Collectors.toList());
-
- return new UserDetailsImpl(
- user.getId(),
- user.getUsername(),
- user.getEmail(),
- user.getPassword(),
- authorities);
- }
-
- @Override
- public Collection extends GrantedAuthority> getAuthorities() {
- return authorities;
- }
-
- public Long getId() {
- return id;
- }
-
- public String getEmail() {
- return email;
- }
-
- @Override
- public String getPassword() {
- return password;
- }
-
- @Override
- public String getUsername() {
- return username;
- }
-
- @Override
- public boolean isAccountNonExpired() {
- return true;
- }
-
- @Override
- public boolean isAccountNonLocked() {
- return true;
- }
-
- @Override
- public boolean isCredentialsNonExpired() {
- return true;
- }
-
- @Override
- public boolean isEnabled() {
- return true;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o)
- return true;
- if (o == null || getClass() != o.getClass())
- return false;
- UserDetailsImpl user = (UserDetailsImpl) o;
- return Objects.equals(id, user.id);
- }
+ private static final long serialVersionUID = 1L;
+
+ private Long id;
+
+ private String username;
+
+ private String email;
+
+ @JsonIgnore
+ private String password;
+
+ private Collection extends GrantedAuthority> authorities;
+
+ public UserDetailsImpl(Long id, String username, String email, String password,
+ Collection extends GrantedAuthority> authorities) {
+ this.id = id;
+ this.username = username;
+ this.email = email;
+ this.password = password;
+ this.authorities = authorities;
+ }
+
+ public static UserDetailsImpl build(User user) {
+ List authorities = user.getRoles().stream()
+ .map(role -> new SimpleGrantedAuthority(role.getName().name()))
+ .collect(Collectors.toList());
+
+ return new UserDetailsImpl(
+ user.getId(),
+ user.getUsername(),
+ user.getEmail(),
+ user.getPassword(),
+ authorities);
+ }
+
+ @Override
+ public Collection extends GrantedAuthority> getAuthorities() {
+ return authorities;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ @Override
+ public String getPassword() {
+ return password;
+ }
+
+ @Override
+ public String getUsername() {
+ return username;
+ }
+
+ @Override
+ public boolean isAccountNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isAccountNonLocked() {
+ return true;
+ }
+
+ @Override
+ public boolean isCredentialsNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ UserDetailsImpl user = (UserDetailsImpl) o;
+ return Objects.equals(id, user.id);
+ }
}
diff --git a/src/main/java/com/bezkoder/springjwt/security/services/UserDetailsServiceImpl.java b/src/main/java/com/bezkoder/springjwt/security/services/UserDetailsServiceImpl.java
index 9a3ed41..de65d7e 100644
--- a/src/main/java/com/bezkoder/springjwt/security/services/UserDetailsServiceImpl.java
+++ b/src/main/java/com/bezkoder/springjwt/security/services/UserDetailsServiceImpl.java
@@ -12,16 +12,16 @@
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
- @Autowired
- UserRepository userRepository;
+ @Autowired
+ UserRepository userRepository;
- @Override
- @Transactional
- public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
- User user = userRepository.findByUsername(username)
- .orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + username));
+ @Override
+ @Transactional
+ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+ User user = userRepository.findByUsername(username)
+ .orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + username));
- return UserDetailsImpl.build(user);
- }
+ return UserDetailsImpl.build(user);
+ }
}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index eea124f..481d5ed 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,15 +1,10 @@
-## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
-spring.datasource.url= jdbc:postgresql://localhost:5432/testdb
-spring.datasource.username= postgres
-spring.datasource.password= 123
+spring.datasource.url=jdbc:mysql://localhost:3306/testdb_spring?useSSL=false
+spring.datasource.username=root
+spring.datasource.password=123456
-spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation= true
-# The SQL dialect makes Hibernate generate better SQL for the chosen database
-spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.PostgreSQLDialect
-
-# Hibernate ddl auto (create, create-drop, validate, update)
-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
diff --git a/src/test/java/com/bezkoder/springjwt/SpringBootSecurityJwtApplicationTests.java b/src/test/java/com/bezkoder/springjwt/SpringBootSecurityJwtApplicationTests.java
index 60fe0c3..42ffdd0 100644
--- a/src/test/java/com/bezkoder/springjwt/SpringBootSecurityJwtApplicationTests.java
+++ b/src/test/java/com/bezkoder/springjwt/SpringBootSecurityJwtApplicationTests.java
@@ -1,11 +1,8 @@
package com.bezkoder.springjwt;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootSecurityJwtApplicationTests {