Skip to content

Commit

Permalink
Merge pull request #125 from IT-Cotato/feature/124-refactor-filter
Browse files Browse the repository at this point in the history
Refactor: roomId, roomType 확인 기능 별도 필터로 분리(#124)
  • Loading branch information
yooooonshine authored Aug 12, 2024
2 parents 50e9224 + 9fd2733 commit dbb35fe
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import middle_point_search.backend.common.security.login.handler.LoginFailureHandler;
import middle_point_search.backend.common.security.login.handler.LoginSuccessHandler;
import middle_point_search.backend.common.security.login.provider.CustomAuthenticationProvider;
import middle_point_search.backend.common.security.roomFilter.filter.RoomFilter;
import middle_point_search.backend.domains.member.repository.MemberRepository;
import middle_point_search.backend.domains.room.repository.RoomRepository;

Expand Down Expand Up @@ -71,6 +72,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
http
.addFilterAfter(jsonUsernamePasswordLoginFilter(), LogoutFilter.class)
.addFilterBefore(jwtAuthenticationFilter(), JsonNamePwAuthenticationFilter.class)
.addFilterAfter(roomFilter(), JwtAuthenticationFilter.class)
.addFilterBefore(exceptionHandlingFilter(), JwtAuthenticationFilter.class);

//예외 처리 추가
Expand Down Expand Up @@ -109,7 +111,8 @@ public JsonNamePwAuthenticationFilter jsonUsernamePasswordLoginFilter() throws E
//JWT 필터 등록
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() {
return new JwtAuthenticationFilter(jwtTokenProvider, memberRepository, securityProperties, pathMatcher, roomRepository);
return new JwtAuthenticationFilter(jwtTokenProvider, memberRepository, securityProperties, pathMatcher,
roomRepository);
}

//예외 핸들링 필터 등록
Expand All @@ -118,4 +121,9 @@ public ExceptionHandlingFilter exceptionHandlingFilter() {
return new ExceptionHandlingFilter();
}

//방id,type 검사를 위한 RoomFilter 등록
@Bean
public RoomFilter roomFilter() {
return new RoomFilter(jwtTokenProvider, securityProperties, pathMatcher, roomRepository);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
Expand All @@ -21,12 +19,9 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import middle_point_search.backend.common.exception.CustomException;
import middle_point_search.backend.common.exception.errorCode.UserErrorCode;
import middle_point_search.backend.common.properties.SecurityProperties;
import middle_point_search.backend.common.security.jwt.provider.JwtTokenProvider;
import middle_point_search.backend.domains.member.repository.MemberRepository;
import middle_point_search.backend.domains.room.domain.Room;
import middle_point_search.backend.domains.room.domain.RoomType;
import middle_point_search.backend.domains.room.repository.RoomRepository;

@Slf4j
Expand Down Expand Up @@ -57,9 +52,6 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse

final String refreshToken = jwtTokenProvider.extractRefreshToken(request).orElse(null);
final String accessToken = jwtTokenProvider.extractAccessToken(request).orElse(null);
final String headerRoomId = jwtTokenProvider.extractRoomId(request).orElse(null);

final String tokenRoomId = jwtTokenProvider.extractRoomId(accessToken).orElse(null);

//1. access토큰이 존재하며, accessToken이 유효하면 인증
//2. access토큰이 존재하며, accesToken이 유효하지 않으면 에러 리턴
Expand All @@ -74,27 +66,6 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
throw new CustomException(INVALID_ACCESS_TOKEN);
}

//헤더 ROOM의 있는 방의 Type과 헤더의 RoomType이 같은지 검사(room검사보다 먼저 되어야 함)
Room headerRoom = roomRepository.findByIdentityNumber(headerRoomId)
.orElseThrow(() -> new CustomException(ROOM_NOT_FOUND));
final RoomType headerRoomType = jwtTokenProvider.extractRoomType(request).orElse(null);
if (headerRoomType != headerRoom.getRoomType()) {
throw new CustomException(ROOM_TYPE_UNPROCESSABLE);
}

//토큰의 있는 방의 Type과 헤더의 RoomType이 같은지 검사(room검사보다 먼저 되어야 함)
final Room room = roomRepository.findByIdentityNumber(tokenRoomId)
.orElseThrow(() -> new CustomException(ROOM_NOT_FOUND));
if (headerRoomType != room.getRoomType()) {
throw new CustomException(ROOM_TYPE_UNPROCESSABLE);
}

//토큰이 다른 room의 토큰인지 검사
if (!Objects.equals(headerRoomId, tokenRoomId)) {
log.info("다른 방의 accessToken으로 인증 실패");
throw new CustomException(UNAUTHORIZED);
}

log.info("access토큰 인증 성공");
Authentication authentication = jwtTokenProvider.getAuthentication(accessToken);
saveAuthentication(authentication);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package middle_point_search.backend.common.security.roomFilter.filter;

import static middle_point_search.backend.common.exception.errorCode.CommonErrorCode.UNAUTHORIZED;
import static middle_point_search.backend.common.exception.errorCode.UserErrorCode.*;

import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;

import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import middle_point_search.backend.common.exception.CustomException;
import middle_point_search.backend.common.properties.SecurityProperties;
import middle_point_search.backend.common.security.jwt.provider.JwtTokenProvider;
import middle_point_search.backend.domains.room.domain.Room;
import middle_point_search.backend.domains.room.domain.RoomType;
import middle_point_search.backend.domains.room.repository.RoomRepository;

@Slf4j
@RequiredArgsConstructor
public class RoomFilter extends OncePerRequestFilter {

private final JwtTokenProvider jwtTokenProvider;
private final SecurityProperties securityProperties;
private final AntPathMatcher pathMatcher;
private final RoomRepository roomRepository;

@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
String path = request.getRequestURI();

boolean result = Arrays.stream(securityProperties.getPermitUrls())
.anyMatch(permitUrl -> pathMatcher.match(permitUrl, path));

log.info("RoomFilter.shouldNotFilter({}) : {}", path, result);

return result;
}

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException, CustomException {

final String accessToken = jwtTokenProvider.extractAccessToken(request).orElse(null);
final String headerRoomId = jwtTokenProvider.extractRoomId(request).orElse(null);
final String tokenRoomId = jwtTokenProvider.extractRoomId(accessToken).orElse(null);
final RoomType headerRoomType = jwtTokenProvider.extractRoomType(request).orElse(null);

final Room headerRoom = roomRepository.findByIdentityNumber(headerRoomId)
.orElseThrow(() -> new CustomException(ROOM_NOT_FOUND));
final Room room = roomRepository.findByIdentityNumber(tokenRoomId)
.orElseThrow(() -> new CustomException(ROOM_NOT_FOUND));

//헤더 ROOM의 있는 방의 Type과 헤더의 RoomType이 같은지 검사(room검사보다 먼저 되어야 함)
if (headerRoomType != headerRoom.getRoomType()) {
throw new CustomException(ROOM_TYPE_UNPROCESSABLE);
}

//토큰의 있는 방의 Type과 헤더의 RoomType이 같은지 검사(room검사보다 먼저 되어야 함)
if (headerRoomType != room.getRoomType()) {
throw new CustomException(ROOM_TYPE_UNPROCESSABLE);
}

//토큰이 다른 room의 토큰인지 검사
if (!Objects.equals(headerRoomId, tokenRoomId)) {
log.info("다른 방의 accessToken으로 인증 실패");
throw new CustomException(UNAUTHORIZED);
}

log.info("roomId, roomType 인증 성공");
filterChain.doFilter(request, response);
}
}

0 comments on commit dbb35fe

Please sign in to comment.