package com.dbnt.faisp.config;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.servlet.http.HttpServletResponse;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig{
private final Logger log = LoggerFactory.getLogger(getClass());
@Bean
public PasswordEncoder passwordEncoder(){
return new Pbkdf2PasswordEncoder();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/css/**", "/img/**", "/js/**", "/vendor/**");
}
@Bean
public AccessDeniedHandler accessDeniedHandler() {
log.warn("accessDeniedHandler");
return (request, response, e) -> {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.setContentType("text/html;charset=UTF-8");
response.getWriter().println("");
response.getWriter().flush();
response.getWriter().close();
};
}
@Bean
public AuthenticationEntryPoint authenticationEntryPoint() {
return (request, response, e) -> {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("text/html;charset=UTF-8");
response.getWriter().println("");
response.getWriter().flush();
response.getWriter().close();
};
}
@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests() // 페이지 권한 설정
.antMatchers(
"/dashboard",
"/refreshSession"
).hasRole(Role.USER.name()) // USER, ADMIN 접근 허용
.antMatchers(
"/codeMgt/**",
"/menuMgt/**"
).hasRole(Role.ADMIN.name()) // ADMIN만 접근 허용
.antMatchers(
"/authMgt/**",
"/userMgt/**",
"/organMgt/**"
).hasRole(Role.SUB_ADMIN.name()) // SUB_ADMIN만 접근 허용
.antMatchers("/login").permitAll() // 로그인 페이지는 권한 없이 접근 허용
.and() // 로그인 설정
.formLogin().loginPage("/login") // Custom login form 사용
.failureUrl("/login-error") // 로그인 실패 시 이동
.defaultSuccessUrl("/") // 로그인 성공 시 이동
/*.failureHandler((request, response, exception) -> {
}) // 로그인 실패시 동작 수행
.successHandler((request, response, authentication) -> {
SavedRequest savedRequest = new HttpSessionRequestCache().getRequest(request,response);
if(savedRequest != null){
String targetUrl = savedRequest.getRedirectUrl();
new DefaultRedirectStrategy().sendRedirect(request,response,targetUrl);
}else{
new DefaultRedirectStrategy().sendRedirect(request,response,"/");
}
}) // 로그인 성공시 동작 수행.*/
.and() // 로그아웃 설정
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")) // 로그아웃 시 URL 재정의
.logoutSuccessUrl("/") // 로그아웃 성공 시 redirect 이동
.invalidateHttpSession(true) // HTTP Session 초기화
.deleteCookies("JSESSIONID") // 특정 쿠키 제거
.and() // 403 예외처리 핸들링
//.exceptionHandling().accessDeniedPage("/denied");
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler())
.authenticationEntryPoint(authenticationEntryPoint());
return http.build();
}
}