0% found this document useful (0 votes)
56 views7 pages

Spring Security Hirchoua Badr Xproce

The document outlines a Java Spring Boot application implementing JWT authentication for user management. It includes interfaces and classes for customer repository, authentication service, user service, and JWT handling, along with REST controllers for user registration and login. The security configuration ensures stateless session management and defines authorization rules for specific endpoints.

Uploaded by

Said Chakir
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
56 views7 pages

Spring Security Hirchoua Badr Xproce

The document outlines a Java Spring Boot application implementing JWT authentication for user management. It includes interfaces and classes for customer repository, authentication service, user service, and JWT handling, along with REST controllers for user registration and login. The security configuration ensures stateless session management and defines authorization rules for specific endpoints.

Uploaded by

Said Chakir
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

https://github.

com/badrhr/jwt-auth-api

public interface CustomerRepository


extends JpaRepository<Customer, Integer> { @Service @Service
Optional<Customer> findByEmail(String email); @AllArgsConstructor @AllArgsConstructor
} public class AuthenticationService { public class UserService {
private final CustomerRepository customerRepository; private final CustomerRepository customerRepository;
@Entity @Getter private final PasswordEncoder passwordEncoder;
@Setter @NoArgsConstructor private final AuthenticationManager authenticationManager; public List<CustomUser> allUsers() {
@AllArgsConstructor List<CustomUser> users =
@Builder @ToString public CustomUser signup(RegisterUserDto input) { customerRepository.findAll()
public class Customer { Customer customer = Customer.builder() .stream()
@Id .email(input.getEmail()) .map(customer ->
@GeneratedValue(strategy = GenerationType.AUTO) .password( CustomUser.builder()
@Column(nullable = false) passwordEncoder.encode(input.getPassword())) .customer(customer)
private Integer id; .fullName(input.getFullName()) .build())
.build(); .collect(Collectors.toList());
@Column(nullable = false) customer = customerRepository.save(customer); return users;
private String fullName; return CustomUser.builder().customer(customer).build(); }
} }
@Column(unique = true, length = 100, nullable = false)
private String email; public CustomUser authenticate(LoginUserDto input) {
authenticationManager.authenticate(
@Column(nullable = false) new UsernamePasswordAuthenticationToken(
private String password; input.getEmail(),
input.getPassword()
@CreationTimestamp )
@Column(updatable = false, name = "created_at") );
private Date createdAt; Customer customer = customerRepository.findByEmail(
input.getEmail()).orElseThrow();
@UpdateTimestamp return CustomUser.builder().customer(customer).build();
@Column(name = "updated_at") }
private Date updatedAt; }
}
@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder @ToString
public class CustomUser implements UserDetails {
private Customer customer;

@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 String extractUsername(String token) { private boolean isTokenExpired(String token) {


return extractClaim(token, Claims::getSubject); return extractExpiration(token).before(new Date());
} }

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();
} }

public long getExpirationTime() { private Key getSignInKey() {


return jwtExpiration; byte[] keyBytes = Decoders.BASE64.decode(secretKey);
} return Keys.hmacShaKeyFor(keyBytes);
}
}
@Override
protected void doFilterInternal(
@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain filterChain
) throws ServletException, IOException {
final String authHeader = request.getHeader("Authorization");

if (authHeader == null || !authHeader.startsWith("Bearer ")) {


@Component filterChain.doFilter(request, response);
@AllArgsConstructor return;
public class JwtAuthenticationFilter extends OncePerRequestFilter { }
private final HandlerExceptionResolver handlerExceptionResolver;
private final JwtService jwtService; try {
private final UserDetailsService userDetailsService; final String jwt = authHeader.substring(7);
final String userEmail = jwtService.extractUsername(jwt);

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

if (userEmail != null && authentication == null) {


UserDetails userDetails = this.userDetailsService.loadUserByUsername(userEmail);

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;

private static final String[] AUTH_WHITELIST = {


"/auth/**",
"/h2-console/**"
};

@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;

public ApplicationConfiguration(CustomerRepository userRepository) {


this.userRepository = 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); }
}
}

You might also like