Skip to content

Commit

Permalink
hotfix : JwtAuthenticationFilter 및 Enum 팩토리 메소드 로직을 수정한다
Browse files Browse the repository at this point in the history
  • Loading branch information
packdev937 committed May 8, 2024
1 parent f0e89b0 commit 31f0b4b
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lombok.RequiredArgsConstructor;
import org.springframework.core.env.Environment;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

Expand All @@ -12,8 +13,7 @@ public class HealthCheckController implements HealthCheckControllerDocs {
private final Environment environment;

@Override
public String healthCheck() {
return environment.getProperty("spring.application.name") + " is running on port: "
+ environment.getProperty("local.server.port");
public ResponseEntity<Void> healthCheck() {
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import kusitms.duduk.core.exception.ErrorResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;

public interface HealthCheckControllerDocs {
Expand All @@ -19,5 +20,5 @@ public interface HealthCheckControllerDocs {
content = {@Content(schema = @Schema(implementation = ErrorResponse.class))})
})
@Operation(summary = "헬스 체크", description = "서버 상태 확인")
String healthCheck();
ResponseEntity<Void> healthCheck();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package kusitms.duduk.apiserver.security;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;

public class JwtAccessDeniedHandler implements AccessDeniedHandler {

@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package kusitms.duduk.apiserver.security.infrastructure;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;

public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {

@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("Unauthorized: Invalid or missing access token");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
* 사용자 요청 헤더에 RefreshToken이 있는 경우는 AccessToken이 만료되었을 때입니다.
* AccessToken이 만료되었다면 (403 ERROR) 후 클라이언트가 다시 요청합니다.
*/
String refreshToken = null;
try {
refreshToken = extractRefreshToken(request)
String refreshToken = extractRefreshToken(request)
.filter(jwtTokenProvider::isTokenValid)
.orElse(null);
/**
Expand Down Expand Up @@ -109,17 +108,23 @@ private String reIssueRefreshToken(User user) {
private void verifyAccessTokenAndSaveAuthentication(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
Optional<String> accessToken = extractAccessToken(request);

if(accessToken.isEmpty()){
filterChain.doFilter(request, response);
return;
}
/**
* Authentication 객체는 해당 클래스에서 혹은 JwtTokenProvider에서 처리해도 무방합니다.
* 다만, getSubject()를 통해 email을 추출하고 email을 통해 User 정보를 가져올 수 있으니
* 해당 정보를 사용해서 UserDetails 혹은 OAuth2User를 만든다면 위 클래스에서 진행하는 것이 나을 수 있습니다.
* 현재 경우에는 accessToken에 담겨 있는 email, Authorities 정보로 Authentication 객체를 생성합니다.
*/
extractAccessToken(request)
.filter(jwtTokenProvider::isTokenValid)
.ifPresent(accessToken -> jwtTokenProvider.getSubject(accessToken)
if(jwtTokenProvider.isTokenValid(accessToken.get())){
jwtTokenProvider.getSubject(accessToken.get())
.ifPresent(email -> loadUserPort.findByEmail(email)
.ifPresent(this::saveAuthentication)));
.ifPresent(this::saveAuthentication));
}

filterChain.doFilter(request, response);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
Expand All @@ -21,7 +22,7 @@ public class OAuthController implements OAuthControllerDocs {

@GetMapping("/{provider}")
public ResponseEntity<OAuthLoginResponse> oAuthLogin(
@PathVariable final String provider,
@RequestParam(name = "prodiver") final String provider,
@RequestHeader("OAuth") final String accessToken) {
return new ResponseEntity<>(loginOAuthUseCase.process(Provider.from(provider), accessToken),
HttpStatus.OK);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ public User toDomain(CreateUserRequest request) {
.birthday(request.birthDay())
.role(Role.USER)
.provider(Provider.from(request.provider()))
.category(Category.valueOf(request.category()))
.goal(Goal.valueOf(request.goal()))
.category(Category.from(request.category()))
.goal(Goal.from(request.goal()))
.acorn(Acorn.initial())
.build();
}
Expand Down
12 changes: 6 additions & 6 deletions domain/src/main/java/kusitms/duduk/domain/global/Category.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
@Getter
@RequiredArgsConstructor
public enum Category {
STOCK("주식"),
CRYPTO("암호화폐"),
ESTATE("부동산"),
FUND("펀드"),
ETC("기타");
STOCK("stock"),
CRYPTO("crypto"),
ESTATE("estate"),
FUND("fund"),
ETC("etc");

private final String description;

public static Category from(String description) {
return Arrays.stream(Category.values())
.filter(d -> d.description.equals(description))
.filter(d -> d.description.equalsIgnoreCase(description))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("올바르지 않은 카테고리입니다."));
}
Expand Down

0 comments on commit 31f0b4b

Please sign in to comment.