Skip to content

Commit ed5f59a

Browse files
committed
Angular 10 Spring Boot JWT Authentication Example – Angular 6, 8, 9, 10 + Spring Security + MySQL/PostgreSQL
1 parent b9643c6 commit ed5f59a

File tree

22 files changed

+979
-0
lines changed

22 files changed

+979
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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.7.RELEASE</version>
9+
<relativePath/> <!-- lookup parent from repository -->
10+
</parent>
11+
<groupId>com.loizenai</groupId>
12+
<artifactId>SpringBootJwtAuthenticationExamples</artifactId>
13+
<version>1</version>
14+
<name>SpringBootJwtAuthenticationExamples</name>
15+
<description>SpringBootJwtAuthenticationExamples</description>
16+
17+
<properties>
18+
<java.version>1.8</java.version>
19+
</properties>
20+
21+
<dependencies>
22+
<dependency>
23+
<groupId>org.springframework.boot</groupId>
24+
<artifactId>spring-boot-starter-data-jpa</artifactId>
25+
</dependency>
26+
<dependency>
27+
<groupId>org.springframework.boot</groupId>
28+
<artifactId>spring-boot-starter-security</artifactId>
29+
</dependency>
30+
<dependency>
31+
<groupId>org.springframework.boot</groupId>
32+
<artifactId>spring-boot-starter-web</artifactId>
33+
</dependency>
34+
<dependency>
35+
<groupId>mysql</groupId>
36+
<artifactId>mysql-connector-java</artifactId>
37+
<scope>runtime</scope>
38+
</dependency>
39+
40+
<!-- For Working with Json Web Tokens (JWT) -->
41+
<dependency>
42+
<groupId>io.jsonwebtoken</groupId>
43+
<artifactId>jjwt</artifactId>
44+
<version>0.9.0</version>
45+
</dependency>
46+
47+
<dependency>
48+
<groupId>org.springframework.boot</groupId>
49+
<artifactId>spring-boot-starter</artifactId>
50+
</dependency>
51+
52+
<dependency>
53+
<groupId>org.springframework.boot</groupId>
54+
<artifactId>spring-boot-starter-test</artifactId>
55+
<scope>test</scope>
56+
<exclusions>
57+
<exclusion>
58+
<groupId>org.junit.vintage</groupId>
59+
<artifactId>junit-vintage-engine</artifactId>
60+
</exclusion>
61+
</exclusions>
62+
</dependency>
63+
</dependencies>
64+
65+
<build>
66+
<plugins>
67+
<plugin>
68+
<groupId>org.springframework.boot</groupId>
69+
<artifactId>spring-boot-maven-plugin</artifactId>
70+
</plugin>
71+
</plugins>
72+
</build>
73+
74+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.loizenai.jwtauthentication;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication
7+
public class SpringBootJwtAuthenticationExamplesApplication {
8+
9+
public static void main(String[] args) {
10+
SpringApplication.run(SpringBootJwtAuthenticationExamplesApplication.class, args);
11+
}
12+
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package com.loizenai.jwtauthentication.controller;
2+
3+
import java.util.HashSet;
4+
import java.util.Set;
5+
6+
import javax.validation.Valid;
7+
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.http.HttpStatus;
10+
import org.springframework.http.ResponseEntity;
11+
import org.springframework.security.authentication.AuthenticationManager;
12+
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
13+
import org.springframework.security.core.Authentication;
14+
import org.springframework.security.core.context.SecurityContextHolder;
15+
import org.springframework.security.core.userdetails.UserDetails;
16+
import org.springframework.security.crypto.password.PasswordEncoder;
17+
import org.springframework.web.bind.annotation.CrossOrigin;
18+
import org.springframework.web.bind.annotation.PostMapping;
19+
import org.springframework.web.bind.annotation.RequestBody;
20+
import org.springframework.web.bind.annotation.RequestMapping;
21+
import org.springframework.web.bind.annotation.RestController;
22+
23+
import com.loizenai.jwtauthentication.message.request.LoginForm;
24+
import com.loizenai.jwtauthentication.message.request.SignUpForm;
25+
import com.loizenai.jwtauthentication.message.response.JwtResponse;
26+
import com.loizenai.jwtauthentication.message.response.ResponseMessage;
27+
import com.loizenai.jwtauthentication.model.Role;
28+
import com.loizenai.jwtauthentication.model.RoleName;
29+
import com.loizenai.jwtauthentication.model.User;
30+
import com.loizenai.jwtauthentication.repository.RoleRepository;
31+
import com.loizenai.jwtauthentication.repository.UserRepository;
32+
import com.loizenai.jwtauthentication.security.jwt.JwtProvider;
33+
34+
@CrossOrigin(origins = "*", maxAge = 3600)
35+
@RestController
36+
@RequestMapping("/api/auth")
37+
public class AuthRestAPIs {
38+
39+
@Autowired
40+
AuthenticationManager authenticationManager;
41+
42+
@Autowired
43+
UserRepository userRepository;
44+
45+
@Autowired
46+
RoleRepository roleRepository;
47+
48+
@Autowired
49+
PasswordEncoder encoder;
50+
51+
@Autowired
52+
JwtProvider jwtProvider;
53+
54+
@PostMapping("/signin")
55+
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginForm loginRequest) {
56+
57+
Authentication authentication = authenticationManager.authenticate(
58+
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
59+
60+
SecurityContextHolder.getContext().setAuthentication(authentication);
61+
62+
String jwt = jwtProvider.generateJwtToken(authentication);
63+
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
64+
65+
return ResponseEntity.ok(new JwtResponse(jwt, userDetails.getUsername(), userDetails.getAuthorities()));
66+
}
67+
68+
@PostMapping("/signup")
69+
public ResponseEntity<?> registerUser(@Valid @RequestBody SignUpForm signUpRequest) {
70+
if (userRepository.existsByUsername(signUpRequest.getUsername())) {
71+
return new ResponseEntity<>(new ResponseMessage("Fail -> Username is already taken!"),
72+
HttpStatus.BAD_REQUEST);
73+
}
74+
75+
if (userRepository.existsByEmail(signUpRequest.getEmail())) {
76+
return new ResponseEntity<>(new ResponseMessage("Fail -> Email is already in use!"),
77+
HttpStatus.BAD_REQUEST);
78+
}
79+
80+
// Creating user's account
81+
User user = new User(signUpRequest.getName(), signUpRequest.getUsername(), signUpRequest.getEmail(),
82+
encoder.encode(signUpRequest.getPassword()));
83+
84+
Set<String> strRoles = signUpRequest.getRole();
85+
Set<Role> roles = new HashSet<>();
86+
87+
strRoles.forEach(role -> {
88+
switch (role) {
89+
case "admin":
90+
Role adminRole = roleRepository.findByName(RoleName.ROLE_ADMIN)
91+
.orElseThrow(() -> new RuntimeException("Fail! -> Cause: User Role not find."));
92+
roles.add(adminRole);
93+
94+
break;
95+
case "pm":
96+
Role pmRole = roleRepository.findByName(RoleName.ROLE_PM)
97+
.orElseThrow(() -> new RuntimeException("Fail! -> Cause: User Role not find."));
98+
roles.add(pmRole);
99+
100+
break;
101+
default:
102+
Role userRole = roleRepository.findByName(RoleName.ROLE_USER)
103+
.orElseThrow(() -> new RuntimeException("Fail! -> Cause: User Role not find."));
104+
roles.add(userRole);
105+
}
106+
});
107+
108+
user.setRoles(roles);
109+
userRepository.save(user);
110+
111+
return new ResponseEntity<>(new ResponseMessage("User registered successfully!"), HttpStatus.OK);
112+
}
113+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.loizenai.jwtauthentication.controller;
2+
3+
import org.springframework.security.access.prepost.PreAuthorize;
4+
import org.springframework.web.bind.annotation.CrossOrigin;
5+
import org.springframework.web.bind.annotation.GetMapping;
6+
import org.springframework.web.bind.annotation.RestController;
7+
8+
@CrossOrigin(origins = "*", maxAge = 3600)
9+
@RestController
10+
public class TestRestAPIs {
11+
12+
@GetMapping("/api/test/user")
13+
@PreAuthorize("hasRole('USER') or hasRole('ADMIN')")
14+
public String userAccess() {
15+
return ">>> User Contents!";
16+
}
17+
18+
@GetMapping("/api/test/pm")
19+
@PreAuthorize("hasRole('PM') or hasRole('ADMIN')")
20+
public String projectManagementAccess() {
21+
return ">>> Project Management Board";
22+
}
23+
24+
@GetMapping("/api/test/admin")
25+
@PreAuthorize("hasRole('ADMIN')")
26+
public String adminAccess() {
27+
return ">>> Admin Contents";
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.loizenai.jwtauthentication.message.request;
2+
3+
import javax.validation.constraints.NotBlank;
4+
import javax.validation.constraints.Size;
5+
6+
public class LoginForm {
7+
@NotBlank
8+
@Size(min=3, max = 60)
9+
private String username;
10+
11+
@NotBlank
12+
@Size(min = 6, max = 40)
13+
private String password;
14+
15+
public String getUsername() {
16+
return username;
17+
}
18+
19+
public void setUsername(String username) {
20+
this.username = username;
21+
}
22+
23+
public String getPassword() {
24+
return password;
25+
}
26+
27+
public void setPassword(String password) {
28+
this.password = password;
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.loizenai.jwtauthentication.message.request;
2+
3+
import java.util.Set;
4+
5+
import javax.validation.constraints.*;
6+
7+
public class SignUpForm {
8+
@NotBlank
9+
@Size(min = 3, max = 50)
10+
private String name;
11+
12+
@NotBlank
13+
@Size(min = 3, max = 50)
14+
private String username;
15+
16+
@NotBlank
17+
@Size(max = 60)
18+
@Email
19+
private String email;
20+
21+
private Set<String> role;
22+
23+
@NotBlank
24+
@Size(min = 6, max = 40)
25+
private String password;
26+
27+
public String getName() {
28+
return name;
29+
}
30+
31+
public void setName(String name) {
32+
this.name = name;
33+
}
34+
35+
public String getUsername() {
36+
return username;
37+
}
38+
39+
public void setUsername(String username) {
40+
this.username = username;
41+
}
42+
43+
public String getEmail() {
44+
return email;
45+
}
46+
47+
public void setEmail(String email) {
48+
this.email = email;
49+
}
50+
51+
public String getPassword() {
52+
return password;
53+
}
54+
55+
public void setPassword(String password) {
56+
this.password = password;
57+
}
58+
59+
public Set<String> getRole() {
60+
return this.role;
61+
}
62+
63+
public void setRole(Set<String> role) {
64+
this.role = role;
65+
}
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.loizenai.jwtauthentication.message.response;
2+
3+
import java.util.Collection;
4+
5+
import org.springframework.security.core.GrantedAuthority;
6+
7+
public class JwtResponse {
8+
private String token;
9+
private String type = "Bearer";
10+
private String username;
11+
private Collection<? extends GrantedAuthority> authorities;
12+
13+
public JwtResponse(String accessToken, String username, Collection<? extends GrantedAuthority> authorities) {
14+
this.token = accessToken;
15+
this.username = username;
16+
this.authorities = authorities;
17+
}
18+
19+
public String getAccessToken() {
20+
return token;
21+
}
22+
23+
public void setAccessToken(String accessToken) {
24+
this.token = accessToken;
25+
}
26+
27+
public String getTokenType() {
28+
return type;
29+
}
30+
31+
public void setTokenType(String tokenType) {
32+
this.type = tokenType;
33+
}
34+
35+
public String getUsername() {
36+
return username;
37+
}
38+
39+
public void setUsername(String username) {
40+
this.username = username;
41+
}
42+
43+
public Collection<? extends GrantedAuthority> getAuthorities() {
44+
return authorities;
45+
}
46+
}

0 commit comments

Comments
 (0)