Spring Security 환경 설정을 구성하기 위한 클래스이다.
/**
* Spring Security 환경 설정을 구성하기 위한 클래스
* 웹 서비스가 로드 될때 Spring Container 의해 관리가 되는 클래스
* 사용자에 대한 '인증', '인가'에 대한 구성을 Bean 메서드로 주입함
*
*/
@Slf4j
@RequiredArgsConstructor
@Configuration // ** 현재 클래스를 (설정 클래스)로 설정
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder(){
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
/* BCrypt : 기본으로 사용. 가장 많이 사용되는 알고리즘.
* SCrypt : 개발자가 직접 필요에 따라 변경 가능.
* Argon2
* PBKDF2
* MD5
* SHA-1, SHA-256 등
*/
}
public class CustomSecurityFilterManager extends AbstractHttpConfigurer<CustomSecurityFilterManager, HttpSecurity>{
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
AuthenticationManager authenticationManager = httpSecurity.getSharedObject(
AuthenticationManager.class
);
httpSecurity.addFilter(new JwtAuthenticationFilter(authenticationManager));
super.configure(httpSecurity);
}
}
/*
* HTTP에 대해서 '인증'과 '인가'를 담당하는 메서드
* 필터를 통해 인증 방식과 인증 절차에 대해서 등록하며 설정을 담당하는 메서드
* */
@Bean // 스프링 빈으로 등록
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// 1. CSRF 해제 - 서버에 인증정보를 저장하지 않기때문에
http.csrf().disable(); // postman 접근해야 함!! - CSR 할때!!
// 2. iframe 거부 설정
http.headers().frameOptions().sameOrigin();
// 3. cors 재설정
http.cors().configurationSource(configurationSource());
// 4. jSessionId 사용 거부
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); // 세션 정책
// 5. form 로긴 해제 (UsernamePasswordAuthenticationFilter 비활성화) (폼 로그인 비활성화)
http.formLogin().disable();
// 6. 로그인 인증창이 뜨지 않게 비활성화(기본 인증 비활성화)
http.httpBasic().disable(); //bearer 방식으로
// 7. 커스텀 필터 적용 (시큐리티 필터 교환) 커스텀 필터 적용
http.apply(new CustomSecurityFilterManager());
// 8. 인증 실패 처리
http.exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
log.warn("인증되지 않은 사용자가 자원에 접근하려 합니다 : " + authException.getMessage());
FilterResponseUtils.unAuthorized(response, new Exception401("인증되지 않았습니다"));
});
// 9. 권한 실패 처리
http.exceptionHandling().accessDeniedHandler((request, response, accessDeniedException) -> {
log.warn("권한이 없는 사용자가 자원에 접근하려 합니다 : " + accessDeniedException.getMessage());
FilterResponseUtils.forbidden(response, new Exception403("권한이 없습니다"));
});
// 10. 인증, 권한 필터 설정 - 경로에 대한 인증 설정
http.authorizeRequests(
authorize -> authorize
.antMatchers("/carts/**", "/options/**", "/orders/**")
.authenticated()
.antMatchers("/admin/**")
.access("hasRole('ADMIN')")
// ("/admin/**")에 대한 요청은 ADMIN권한을 가진 회원만 승인한다.
// 회원 권한을 설정할때 , 반드시 "ROLE_"을 붙여야만 Security가 인식함
.anyRequest().permitAll() //다른 주소는 모두 허용
// 모든 요청에 대해 인증을 요구 하지 않는다
// 위에서 설정한 특정 경로에 대한 권한 인증 확인만 하고 다른 경로는 확인하지 않는다
);
// 12. 로그아웃 관련 설정 (이 부분 추가)
http.logout()
.logoutUrl("/logout")
.logoutSuccessHandler((request, response, authentication) -> {
response.sendRedirect("/");
})
.deleteCookies("jwtToken");
return http.build();
}
// ** 규칙: 헤더(Authorization), 메서드, IP 주소, 클라이언트으 쿠키 요청을 허용
public CorsConfigurationSource configurationSource() {
CorsConfiguration corsConfigurationSource = new CorsConfiguration();
corsConfigurationSource.addAllowedHeader("*"); // 모든 헤더를 허용
corsConfigurationSource.addAllowedMethod("*"); // GET, POST, PUT, DELETE 등의 모든 메서드를 허용
corsConfigurationSource.addAllowedOriginPattern("*"); // 모든 IP주소를 허용
corsConfigurationSource.setAllowCredentials(true); // 클라이언트 쿠키 요청 허용
corsConfigurationSource.addExposedHeader("Authorization"); // 헤더
UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource
= new UrlBasedCorsConfigurationSource();
// ** (/) 들어오는 모든 유형의 URL 패턴을 허용.
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfigurationSource);
return urlBasedCorsConfigurationSource;
}
}
@Configuration: 이 클래스가 구성 클래스임을 나타내는 어노테이션
passwordEncoder() : 패스워드 인코더를 빈으로 등록
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
인증 매니저 빈으로 등록
: 실질적으로는 AuthenticationManager에 등록된 AuthenticationProvider에 의해 인증이 처리됨
http.csrf().disable();
: CSRF 비활성화
http.headers().frameOptions().sameOrigin();
: iframe 거부 설정
http.cors().configurationSource(configurationSource());
: cors 설정
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
: 세션을 사용하지 않음
http.formLogin().disable();
: 폼 로그인 비활성화
http.httpBasic().disable();
: 기본 HTTP 인증 비활성화
http.apply(new CustomSecurityFilterManager());
: 커스텀 필터 적용
인증 및 권한 설정
http.authorizeRequests(
authorize -> authorize
.antMatchers("/petsitter/**","/carts/**", "/options/**", "/orders/**").authenticated()
.antMatchers("/admin/**").access("hasRole('ADMIN')")
.anyRequest().permitAll()
);
.antMatchers("").authenticated(): 해당 경로는 인증이 필요함
.antMatchers("/admin/**").access("hasRole('ADMIN')") : 해당 경로는 ADMIN권한을 가진 사용자만 접근 가능
그외 모든 사용자에게 허용
인증 및 권한 실패 처리
http.exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
// 인증 실패 처리
});
http.exceptionHandling().accessDeniedHandler((request, response, accessDeniedException) -> {
// 권한 실패 처리
});
: 인증 실패 및 권한 실패 시의 처리를 정의
: 인증 실패 시 401응답을 보내고, 권한 실패시 403응답을 보냄
로그아웃 관련
http.logout()
.logoutUrl("/logout")
.logoutSuccessHandler((request, response, authentication) -> {
// 로그아웃 성공 시 처리
})
.deleteCookies("jwtToken");
: 로그아웃 URL을 "/logout"으로 지정하고, 로그아웃 성공 시 처리 및 쿠키 삭제를 설정
public CorsConfigurationSource configurationSource() {
CorsConfiguration corsConfigurationSource = new CorsConfiguration();
corsConfigurationSource.addAllowedHeader("*"); // 모든 헤더를 허용
corsConfigurationSource.addAllowedMethod("*"); // GET, POST, PUT, DELETE 등의 모든 메서드를 허용
corsConfigurationSource.addAllowedOriginPattern("*"); // 모든 IP주소를 허용
corsConfigurationSource.setAllowCredentials(true); // 클라이언트 쿠키 요청 허용
corsConfigurationSource.addExposedHeader("Authorization"); // 헤더
UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource
= new UrlBasedCorsConfigurationSource();
// ** (/) 들어오는 모든 유형의 URL 패턴을 허용.
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfigurationSource);
return urlBasedCorsConfigurationSource;
}
: CORS(Cross-Origin Resource Sharing) 설정을 정의함
: 모든 헤더, 메서드, IP 주소, 클라이언트 쿠키 요청을 허용하도록 설정
CORS(Cross-Origin Resource Sharing)
웹 페이지에서 실행중인 스크립트가 다른 도메인에 있는 리소스에 접근하는 권한을 부여하는 보안기술
동일 출처 정책(same-Origin Policy)에 따라 다른 도메인에서 온 요청에 대한 보안을 강화 함