Skip to content

Commit

Permalink
ref: 파트별 멘토 리스트 조회, 멘토 상세 정보 조회 토큰 해제 (#190)
Browse files Browse the repository at this point in the history
  • Loading branch information
qzzloz authored Nov 30, 2024
1 parent 426fb59 commit 4f9eb48
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 76 deletions.
145 changes: 73 additions & 72 deletions src/main/java/com/soongsil/CoffeeChat/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,78 +28,79 @@
@EnableWebSecurity
public class SecurityConfig {

private final CustomOAuth2UserService customOAuth2UserService;
private final CustomSuccessHandler customSuccessHandler;
private final JWTUtil jwtUtil;
private final RefreshRepository refreshRepository;

public SecurityConfig(CustomOAuth2UserService customOAuth2UserService,
CustomSuccessHandler customSuccessHandler,
JWTUtil jwtUtil,
RefreshRepository refreshRepository) {
this.customOAuth2UserService = customOAuth2UserService;
this.customSuccessHandler = customSuccessHandler;
this.jwtUtil = jwtUtil;
this.refreshRepository = refreshRepository;
}

@Bean
public RoleHierarchy roleHierarchy() {
RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
hierarchy.setHierarchy("""
ROLE_ADMIN > ROLE_MENTEE
ROLE_ADMIN > ROLE_MENTOR
ROLE_MENTEE > ROLE_USER
ROLE_MENTOR > ROLE_USER
""");
return hierarchy;
}


@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors(corsCustomizer -> corsCustomizer.configurationSource(request -> {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(
Arrays.asList("https://localhost:3000", "http://localhost:8080", "http://localhost:3000",
"https://cogo.life", "https://coffeego-ssu.web.app")); // 프론트 서버의 주소들 // 프론트 서버의 주소
configuration.setAllowedMethods(Collections.singletonList("*")); // 모든 요청 메서드 허용
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Collections.singletonList("*")); // 모든 헤더 허용
configuration.setMaxAge(3600L);
configuration.setExposedHeaders(Arrays.asList("Set-Cookie", "Authorization", "Access",
"loginStatus")); // Set-Cookie 및 Authorization 헤더 노출
return configuration;
}))
.csrf(csrf -> csrf.disable()) // CSRF 비활성화
.formLogin(formLogin -> formLogin.disable()) // 폼 로그인 비활성화
.httpBasic(httpBasic -> httpBasic.disable()) // HTTP Basic 인증 비활성화
.oauth2Login(oauth2 -> oauth2
.userInfoEndpoint(userInfoEndpoint -> userInfoEndpoint.userService(customOAuth2UserService))
.successHandler(customSuccessHandler))
.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 모든 OPTIONS 요청에 대해 인증을 요구하지 않음
.requestMatchers("/health-check", "/", "/auth/reissue/**", "/security-check").permitAll()
.requestMatchers("/api/v2/users/**", "/auth/**").hasRole("USER")
.requestMatchers(("/auth/reissue/mobile/**")).permitAll()
.requestMatchers("/api/v2/possibleDates/**").hasAnyRole("MENTOR", "MENTEE")
.requestMatchers("/api/v2/mentors/**").hasAnyRole("MENTOR", "MENTEE")
.requestMatchers("/api/v2/applications/**").hasAnyRole("MENTOR", "MENTEE")
.anyRequest().authenticated())
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 세션 정책을 STATELESS로 설정
.addFilterBefore(new CustomLogoutFilter(jwtUtil, refreshRepository), LogoutFilter.class)
.addFilterAfter(new JWTFilter(jwtUtil), OAuth2LoginAuthenticationFilter.class);

return http.build();
}

@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return web -> web.ignoring()
.requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-resources/**");
}
private final CustomOAuth2UserService customOAuth2UserService;
private final CustomSuccessHandler customSuccessHandler;
private final JWTUtil jwtUtil;
private final RefreshRepository refreshRepository;

public SecurityConfig(CustomOAuth2UserService customOAuth2UserService,
CustomSuccessHandler customSuccessHandler,
JWTUtil jwtUtil,
RefreshRepository refreshRepository) {
this.customOAuth2UserService = customOAuth2UserService;
this.customSuccessHandler = customSuccessHandler;
this.jwtUtil = jwtUtil;
this.refreshRepository = refreshRepository;
}

@Bean
public RoleHierarchy roleHierarchy() {
RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
hierarchy.setHierarchy("""
ROLE_ADMIN > ROLE_MENTEE
ROLE_ADMIN > ROLE_MENTOR
ROLE_MENTEE > ROLE_USER
ROLE_MENTOR > ROLE_USER
""");
return hierarchy;
}


@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors(corsCustomizer -> corsCustomizer.configurationSource(request -> {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(
Arrays.asList("https://localhost:3000", "http://localhost:8080", "http://localhost:3000",
"https://cogo.life", "https://coffeego-ssu.web.app")); // 프론트 서버의 주소들 // 프론트 서버의 주소
configuration.setAllowedMethods(Collections.singletonList("*")); // 모든 요청 메서드 허용
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Collections.singletonList("*")); // 모든 헤더 허용
configuration.setMaxAge(3600L);
configuration.setExposedHeaders(Arrays.asList("Set-Cookie", "Authorization", "Access",
"loginStatus")); // Set-Cookie 및 Authorization 헤더 노출
return configuration;
}))
.csrf(csrf -> csrf.disable()) // CSRF 비활성화
.formLogin(formLogin -> formLogin.disable()) // 폼 로그인 비활성화
.httpBasic(httpBasic -> httpBasic.disable()) // HTTP Basic 인증 비활성화
.oauth2Login(oauth2 -> oauth2
.userInfoEndpoint(userInfoEndpoint -> userInfoEndpoint.userService(customOAuth2UserService))
.successHandler(customSuccessHandler))
.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 모든 OPTIONS 요청에 대해 인증을 요구하지 않음
.requestMatchers("/health-check", "/", "/auth/reissue/**", "/security-check").permitAll()
.requestMatchers(HttpMethod.GET, "/api/v2/mentors/{mentorId}/**").permitAll() // mentorId로 조회
.requestMatchers(HttpMethod.GET, "/api/v2/mentors/part").permitAll() // 파트별 조회.requestMatchers("/api/v2/users/**", "/auth/**").hasRole("USER")
.requestMatchers("/auth/reissue/mobile/**").permitAll()
.requestMatchers("/api/v2/possibleDates/**").hasAnyRole("MENTOR", "MENTEE")
.requestMatchers("/api/v2/mentors/**").hasAnyRole("MENTOR", "MENTEE")
.requestMatchers("/api/v2/applications/**").hasAnyRole("MENTOR", "MENTEE")
.anyRequest().authenticated())
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 세션 정책을 STATELESS로 설정
.addFilterBefore(new CustomLogoutFilter(jwtUtil, refreshRepository), LogoutFilter.class)
.addFilterAfter(new JWTFilter(jwtUtil), OAuth2LoginAuthenticationFilter.class);

return http.build();
}

@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return web -> web.ignoring()
.requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-resources/**");
}
}


Expand Down
10 changes: 6 additions & 4 deletions src/main/java/com/soongsil/CoffeeChat/config/jwt/JWTFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public JWTFilter(JWTUtil jwtUtil) {

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

// 특정 경로들에 대해 필터 로직을 건너뛰도록 설정
if (request.getMethod().equals(HttpMethod.OPTIONS.name())) {
Expand All @@ -37,7 +37,9 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
return;
}
String path = request.getRequestURI();
if (path.startsWith("/health-check") || path.startsWith("/security-check") || path.startsWith("/auth/reissue")||path.startsWith("/login")) {
if (path.startsWith("/health-check") || path.startsWith("/security-check")
|| path.startsWith("/auth/reissue") || path.startsWith("/login")
|| path.matches("^/api/v2/mentors/\\d+$") || path.matches("^/api/v2/mentors/part$")) {
System.out.println("jwt필터 통과로직");
filterChain.doFilter(request, response);
return;
Expand All @@ -63,7 +65,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401 에러 반환
response.setContentType("application/json");
response.getWriter()
.write("{\"error\": \"Access token expired\"}"); //응답 json에 error : access token expired메시지 작성
.write("{\"error\": \"Access token expired\"}"); //응답 json에 error : access token expired메시지 작성
filterChain.doFilter(request, response);

//조건이 해당되면 메소드 종료 (필수)
Expand All @@ -87,7 +89,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse

//스프링 시큐리티 인증 토큰 생성
Authentication authToken = new UsernamePasswordAuthenticationToken(customOAuth2User, null,
customOAuth2User.getAuthorities());
customOAuth2User.getAuthorities());
//세션에 사용자 등록
SecurityContextHolder.getContext().setAuthentication(authToken);

Expand Down

0 comments on commit 4f9eb48

Please sign in to comment.