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
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.permitseoul.permitserver.global.response.ApiResponseUtil;
import com.permitseoul.permitserver.global.response.BaseResponse;
import com.permitseoul.permitserver.global.response.code.SuccessCode;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,14 @@ public class SecurityConfig {
private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
private final ExceptionHandlerFilter exceptionHandlerFilter;

private static final String[] whiteURIList = {
private static final String[] whiteURIListNotUsingToken = {
"/actuator/health",
"/api/users/signup",
"/api/users/login",
"/api/users/reissue",
"/api/events",
"/api/events/detail/*",
"/api/users/email-check",
"/api/events/*/timetables",
"/api/events/timetables/*",
"/api/tickets/info/*",
"/api/tickets/door/staff/confirm",
"/api/tickets/door/validation/*",
Expand All @@ -44,6 +42,11 @@ public class SecurityConfig {
"/api/events/*/sitemap",
};

private static final String[] whiteURIListUsingToken = {
"/api/events/*/timetables", // userId ์žˆ์œผ๋ฉด ๊ฐœ์ธํ™”
"/api/events/timetables/*", // userId ์žˆ์œผ๋ฉด ๊ฐœ์ธํ™”
};

private static final String[] adminURIList = {
"/api/admin/**"
};
Expand All @@ -70,17 +73,16 @@ public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Excepti
.csrf(AbstractHttpConfigurer::disable)
.formLogin(AbstractHttpConfigurer::disable)
.httpBasic(AbstractHttpConfigurer::disable)
.sessionManagement(sessionManagementConfigurer ->
sessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.exceptionHandling(exceptionHandlingConfigurer ->
exceptionHandlingConfigurer.authenticationEntryPoint(jwtAuthenticationEntryPoint))
.sessionManagement(sessionManagementConfigurer -> sessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.exceptionHandling(exceptionHandlingConfigurer -> exceptionHandlingConfigurer.authenticationEntryPoint(jwtAuthenticationEntryPoint))
.authorizeHttpRequests(auth -> auth
.requestMatchers(whiteURIList).permitAll() // ๋กœ๊ทธ์ธ ์ƒ๊ด€ X
.requestMatchers(adminURIList).hasRole(UserRole.ADMIN.name()) // ADMIN ๊ถŒํ•œ ํ•„์š”
.requestMatchers(staffURIList).hasAnyRole(UserRole.STAFF.name(), UserRole.ADMIN.name()) //staff ๊ถŒํ•œ ์ด์ƒ
.requestMatchers(adminURIList).hasRole(UserRole.ADMIN.name()) // ADMIN// ๊ถŒํ•œ ํ•„์š”
.requestMatchers(staffURIList).hasAnyRole(UserRole.STAFF.name(), UserRole.ADMIN.name()) // staff ๊ถŒํ•œ ์ด์ƒ
.requestMatchers(authRequiredURIList).authenticated() // ๋กœ๊ทธ์ธ ํ•„์ˆ˜
)
.addFilterBefore(new JwtAuthenticationFilter(jwtProvider, List.of(whiteURIList)), UsernamePasswordAuthenticationFilter.class)
.requestMatchers(whiteURIListNotUsingToken).permitAll() // ๋กœ๊ทธ์ธ ์ƒ๊ด€ X + AccessToken ์‚ฌ์šฉX
.requestMatchers(whiteURIListUsingToken).permitAll() // ๋กœ๊ทธ์ธ ์ƒ๊ด€ X + AccessToken ์žˆ์œผ๋ฉด ์‚ฌ์šฉ
.anyRequest().denyAll())
.addFilterBefore(new JwtAuthenticationFilter(jwtProvider, List.of(whiteURIListNotUsingToken), List.of(whiteURIListUsingToken)), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(exceptionHandlerFilter, JwtAuthenticationFilter.class)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
import com.permitseoul.permitserver.domain.auth.core.exception.AuthWrongJwtException;
import com.permitseoul.permitserver.domain.auth.core.jwt.CookieExtractor;
import com.permitseoul.permitserver.domain.auth.core.jwt.JwtProvider;
import com.permitseoul.permitserver.global.Constants;
import com.permitseoul.permitserver.global.domain.CookieType;
import com.permitseoul.permitserver.global.exception.FilterException;
import com.permitseoul.permitserver.global.response.code.ErrorCode;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.NonNull;
Expand All @@ -26,38 +24,38 @@
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Enumeration;
import java.util.List;


@RequiredArgsConstructor
@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtProvider jwtProvider;
private final List<String> whiteURIList;
private final List<String> whiteURIListNotUsingToken;
private final List<String> whiteURIListUsingToken;
private final AntPathMatcher pathMatcher = new AntPathMatcher();
private static final String REISSUE_URI = "/api/users/reissue";
private static final String LOGIN_URI = "/api/users/login";
private static final String USER_ID_MDC_KEY = "user_id";
private static final String ANONYMOUS_USER_ID = "anonymous";

@Override
protected boolean shouldNotFilter(@NonNull final HttpServletRequest request) {
return whiteURIListNotUsingToken.stream()
.anyMatch(pattern -> pathMatcher.match(pattern, request.getRequestURI()));
}

@Override
protected void doFilterInternal(@NonNull final HttpServletRequest request,
@NonNull final HttpServletResponse response,
@NonNull final FilterChain filterChain) throws ServletException, IOException {
@NonNull final HttpServletResponse response,
@NonNull final FilterChain filterChain) throws ServletException, IOException {
final String uri = request.getRequestURI();
try {
MDC.put(USER_ID_MDC_KEY, ANONYMOUS_USER_ID);

if(isHealthCheckUri(uri) || isLoginOrReissue(uri)) {
filterChain.doFilter(request, response);
return;
}
setAuthentication(request);
filterChain.doFilter(request, response);
} catch (AuthCookieException e) {
if(isWhiteListUrl(uri)) {
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(null, null, null));
if (isUsingTokenUrl(uri)) {
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(null, null, null));
filterChain.doFilter(request, response);
} else {
throw new FilterException(ErrorCode.NOT_FOUND_AT_COOKIE);
Expand All @@ -69,14 +67,12 @@ protected void doFilterInternal(@NonNull final HttpServletRequest request,
} catch (ServletException | IOException e) {
log.error("[JWT Filter] unexpected error. ua={}",
request.getHeader("User-Agent"),
e
);
e);
throw new FilterException(ErrorCode.INTERNAL_FILTER_ERROR);
} catch (Exception e) {
log.error("[JWT Filter] unexpected error. ua={}",
request.getHeader("User-Agent"),
e
);
e);
throw new FilterException(ErrorCode.INTERNAL_SERVER_ERROR);
} finally {
MDC.remove(USER_ID_MDC_KEY);
Expand All @@ -93,16 +89,7 @@ private void setAuthentication(final HttpServletRequest request) {
new UsernamePasswordAuthenticationToken(userId, null, authorities));
}

private boolean isWhiteListUrl(final String requestURI) {
return whiteURIList.stream().anyMatch(pattern -> pathMatcher.match(pattern, requestURI));
}

private boolean isHealthCheckUri(final String uri) {
return pathMatcher.match(Constants.HEALTH_CHECK_URL, uri);
}

private boolean isLoginOrReissue(final String uri) {
return pathMatcher.match(LOGIN_URI, uri)
|| pathMatcher.match(REISSUE_URI, uri);
private boolean isUsingTokenUrl(final String requestURI) {
return whiteURIListUsingToken.stream().anyMatch(pattern -> pathMatcher.match(pattern, requestURI));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

@Component
@Slf4j
//@Profile("!local")
@Profile("!local")
@Order(Ordered.HIGHEST_PRECEDENCE)
class RequestObservabilityFilter extends OncePerRequestFilter {
private static final String NGINX_REQUEST_ID = "X-Request-ID";
Expand Down