Spring Security Hirchoua Badr Xproce
Spring Security Hirchoua Badr Xproce
com/badrhr/jwt-auth-api
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return List.of();
}
@Getter @Getter @Getter public String getPassword() {
@Setter @Setter @Setter return customer.getPassword();
@ToString @ToString @ToString }
@NoArgsConstructor @NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor @AllArgsConstructor @Override
public class RegisterUserDto { public class LoginUserDto { @Builder public String getUsername() {
private String email; private String email; public class LoginResponse { return customer.getEmail();
private String password; private String password; private String token; }
private String fullName; private long expiresIn; @Override
} } } public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
server.port=8090
@Override
spring.datasource.url=jdbc:h2:mem:security-db public boolean isCredentialsNonExpired() {
return true;
spring.h2.console.enabled=true }
security.jwt.secret-key= =3cfa76ef14937c1c0ea519f8fc057a80fcd04a7420f8e8bcd0a7567c272e007b @Override
public boolean isEnabled() {
security.jwt.expiration-time=3600000 return true;
}
logging.level.org.springframework.security=TRACE public Integer getId() {
return customer.getId();
}
}
private String buildToken( Map<String, Object> extraClaims,
UserDetails userDetails,
long expiration ) {
return Jwts.builder()
.setClaims(extraClaims)
.setSubject(userDetails.getUsername())
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + expiration))
.signWith(getSignInKey(), SignatureAlgorithm.HS256)
@Service .compact();
public class JwtService { }
@Value("${security.jwt.secret-key}")
private String secretKey; public boolean isTokenValid(String token, UserDetails userDetails) {
final String username = extractUsername(token);
@Value("${security.jwt.expiration-time}") return (username.equals(userDetails.getUsername())) && !isTokenExpired(token);
private long jwtExpiration; }
public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) { private Date extractExpiration(String token) {
final Claims claims = extractAllClaims(token); return extractClaim(token, Claims::getExpiration);
return claimsResolver.apply(claims); }
}
private Claims extractAllClaims(String token) {
public String generateToken(UserDetails userDetails) { return Jwts
return generateToken(new HashMap<>(), userDetails); .parserBuilder()
} .setSigningKey(getSignInKey())
.build()
public String generateToken(Map<String, Object> extraClaims, UserDetails userDetails) { .parseClaimsJws(token)
return buildToken(extraClaims, userDetails, jwtExpiration); .getBody();
} }
if (jwtService.isTokenValid(jwt, userDetails)) {
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities()
);
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
filterChain.doFilter(request, response);
} catch (Exception exception) {
handlerExceptionResolver.resolveException(request, response, null, exception);
}
}
}
@Configuration
@EnableWebSecurity
@AllArgsConstructor
public class SecurityConfiguration {
private final AuthenticationProvider authenticationProvider;
private final JwtAuthenticationFilter jwtAuthFilter;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
. authorizeHttpRequests(authorizeRequests ->
authorizeRequests
.requestMatchers(AUTH_WHITELIST).permitAll()
.anyRequest().authenticated()
)
.headers(httpSecurityHeadersConfigurer -> {
httpSecurityHeadersConfigurer.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable);
})
.sessionManagement(sessionManagement ->
sessionManagement
.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authenticationProvider(authenticationProvider)
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Configuration
public class ApplicationConfiguration {
private final CustomerRepository userRepository;
@Bean
UserDetailsService userDetailsService() {
return username -> CustomUser.builder()
.customer(userRepository.findByEmail(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found")))
.build() ;
}
@Bean
BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
return config.getAuthenticationManager();
}
@Bean
AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
}
@RequestMapping("/auth") @RequestMapping("/users")
@RestController @RestController
public class AuthenticationController { public class UserController {
private final JwtService jwtService; private final UserService userService;
private final AuthenticationService authenticationService;
public UserController(UserService userService) {
public AuthenticationController(JwtService jwtService, AuthenticationService authenticationService) { this.userService = userService;
this.jwtService = jwtService; }
this.authenticationService = authenticationService;
} @GetMapping("/me")
public ResponseEntity<CustomUser> authenticatedUser() {
@PostMapping("/signup") Authentication authentication =
public ResponseEntity<CustomUser> register(@RequestBody RegisterUserDto registerUserDto) { SecurityContextHolder.getContext().getAuthentication();
CustomUser registeredUser = authenticationService.signup(registerUserDto); CustomUser currentUser = (CustomUser)
return ResponseEntity.ok(registeredUser); authentication.getPrincipal();
} return ResponseEntity.ok(currentUser);
}
@PostMapping("/login")
public ResponseEntity<LoginResponse> authenticate(@RequestBody LoginUserDto loginUserDto) { @GetMapping
CustomUser authenticatedUser = authenticationService.authenticate(loginUserDto); public ResponseEntity<List<CustomUser>> allUsers() {
String jwtToken = jwtService.generateToken(authenticatedUser); List<CustomUser> users = userService.allUsers();
LoginResponse loginResponse = return ResponseEntity.ok(users);
LoginResponse.builder().token(jwtToken).expiresIn(jwtService.getExpirationTime()).build(); }
return ResponseEntity.ok(loginResponse); }
}
}