Skip to content

Commit

Permalink
Merge pull request #204 from Soongsil-CoffeeChat/feat/#177
Browse files Browse the repository at this point in the history
config파일들 재정리
  • Loading branch information
KimKyoHwee authored Jan 2, 2025
2 parents 24d9f95 + a67ae63 commit 11aa3a3
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 223 deletions.
23 changes: 13 additions & 10 deletions src/main/java/com/soongsil/CoffeeChat/config/CorsMvcConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsMvcConfig implements WebMvcConfigurer { //컨트롤러에서 보내는 데이터를 받을수 있게끔
public class CorsMvcConfig implements WebMvcConfigurer {

@Override
public void addCorsMappings(CorsRegistry corsRegistry) {

corsRegistry.addMapping("/**") //모든 경로에서 매핑 진행
.exposedHeaders("Set-Cookie") //노출할 헤더값은 쿠키헤더"
.allowedOrigins("https://localhost:3000", "https://cogo.life", "https://coffeego-ssu.web.app",
"http://localhost:8080", "http://localhost:3000")
.allowedMethods("OPTIONS", "GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
corsRegistry.addMapping("/**")
.allowedOrigins(
"https://localhost:3000",
"http://localhost:8080",
"https://cogo.life",
"https://coffeego-ssu.web.app",
"https://accounts.google.co.kr")
.allowedMethods("OPTIONS", "GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.exposedHeaders("Set-Cookie", "Authorization", "loginStatus")
.allowCredentials(true)
.maxAge(3600);
}
}

131 changes: 15 additions & 116 deletions src/main/java/com/soongsil/CoffeeChat/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,23 @@ public RoleHierarchy roleHierarchy() {
return hierarchy;
}


@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors(corsCustomizer -> corsCustomizer.configurationSource(request -> {
.cors(cors -> cors.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.setAllowedOrigins(Arrays.asList(
"https://localhost:3000",
"http://localhost:8080",
"https://cogo.life",
"https://coffeego-ssu.web.app",
"https://accounts.google.co.kr"
));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Collections.singletonList("*"));
configuration.setExposedHeaders(Arrays.asList("Set-Cookie", "Authorization", "Access", "loginStatus"));
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 비활성화
Expand All @@ -79,18 +81,18 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.userInfoEndpoint(userInfoEndpoint -> userInfoEndpoint.userService(customOAuth2UserService))
.successHandler(customSuccessHandler))
.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 모든 OPTIONS 요청에 대해 인증을 요구하지 않음
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.requestMatchers("/health-check", "/", "/auth/reissue/**", "/security-check", "/reissue").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(HttpMethod.GET, "/api/v2/mentors/{mentorId}/**").permitAll()
.requestMatchers(HttpMethod.GET, "/api/v2/mentors/part").permitAll()
.requestMatchers("/auth/reissue/mobile/**").permitAll()
.requestMatchers("/auth/issue/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로 설정
.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.addFilterBefore(new CustomLogoutFilter(jwtUtil, refreshRepository), LogoutFilter.class)
.addFilterAfter(new JWTFilter(jwtUtil), OAuth2LoginAuthenticationFilter.class);

Expand All @@ -104,106 +106,3 @@ public WebSecurityCustomizer webSecurityCustomizer() {
}
}




/*
@Configuration
@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\n"+
"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(Collections.singletonList("http://localhost:3000")); //프론트 서버의 주소
configuration.setAllowedMethods(Collections.singletonList("*")); //GET, POST, PUT등 모든 요청 허용
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Collections.singletonList("*")); //모든 헤더 허용
configuration.setMaxAge(3600L);
configuration.setExposedHeaders(
Collections.singletonList("Set-Cookie")); //우리가 줄 데이터를 웹페이지에서 보이게 하기
configuration.setExposedHeaders(Collections.singletonList("Authorization"));
return configuration;
}));
//csrf disable : stateless이기 때문에 끄기
http
.csrf((auth) -> auth.disable());
//From 로그인 방식 disable
http
.formLogin((auth) -> auth.disable());
//HTTP Basic 인증 방식 disable
http
.httpBasic((auth) -> auth.disable());
//특정 필터 이전에 JWTFilter 추가
//기본으로 설정되어있는 LogoutFilter 바로 앞에 커스텀한 LogoutFilter 추가
http
.addFilterBefore(new CustomLogoutFilter(jwtUtil, refreshRepository), LogoutFilter.class);
http
.addFilterAfter(new JWTFilter(jwtUtil), OAuth2LoginAuthenticationFilter.class);
//oauth2로그인 (인증이 완료되면 리소스 서버로부터 데이터를 받아서 OAuth2UserService로 전달)
//로그인 성공시 customSuccessHandler 호출
http
.oauth2Login((oauth2) -> oauth2
.userInfoEndpoint((userInfoEndpointConfig) -> userInfoEndpointConfig
.userService(customOAuth2UserService))
.successHandler(customSuccessHandler)
);
http
.addFilterBefore(new CustomLogoutFilter(jwtUtil, refreshRepository), LogoutFilter.class);
//경로별 인가 작업
http //기본경로 "/" 제외한 나머지는 로그인해야만 사용가능
.authorizeHttpRequests((auth) -> auth
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() //preflight처리
.requestMatchers("/health-check", "/", "reissue").permitAll()
.requestMatchers("/api/v1/user/**", "auth/**").hasRole("USER")
//.requestMatchers("/api/v1/**").hasAnyRole("MENTEE", "MENTOR") //로그인 제외하면 다 멘티나 멘토 아니면 접근불가
.requestMatchers("api/v1/possibleDate/**").hasRole("MENTOR")
.requestMatchers("api/v1/mentor/**").hasRole("MENTEE")
.anyRequest().authenticated());
//세션 설정 : STATELESS (JWT로 인증 인가 사용할 것이므로)
http
.sessionManagement((session) -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
return http.build();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring()
.requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-resources/**");
}
}
*/
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
import java.util.Date;
import java.util.Iterator;

//로그인이 성공했을 때 받은 데이터들을 바탕으로 JWT발급을 위한 핸들러
/*
@Component
public class CustomSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
private final JWTUtil jwtUtil;
Expand All @@ -48,125 +46,37 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
Authentication authentication) throws IOException, ServletException {

CustomOAuth2User customUserDetails = (CustomOAuth2User) authentication.getPrincipal();
String username = customUserDetails.getUsername();
String role = authentication.getAuthorities().iterator().next().getAuthority();

Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
Iterator<? extends GrantedAuthority> iterator = authorities.iterator();
GrantedAuthority auth = iterator.next();
String role = auth.getAuthority();
//String accessToken = jwtUtil.createJwt("access", username, role, 600000L); // 10분
String accessToken = jwtUtil.createJwt("access", username, role, 180000L); // 10분
System.out.println("accessToken = " + accessToken);
String refreshToken = jwtUtil.createJwt("refresh", username, role, 86400000L); // 24시간
String accessToken = jwtUtil.createJwt("access", username, role, 600000L);
String refreshToken = jwtUtil.createJwt("refresh", username, role, 86400000L);

addRefreshEntity(username, refreshToken, 86400000L);

System.out.println("=====쿠키쿠키=====");
// Refresh 토큰 쿠키에 추가
// Add Cookies
addSameSiteCookie(response, "refresh", refreshToken);
System.out.println("리프레쉬: " + refreshToken);
System.out.println("=====쿠키쿠키=====");
// loginStatus 쿠키 추가
if (role.equals("ROLE_USER")) {
addSameSiteCookie(response, "loginStatus", "signup");
} else if (role.equals("ROLE_MENTEE") || role.equals("ROLE_MENTOR")) {
addSameSiteCookie(response, "loginStatus", "main");
}
addSameSiteCookie(response, "loginStatus", role.equals("ROLE_USER") ? "signup" : "main");

response.setStatus(HttpStatus.OK.value());
//response.sendRedirect("http://localhost:8080/swagger-ui/index.html"); //서버 로컬 테스트용
//response.sendRedirect("https://localhost:3000/callback");
response.sendRedirect("https://coffeego-ssu.web.app/callback");
}

private void addSameSiteCookie(HttpServletResponse response, String name, String value) {
ResponseCookie responseCookie = ResponseCookie.from(name, value)
.domain("coffeego-ssu.web.app")
.httpOnly(true)
.secure(true)
.path("/")
.maxAge(24 * 60 * 60)
.sameSite("None")
.build();
response.addHeader("Set-Cookie", responseCookie.toString());
}
}
*/
@Component
public class CustomSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
private final JWTUtil jwtUtil;
private final RefreshRepository refreshRepository;

public CustomSuccessHandler(JWTUtil jwtUtil, RefreshRepository refreshRepository) {
this.jwtUtil = jwtUtil;
this.refreshRepository = refreshRepository;
}

private void addRefreshEntity(String username, String refresh, Long expiredMs) {
Date date = new Date(System.currentTimeMillis() + expiredMs);

Refresh refreshEntity = new Refresh();
refreshEntity.setUsername(username);
refreshEntity.setRefresh(refresh);
refreshEntity.setExpiration(date.toString());

refreshRepository.save(refreshEntity);
}

@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {

CustomOAuth2User customUserDetails = (CustomOAuth2User)authentication.getPrincipal();

String username = customUserDetails.getUsername();

Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
Iterator<? extends GrantedAuthority> iterator = authorities.iterator();
GrantedAuthority auth = iterator.next();
String role = auth.getAuthority();

//String accessToken = jwtUtil.createJwt("access", username, role, 600000L); // 10분
String accessToken = jwtUtil.createJwt("access", username, role, 180000L); // 10분
System.out.println("accessToken = " + accessToken);
String refreshToken = jwtUtil.createJwt("refresh", username, role, 86400000L); // 24시간

addRefreshEntity(username, refreshToken, 86400000L);

// Refresh 토큰 쿠키에 추가
addSameSiteCookie(response, "refresh", refreshToken);

// loginStatus 쿠키 추가
if (role.equals("ROLE_USER")) {
addSameSiteCookie(response, "loginStatus", "signup");
} else if (role.equals("ROLE_MENTEE") || role.equals("ROLE_MENTOR")) {
addSameSiteCookie(response, "loginStatus", "main");
}

response.setStatus(HttpStatus.OK.value());
//response.sendRedirect("http://localhost:8080/swagger-ui/index.html"); //서버 로컬 테스트용
//response.sendRedirect("https://localhost:3000/callback");
response.sendRedirect("https://coffeego-ssu.web.app/callback");
}

private void addSameSiteCookie(HttpServletResponse response, String name, String value) {
ResponseCookie responseCookie = ResponseCookie.from(name, value)
.httpOnly(true)
.secure(true)
.maxAge(24 * 60 * 60)
.domain(".coffeego-ssu.web.app")
.path("/")
.sameSite("None")
.maxAge(24 * 60 * 60)
.build();

response.addHeader("Set-Cookie", responseCookie.toString());
}
}


/*
package com.soongsil.CoffeeChat.config.oauth2;
Expand Down

0 comments on commit 11aa3a3

Please sign in to comment.