Skip to content

Commit cbd02d6

Browse files
Merge pull request #16 from hamzanassour/master
Code Refactoring & Redirecting User to login page if it is not authenticated
2 parents 1569281 + c5b9c17 commit cbd02d6

File tree

6 files changed

+106
-88
lines changed

6 files changed

+106
-88
lines changed

spring-boot-vuejs-jwt-auth/Spring-Boot-API/src/main/java/com/howtodoinjava/app/security/config/SecurityConfig.java

Lines changed: 19 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@
33

44
import com.howtodoinjava.app.security.filter.JwtTokenFilter;
55
import com.howtodoinjava.app.security.repo.UserRepository;
6-
import com.howtodoinjava.app.security.utils.JwtAuthenticationEntryPoint;
76
import jakarta.servlet.http.HttpServletResponse;
87
import lombok.RequiredArgsConstructor;
98
import org.springframework.beans.factory.annotation.Autowired;
109
import org.springframework.context.annotation.Bean;
1110
import org.springframework.context.annotation.Configuration;
1211

13-
import org.springframework.http.HttpMethod;
12+
import org.springframework.context.annotation.Lazy;
1413
import org.springframework.security.authentication.AuthenticationManager;
1514

1615
import org.springframework.security.authentication.AuthenticationProvider;
@@ -19,48 +18,27 @@
1918
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
2019
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
2120
import org.springframework.security.config.http.SessionCreationPolicy;
22-
import org.springframework.security.core.userdetails.UserDetails;
2321
import org.springframework.security.core.userdetails.UserDetailsService;
24-
import org.springframework.security.core.userdetails.UsernameNotFoundException;
2522
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
2623
import org.springframework.security.crypto.password.PasswordEncoder;
2724
import org.springframework.security.web.SecurityFilterChain;
2825
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
29-
import org.springframework.web.cors.CorsConfiguration;
30-
import org.springframework.web.cors.CorsConfigurationSource;
31-
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
26+
3227

3328
@EnableWebSecurity
3429
@Configuration
3530
@RequiredArgsConstructor
3631
public class SecurityConfig {
3732

3833
private final JwtTokenFilter jwtAuthenticationFilter;
39-
private final AuthenticationProvider authenticationProvider;
40-
private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
34+
private final UserDetailsService userDetailsService ;
4135

42-
@Autowired
43-
private UserRepository userRepository;
4436

45-
@Bean
46-
UserDetailsService userDetailsService() {
47-
return new UserDetailsService() {
48-
@Override
49-
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
50-
try {
51-
return userRepository.findByUsername(username)
52-
.orElseThrow(() -> new Exception("user Not found hahahah "));
53-
} catch (Exception e) {
54-
throw new RuntimeException(e);
55-
}
56-
}
57-
};
58-
}
5937

6038
@Bean
6139
public AuthenticationProvider authenticationProvider() {
6240
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
63-
daoAuthenticationProvider.setUserDetailsService(userDetailsService());
41+
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
6442
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
6543
return daoAuthenticationProvider;
6644
}
@@ -78,25 +56,25 @@ AuthenticationManager authenticationManager(
7856

7957
@Bean
8058
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
81-
httpSecurity.csrf().disable();
59+
8260
httpSecurity.headers().frameOptions().disable();
61+
httpSecurity.csrf().disable();
8362
httpSecurity
84-
.authorizeRequests()
85-
.requestMatchers(HttpMethod.POST, "/api/auth/login").permitAll()
86-
.requestMatchers(HttpMethod.GET, "/api/auth/logout").permitAll()
87-
.requestMatchers(HttpMethod.POST, "/h2-console").permitAll()
88-
.anyRequest().authenticated()
89-
.and()
90-
.exceptionHandling()
91-
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
92-
.and()
93-
.sessionManagement()
94-
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
95-
.and()
96-
.authenticationProvider(authenticationProvider)
97-
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
63+
.authorizeHttpRequests()
64+
.requestMatchers("/api/auth/**").permitAll()
65+
.anyRequest().authenticated()
66+
.and()
67+
.sessionManagement()
68+
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
69+
.and()
70+
.exceptionHandling()
71+
.authenticationEntryPoint(((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED)))
72+
.and()
73+
.authenticationProvider(authenticationProvider())
74+
.addFilterBefore(jwtAuthenticationFilter , UsernamePasswordAuthenticationFilter.class);
9875

9976
return httpSecurity.build();
77+
10078
}
10179

10280
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.howtodoinjava.app.security.service;
2+
3+
import com.howtodoinjava.app.security.repo.UserRepository;
4+
import org.springframework.beans.factory.annotation.Autowired;
5+
import org.springframework.context.annotation.Bean;
6+
import org.springframework.context.annotation.Configuration;
7+
import org.springframework.security.core.userdetails.UserDetails;
8+
import org.springframework.security.core.userdetails.UserDetailsService;
9+
import org.springframework.security.core.userdetails.UsernameNotFoundException;
10+
11+
@Configuration
12+
public class CustomUserDetailsService implements UserDetailsService {
13+
14+
@Autowired
15+
private UserRepository userRepository;
16+
17+
@Override
18+
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
19+
try {
20+
return userRepository.findByUsername(username)
21+
.orElseThrow(() -> new Exception("user Not found "));
22+
} catch (Exception e) {
23+
throw new RuntimeException(e);
24+
}
25+
}
26+
27+
}

spring-boot-vuejs-jwt-auth/Spring-Boot-API/src/main/java/com/howtodoinjava/app/security/utils/JwtTokenProvider.java

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.jsonwebtoken.*;
44
import io.jsonwebtoken.security.Keys;
5+
import io.jsonwebtoken.security.SignatureException;
56
import jakarta.servlet.http.HttpServletRequest;
67
import lombok.extern.slf4j.Slf4j;
78
import org.springframework.security.core.Authentication;
@@ -16,54 +17,57 @@
1617
@Slf4j
1718
public class JwtTokenProvider {
1819

19-
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS512);
20+
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS512);
2021

21-
public String createToken(Authentication authentication) {
22-
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
23-
Date now = new Date();
24-
Date expiryDate = new Date(now.getTime() + 3600000);
22+
public String createToken(Authentication authentication) {
23+
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
24+
Date now = new Date();
25+
Date expiryDate = new Date(now.getTime() + 3600000);
26+
27+
return Jwts.builder()
28+
.setSubject(userDetails.getUsername())
29+
.setIssuedAt(new Date())
30+
.setExpiration(expiryDate)
31+
.signWith(SignatureAlgorithm.HS512, key)
32+
.compact();
33+
}
2534

26-
return Jwts.builder()
27-
.setSubject(userDetails.getUsername())
28-
.setIssuedAt(new Date())
29-
.setExpiration(expiryDate)
30-
.signWith(SignatureAlgorithm.HS512, key)
31-
.compact();
32-
}
3335

3436

35-
public String resolveToken(HttpServletRequest request) {
36-
String bearerToken = request.getHeader("Authorization");
37-
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
38-
return bearerToken.substring(7);
37+
public String resolveToken(HttpServletRequest request) {
38+
String bearerToken = request.getHeader("Authorization");
39+
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
40+
return bearerToken.substring(7);
41+
}
42+
return null;
3943
}
40-
return null;
41-
}
4244

4345

44-
public boolean validateToken(String token) {
45-
// Check if the token is valid and not expired
46-
try {
47-
Jwts.parser().setSigningKey(key).parseClaimsJws(token);
48-
return true;
49-
} catch (MalformedJwtException ex) {
50-
log.error("Invalid JWT token");
51-
} catch (ExpiredJwtException ex) {
52-
log.error("Expired JWT token");
53-
} catch (UnsupportedJwtException ex) {
54-
log.error("Unsupported JWT token");
55-
} catch (IllegalArgumentException ex) {
56-
log.error("JWT claims string is empty");
46+
public boolean validateToken(String token) {
47+
// Check if the token is valid and not expired
48+
try {
49+
Jwts.parser().setSigningKey(key).parseClaimsJws(token);
50+
return true;
51+
} catch (MalformedJwtException ex) {
52+
log.error("Invalid JWT token");
53+
} catch (ExpiredJwtException ex) {
54+
log.error("Expired JWT token");
55+
} catch (UnsupportedJwtException ex) {
56+
log.error("Unsupported JWT token");
57+
} catch (IllegalArgumentException ex) {
58+
log.error("JWT claims string is empty");
59+
}catch (SignatureException e){
60+
log.error("there is an error with the signature of you token ");
61+
}
62+
return false;
5763
}
58-
return false;
59-
}
6064

61-
public String getUsername(String token) {
62-
// Extract the username from the JWT token
63-
return Jwts.parser()
64-
.setSigningKey(key)
65-
.parseClaimsJws(token)
66-
.getBody()
67-
.getSubject();
68-
}
65+
public String getUsername(String token) {
66+
// Extract the username from the JWT token
67+
return Jwts.parser()
68+
.setSigningKey(key)
69+
.parseClaimsJws(token)
70+
.getBody()
71+
.getSubject();
72+
}
6973
}

spring-boot-vuejs-jwt-auth/Spring-Boot-API/src/main/resources/application.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ spring.datasource.username=sa
66
spring.datasource.password=password
77
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
88
spring.h2.console.enabled=true
9+
10+
11+
spring.main.allow-circular-references=true

spring-boot-vuejs-jwt-auth/vue-app/src/utils/apiClient.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ const token = localStorage.getItem("jwtToken");
1414

1515
axiosInstance.interceptors.request.use(
1616
(config) => {
17-
if (config.url !== "/auth/login") {
18-
config.headers.Authorization = `Bearer ${token}`;
19-
}
17+
config.headers.Authorization = `Bearer ${token}`;
2018
return config;
2119
},
2220
(error) => {

spring-boot-vuejs-jwt-auth/vue-app/src/views/HomeView.vue

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,17 @@ export default defineComponent({
2626
setup() {
2727
let employees = ref<Employee[]>([]);
2828
29-
employeeService.getAllEmployees().then((response) => {
30-
employees.value = response;
31-
});
29+
employeeService
30+
.getAllEmployees()
31+
.then((response) => {
32+
employees.value = response;
33+
})
34+
.catch((error) => {
35+
if (error.response && error.response.status === 401) {
36+
// Redirect the user to the login page
37+
window.location.href = "/login";
38+
}
39+
});
3240
3341
return {
3442
employees,

0 commit comments

Comments
 (0)