
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
package com.takensoft.common.config;
import com.takensoft.cms.accesCtrl.service.AccesCtrlService;
import com.takensoft.cms.mber.service.LgnHstryService;
import com.takensoft.cms.mber.service.RefreshTokenService;
import com.takensoft.common.filter.AccesFilter;
import com.takensoft.common.filter.JWTFilter;
import com.takensoft.common.filter.LoginFilter;
import com.takensoft.common.util.CommonUtils;
import com.takensoft.common.exception.CustomAccessDenieHandler;
import com.takensoft.common.exception.CustomAuthenticationEntryPoint;
import com.takensoft.common.util.JWTUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Collections;
/**
* @author takensoft
* @since 2024.04.01
*
* 스프링 시큐리티 설정
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig {
// AuthenticationManager가 인자로 받을 AuthenticationConfiguration 객체 생성자 주입
private final AuthenticationConfiguration authenticationConfiguration;
private final JWTUtil jwtUtil;
private final RefreshTokenService refreshTokenService;
private final LgnHstryService lgnHstryService;
private final AccesCtrlService accesCtrlService;
private final CustomAuthenticationEntryPoint authenticationEntryPoint;
private final CustomAccessDenieHandler accessDenieHandler;
private final CommonUtils commonUtils;
private final CommonConfig commonConfig;
private static String FRONT_URL; // 프론트 접근 허용 URL
private static long JWT_ACCESSTIME; // access 토큰 유지 시간
private static long JWT_REFRESHTIME; // refresh 토큰 유지 시간
private static int COOKIE_TIME; // 쿠키 유지 시간
public SecurityConfig(AuthenticationConfiguration authenticationConfiguration, JWTUtil jwtUtil, RefreshTokenService refreshTokenService, AccesCtrlService accesCtrlService, CommonConfig commonConfig,
LgnHstryService lgnHstryService, CustomAuthenticationEntryPoint authenticationEntryPoint, CustomAccessDenieHandler accessDenieHandler, CommonUtils commonUtils,
@Value("${front.url}")String fUrl,@Value("${jwt.accessTime}")long aTime, @Value("${jwt.refreshTime}")long rTime, @Value("${cookie.time}")int ctime) {
this.authenticationConfiguration = authenticationConfiguration;
this.refreshTokenService = refreshTokenService;
this.lgnHstryService = lgnHstryService;
this.accesCtrlService = accesCtrlService;
this.authenticationEntryPoint = authenticationEntryPoint;
this.accessDenieHandler = accessDenieHandler;
this.jwtUtil = jwtUtil;
this.commonUtils = commonUtils;
this.commonConfig = commonConfig;
this.FRONT_URL = fUrl;
this.JWT_ACCESSTIME = aTime;
this.JWT_REFRESHTIME = rTime;
this.COOKIE_TIME = ctime;
}
// AuthenticationManager Bean 등록
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
return configuration.getAuthenticationManager();
}
// 해시 암호화
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.cors((cors) -> cors
.configurationSource(new CorsConfigurationSource() {
@Override
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Collections.singletonList(FRONT_URL)); // 허용할 프론트 포트 포함 경로 입력
configuration.setAllowedMethods(Collections.singletonList("*")); // 허용할 메소드(GET, POST, PUT 등)
configuration.setAllowedHeaders(Collections.singletonList("*")); // 허용할 헤드
configuration.setAllowCredentials(true); // 프론트에서 credentials 설정하면 true
configuration.setMaxAge(3600L); // 허용을 물고 있을 시간
configuration.setExposedHeaders(Collections.singletonList("Authorization")); // 서버에서 JWT를 Authorization에 담아 보내기 위해 허용을 함
return configuration;
}
})
);
// csrf disable
http.csrf((auth) -> auth.disable());
// formLogin disable
http.formLogin((auth) -> auth.disable());
// http basic 인증 방식 disable
http.httpBasic((auth) -> auth.disable());
// 세션 설정
http.sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
http.exceptionHandling((exception) -> exception
.authenticationEntryPoint(authenticationEntryPoint) // 접근 권한이 없는 경우에 호출
.accessDeniedHandler(accessDenieHandler) // 인증되지 않은 상태로 접근 했을 때 호출
);
http.authorizeHttpRequests((auth) -> auth
.requestMatchers("/", "/mbr/**", "/company/**", "/refresh/**", "/sys/**").permitAll() // 회원관련, 시스템 제공 관련, 기업용페이지는 누구나 접근 가능
.requestMatchers("/admin/**").hasRole("ADMIN") // 관리자 페이지는 ADMIN 권한을 가진 사용자만 접근 가능
.requestMatchers("/editFileUpload/**", "/fileUpload/**").permitAll() // 에디터 파일 업로드
.anyRequest().authenticated() // 그 외에는 로그인한 사용자만 접근 가능
// .anyRequest().permitAll() // 모든 사용자 접근 가능
);
http.addFilterBefore(new JWTFilter(jwtUtil, commonConfig), LoginFilter.class); // 토큰 검증 필터
http.addFilterBefore(new AccesFilter(accesCtrlService, commonUtils, commonConfig), JWTFilter.class); // 아이피 검증
http.addFilterAt(new LoginFilter(authenticationManager(authenticationConfiguration), jwtUtil, refreshTokenService, lgnHstryService, commonUtils,
commonConfig, JWT_ACCESSTIME, JWT_REFRESHTIME, COOKIE_TIME), UsernamePasswordAuthenticationFilter.class); // 로그인 필터
return http.build();
}
}