Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions src/main/java/com/writon/admin/domain/service/AuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
Expand Down Expand Up @@ -63,9 +66,18 @@ public LoginResponseDto login(LoginRequestDto loginRequestDto) {

// 2. 실제로 검증 (사용자 비밀번호 체크) 이 이루어지는 부분
// authenticate 메서드가 실행이 될 때 CustomUserDetailsService 에서 만들었던 loadUserByUsername 메서드가 실행됨
Authentication authentication = authenticationManagerBuilder.getObject()
.authenticate(authenticationToken);
String identifier = authentication.getName();
String identifier;
try {
Authentication authentication = authenticationManagerBuilder.getObject()
.authenticate(authenticationToken);
identifier = authentication.getName();
} catch (BadCredentialsException e) {
throw new CustomException(ErrorCode.BAD_CREDENTIAL_ACCESS);
} catch (DisabledException e) {
throw new CustomException(ErrorCode.DISABLED_USER);
} catch (LockedException e) {
throw new CustomException(ErrorCode.LOCKED_USER);
}

// 3. 인증 정보를 기반으로 JWT 토큰 생성
TokenDto tokenDto = tokenProvider.createToken(identifier);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ public void commence(
errorCode = ErrorCode.REFRESH_TOKEN_EXPIRATION;
}

if (exception.equals(ErrorCode.NOT_CORRECT_USER.getCode())) {
errorCode = ErrorCode.NOT_CORRECT_USER;
if (exception.equals(ErrorCode.UNAUTHORIZED_TOKEN.getCode())) {
errorCode = ErrorCode.UNAUTHORIZED_TOKEN;
}
}

Expand Down
12 changes: 11 additions & 1 deletion src/main/java/com/writon/admin/global/config/auth/JwtFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.Authentication;
Expand All @@ -24,6 +26,14 @@ public class JwtFilter extends OncePerRequestFilter {
private final TokenProvider tokenProvider;
private final RedisTemplate<String, Object> redisTemplate;
private final ExceptionResponseHandler exceptionResponseHandler = new ExceptionResponseHandler();
private final List<String> excludedPaths = Arrays.asList("/auth/login","/auth/signup");

@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException{
// 로그인, 회원가입 API URL이 포함되는지 확인하는 함수
String path = request.getRequestURI();
return excludedPaths.stream().anyMatch(path::equals);
}

// 실제 필터링 로직은 doFilterInternal 에 들어감
// JWT 토큰의 인증 정보를 현재 쓰레드의 SecurityContext 에 저장하는 역할 수행
Expand All @@ -38,7 +48,7 @@ protected void doFilterInternal(
String jwt = resolveToken(request);

// 2. 토큰의 존재여부 & accessToken 유효성 검사
if (tokenProvider.validateToken(jwt, request) && StringUtils.hasText(jwt)) {
if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt, request)) {
System.out.println("JWT Token 검증 통과");

// 3. 로그아웃 유저 확인 (access: O, refresh: X)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ public boolean validateToken(String token, HttpServletRequest request) {
} catch (UnsupportedJwtException e) {
log.info("지원되지 않는 JWT 토큰입니다.");
} catch (IllegalArgumentException e) {
log.info("아이디나 비밀번호가 잘못되었습니다");
request.setAttribute("exception", ErrorCode.NOT_CORRECT_USER.getCode());
log.info("JWT 토큰이 잘못되었습니다.");
request.setAttribute("exception", ErrorCode.UNAUTHORIZED_TOKEN.getCode());
}
return false;
}
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/com/writon/admin/global/error/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,21 @@ public enum ErrorCode {
BAD_REQUEST(HttpStatus.BAD_REQUEST, "400", "잘못된 요청입니다"), // 400 Bad Request
UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "401", "권한이 없습니다"), // 401 Unauthorized
FORBIDDEN(HttpStatus.FORBIDDEN, "403", "잘못된 요청입니다"), // 403 Forbidden
NOT_FOUND(HttpStatus.NOT_FOUND, "404", "사용자를 찾을 수 없습니다"), // 404 Not Found
NOT_FOUND(HttpStatus.NOT_FOUND, "404", "정보를 찾을 수 없습니다"), // 404 Not Found
METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, "405", "허용되지 않은 메소드입니다"), // 405 Method Not Allowed
CONFLICT(HttpStatus.CONFLICT, "409", "이미 가입한 사용자입니다"), // 409 Conflict
INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "500", "서버에 오류가 발생하였습니다"), // 500 Internal Server Error
ETC_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "0314", "사용자 지정 오류"),

// auth
USER_NOT_FOUND(HttpStatus.NOT_FOUND, "A01", "사용자를 찾을 수 없습니다"),
NOT_CORRECT_USER(HttpStatus.BAD_REQUEST, "A02", "아이디나 비밀번호가 잘못되었습니다"),
UNAUTHORIZED_TOKEN(HttpStatus.UNAUTHORIZED, "A02", "권한이 없는 토큰입니다"),
REFRESH_TOKEN_EXPIRATION(HttpStatus.UNAUTHORIZED, "A03", "만료된 토큰입니다"),
ACCESS_TOKEN_EXPIRATION(HttpStatus.UNAUTHORIZED, "A04", "토큰 재발급을 요청해주세요"),
REFRESH_TOKEN_INCONSISTENCY(HttpStatus.NOT_FOUND, "A05", "토큰이 일치하지 않습니다"),
BAD_CREDENTIAL_ACCESS(HttpStatus.BAD_REQUEST, "A06", "아이디 혹은 비밀번호가 잘못되었습니다"),
DISABLED_USER(HttpStatus.NOT_FOUND, "A07", "비활성화된 계정입니다"),
LOCKED_USER(HttpStatus.NOT_FOUND, "A08", "계정이 잠겨 있습니다"),

// organization
ORGANIZATION_NOT_FOUND(HttpStatus.NOT_FOUND, "O01", "조직 정보를 찾을 수 없습니다"),
Expand Down