-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added SecurityConfig class with PasswordEncoder and SecurityFilterChain beans. Implemented UserDetails interface in the User class. Added the implementation for the UserDetailsService interface. Added Role entity. Added RoleRepository. Added roles field to the User entity. Added Liquibase changesets to insert roles into DB and assign roles for users. * Added JWT support * Added handling of JwtException and AuthenticationException in GlobalExceptionHandler * Removed redundant Key to SecretKey cast in JwtUtil in lines 38 & 53 * Added swagger request matchers * Added token prefix and auth header strings to constant. Removed redundant AuthenticationException handling in GlobalExceptionHandler. Added max size limits for email and password in UserLoginRequestDto
- Loading branch information
1 parent
afcb489
commit 7e352d8
Showing
15 changed files
with
217 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
src/main/java/mate/academy/bookstore/dto/user/UserLoginRequestDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package mate.academy.bookstore.dto.user; | ||
|
||
import jakarta.validation.constraints.Email; | ||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.validation.constraints.Size; | ||
|
||
public record UserLoginRequestDto( | ||
@NotBlank | ||
@Size(min = 8, max = 20) | ||
String email, | ||
@NotBlank | ||
@Size(min = 8, max = 20, message = "Password must be at least 8 characters long") | ||
String password | ||
) { | ||
} |
4 changes: 4 additions & 0 deletions
4
src/main/java/mate/academy/bookstore/dto/user/UserLoginResponseDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package mate.academy.bookstore.dto.user; | ||
|
||
public record UserLoginResponseDto(String token) { | ||
} |
2 changes: 1 addition & 1 deletion
2
...y/bookstore/dto/user/UserResponseDto.java → ...dto/user/UserRegistrationResponseDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
src/main/java/mate/academy/bookstore/security/AuthenticationService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package mate.academy.bookstore.security; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import mate.academy.bookstore.dto.user.UserLoginRequestDto; | ||
import mate.academy.bookstore.dto.user.UserLoginResponseDto; | ||
import org.springframework.security.authentication.AuthenticationManager; | ||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.stereotype.Service; | ||
|
||
@RequiredArgsConstructor | ||
@Service | ||
public class AuthenticationService { | ||
private final JwtUtil jwtUtil; | ||
private final AuthenticationManager authenticationManager; | ||
|
||
public UserLoginResponseDto authenticate(UserLoginRequestDto request) { | ||
final Authentication authentication = authenticationManager.authenticate( | ||
new UsernamePasswordAuthenticationToken(request.email(), request.password()) | ||
); | ||
|
||
String token = jwtUtil.generateToken(authentication.getName()); | ||
return new UserLoginResponseDto(token); | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
src/main/java/mate/academy/bookstore/security/JwtAuthenticationFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package mate.academy.bookstore.security; | ||
|
||
import jakarta.servlet.FilterChain; | ||
import jakarta.servlet.ServletException; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import java.io.IOException; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.security.core.userdetails.UserDetails; | ||
import org.springframework.security.core.userdetails.UserDetailsService; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.filter.OncePerRequestFilter; | ||
|
||
@RequiredArgsConstructor | ||
@Component | ||
public class JwtAuthenticationFilter extends OncePerRequestFilter { | ||
private static final String BEARER_PREFIX = "Bearer "; | ||
private static final String AUTHORIZATION = "Authorization"; | ||
private final UserDetailsService userDetailsService; | ||
private final JwtUtil jwtUtil; | ||
|
||
@Override | ||
protected void doFilterInternal( | ||
HttpServletRequest request, | ||
HttpServletResponse response, | ||
FilterChain filterChain | ||
) throws ServletException, IOException { | ||
String token = getToken(request); | ||
|
||
if (token != null && jwtUtil.isValidToken(token)) { | ||
String username = jwtUtil.getUsername(token); | ||
UserDetails userDetails = userDetailsService.loadUserByUsername(username); | ||
Authentication authentication = new UsernamePasswordAuthenticationToken( | ||
userDetails, null, userDetails.getAuthorities() | ||
); | ||
SecurityContextHolder.getContext().setAuthentication(authentication); | ||
} | ||
filterChain.doFilter(request, response); | ||
} | ||
|
||
private String getToken(HttpServletRequest request) { | ||
String bearerToken = request.getHeader(AUTHORIZATION); | ||
if (bearerToken != null && bearerToken.startsWith(BEARER_PREFIX)) { | ||
return bearerToken.substring(BEARER_PREFIX.length()); | ||
} | ||
return null; | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
src/main/java/mate/academy/bookstore/security/JwtUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package mate.academy.bookstore.security; | ||
|
||
import io.jsonwebtoken.Claims; | ||
import io.jsonwebtoken.Jws; | ||
import io.jsonwebtoken.JwtException; | ||
import io.jsonwebtoken.Jwts; | ||
import io.jsonwebtoken.security.Keys; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.Date; | ||
import java.util.function.Function; | ||
import javax.crypto.SecretKey; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class JwtUtil { | ||
private final SecretKey secret; | ||
|
||
@Value("${jwt.expiration}") | ||
private Long expiration; | ||
|
||
public JwtUtil(@Value("${jwt.secret}") String secretKey) { | ||
secret = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8)); | ||
} | ||
|
||
public String generateToken(String username) { | ||
return Jwts.builder() | ||
.subject(username) | ||
.issuedAt(new Date(System.currentTimeMillis())) | ||
.expiration(new Date(System.currentTimeMillis() + expiration)) | ||
.signWith(secret) | ||
.compact(); | ||
} | ||
|
||
public boolean isValidToken(String token) { | ||
try { | ||
Jws<Claims> claimsJws = Jwts.parser() | ||
.verifyWith(secret) | ||
.build() | ||
.parseSignedClaims(token); | ||
return !claimsJws.getPayload().getExpiration().before(new Date()); | ||
} catch (JwtException | IllegalArgumentException e) { | ||
throw new JwtException("Expired or invalid JWT token"); | ||
} | ||
} | ||
|
||
public String getUsername(String token) { | ||
return getClaimsFromToken(token, Claims::getSubject); | ||
} | ||
|
||
private <T> T getClaimsFromToken(String token, Function<Claims, T> claimsResolver) { | ||
final Claims claims = Jwts.parser() | ||
.verifyWith(secret) | ||
.build() | ||
.parseSignedClaims(token) | ||
.getPayload(); | ||
return claimsResolver.apply(claims); | ||
} | ||
} |
5 changes: 3 additions & 2 deletions
5
src/main/java/mate/academy/bookstore/service/UserService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
package mate.academy.bookstore.service; | ||
|
||
import mate.academy.bookstore.dto.user.UserRegistrationRequestDto; | ||
import mate.academy.bookstore.dto.user.UserResponseDto; | ||
import mate.academy.bookstore.dto.user.UserRegistrationResponseDto; | ||
import mate.academy.bookstore.exception.RegistrationException; | ||
|
||
public interface UserService { | ||
UserResponseDto save(UserRegistrationRequestDto requestDto) throws RegistrationException; | ||
UserRegistrationResponseDto save(UserRegistrationRequestDto requestDto) | ||
throws RegistrationException; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,4 +17,4 @@ databaseChangeLog: | |
type: enum('USER', 'ADMIN') | ||
constraints: | ||
nullable: false | ||
unique: true | ||
unique: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters