test master 변경

This commit is contained in:
현성필
2024-01-23 11:24:09 +09:00
parent 75a695897d
commit 91e902af25
121 changed files with 329 additions and 338 deletions
@@ -0,0 +1,15 @@
package com.eactive.testmaster.config;
import com.eactive.testmaster.common.util.SecurityUtil;
import org.springframework.data.domain.AuditorAware;
import java.util.Optional;
public class AuditorAwareImpl implements AuditorAware<String> {
@Override
public Optional<String> getCurrentAuditor() {
return Optional.ofNullable(SecurityUtil.getCurrentUserEsntlId());
}
}
@@ -0,0 +1,60 @@
package com.eactive.testmaster.config;
import com.eactive.testmaster.common.entity.EnabledStatus;
import com.eactive.testmaster.common.exception.UserNotFoundException;
import com.eactive.testmaster.login.controller.LoginController;
import com.eactive.testmaster.user.entity.StaffUser;
import com.eactive.testmaster.user.entity.User;
import com.eactive.testmaster.user.repository.StaffUserRepository;
import com.eactive.testmaster.user.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Service
@Transactional
public class PortalAuthenticationFailureHandler implements AuthenticationFailureHandler {
private static final Logger logger = LoggerFactory.getLogger(PortalAuthenticationFailureHandler.class);
UserService userService;
StaffUserRepository staffUserRepository;
public PortalAuthenticationFailureHandler(UserService userService, StaffUserRepository staffUserRepository) {
this.userService = userService;
this.staffUserRepository = staffUserRepository;
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW, noRollbackFor = {AuthenticationException.class, UserNotFoundException.class})
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException {
String username = request.getParameter("id");
try {
User user = userService.findByUserId(username);
if (user != null) {
user.setLockCnt(user.getLockCnt() + 1);
if (user.getLockCnt() >= 5) {
user.setLockAt(EnabledStatus.Y);
}
staffUserRepository.save((StaffUser) user);
}
} catch (UserNotFoundException e) {
logger.error("{} login try {}", username, e.getMessage());
}
request.getSession().setAttribute(LoginController.LOGIN_MESSAGE, exception.getLocalizedMessage());
String contextPath = request.getContextPath();
response.sendRedirect(contextPath + "/login");
}
}
@@ -0,0 +1,56 @@
package com.eactive.testmaster.config;
import com.eactive.testmaster.common.util.EncryptionUtil;
import com.eactive.testmaster.user.entity.User;
import com.eactive.testmaster.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class PortalAuthenticationManager implements AuthenticationManager {
@Autowired
private UserService userService;
@Autowired
private EncryptionUtil encryptionUtil;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication;
String username = token.getName();
String password = token.getCredentials().toString();
String encryptPassword = encryptionUtil.encryptPassword(password, username);
UserDetails user = userService.loadUserByUsername(username);
if (!user.isEnabled()) {
throw new DisabledException("계정이 " + ((User) user).getStatus().getDescription() + "상태입니다. 관리자에게 문의하세요.");
}
if (!user.isAccountNonLocked()) {
throw new LockedException("계정이 잠겨있습니다. 관리자에게 문의하세요.");
}
if (user.getPassword().equals(encryptPassword)) {
UsernamePasswordAuthenticationToken authorityToken = new UsernamePasswordAuthenticationToken(user, password, user.getAuthorities());
authorityToken.setDetails(user);
SecurityContextHolder.getContext().setAuthentication(authorityToken);
return authorityToken;
}
throw new BadCredentialsException("아이디 또는 비밀번호가 일치하지 않습니다.");
}
}
@@ -0,0 +1,43 @@
package com.eactive.testmaster.config;
import com.eactive.testmaster.user.entity.User;
import com.eactive.testmaster.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Service
@Transactional
public class PortalAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Autowired
UserService userService;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
String username = request.getParameter("id");
UserDetails user = userService.loadUserByUsername(username);
((User) user).setLockCnt(0);
userService.updateUser((User) user);
String contextPath = request.getContextPath();
response.sendRedirect(contextPath + "/mgmt/routes/list_view.do");
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException, ServletException {
AuthenticationSuccessHandler.super.onAuthenticationSuccess(request, response, chain, authentication);
}
}
@@ -0,0 +1,37 @@
package com.eactive.testmaster.config;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.envers.repository.support.EnversRevisionRepositoryFactoryBean;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
/**
* @author
* @version : 1.0
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------------- ------------ ---------------------
*
* </pre>
* @ClassName : PortalConfigAppDatasource.java
* @Description : DataSource 설정
* @since :
*/
@Configuration
@EnableJpaRepositories(basePackages = "com.eactive", repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)
@EntityScan(basePackages = "com.eactive")
@EnableJpaAuditing(auditorAwareRef = "auditorProvider")
public class PortalConfigAppDatasource {
@Bean
public AuditorAware<String> auditorProvider() {
return new AuditorAwareImpl();
}
}
@@ -0,0 +1,40 @@
package com.eactive.testmaster.config;
import com.eactive.testmaster.common.message.PortalReloadableResourceBundleMessageSource;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
/**
* @author
* @version : 1.0
* @ClassName : PortalConfigMessageSource.java
* @Description : Portal Message 설정
* @since : 2021. 7. 20
*/
@Configuration
public class PortalConfigMessageSource {
/**
* @return [Resource 설정] 메세지 Properties 경로 설정
*/
@Bean
public ReloadableResourceBundleMessageSource messageSource() {
PortalReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource = new PortalReloadableResourceBundleMessageSource();
reloadableResourceBundleMessageSource.setEgovBaseNames(
"classpath*:message/**/*",
"classpath:/org/egovframe/rte/fdl/idgnr/messages/idgnr",
"classpath:/org/egovframe/rte/fdl/property/messages/properties");
return reloadableResourceBundleMessageSource;
}
@Bean
public LocalValidatorFactoryBean validator(MessageSource messageSource) {
LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
factoryBean.setValidationMessageSource(messageSource);
return factoryBean;
}
}
@@ -0,0 +1,74 @@
package com.eactive.testmaster.config;
import com.navercorp.lucy.security.xss.servletfilter.XssEscapeServletFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
@EnableWebSecurity
public class PortalConfigSecurity extends WebSecurityConfigurerAdapter {
private final PortalAuthenticationFailureHandler authenticationFailureHandler;
private final PortalAuthenticationSuccessHandler authenticationSuccessHandler;
private final PortalAuthenticationManager portalAuthenticationManager;
@Autowired
public PortalConfigSecurity(PortalAuthenticationFailureHandler authenticationFailureHandler,
PortalAuthenticationSuccessHandler authenticationSuccessHandler,
PortalAuthenticationManager portalAuthenticationManager) {
this.authenticationFailureHandler = authenticationFailureHandler;
this.authenticationSuccessHandler = authenticationSuccessHandler;
this.portalAuthenticationManager = portalAuthenticationManager;
}
@Bean
public FilterRegistrationBean<XssEscapeServletFilter> xssFilterRegistrationBean() {
FilterRegistrationBean<XssEscapeServletFilter> registrationBean = new FilterRegistrationBean<>();
XssEscapeServletFilter xssEscapeServletFilter = new XssEscapeServletFilter();
registrationBean.setFilter(xssEscapeServletFilter);
registrationBean.setOrder(Integer.MIN_VALUE + 1);
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().disable();//spring security 와 h2-console 같이 사용.
http
.formLogin()
.loginPage("/login")
.usernameParameter("id")
.passwordParameter("password")
.loginProcessingUrl("/actionLogin.do")
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.and()
.logout().logoutUrl("/actionLogout.do").logoutSuccessUrl("/")
.and().authorizeRequests() // 권한요청 처리 설정 메서드
.antMatchers("/h2-console/**").permitAll() // 누구나 h2-console 접속 허용
.and()
.csrf()
.requireCsrfProtectionMatcher(new AntPathRequestMatcher("/mgmt/**", "POST"))
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
@Override
@Bean
public PortalAuthenticationManager authenticationManager() {
return portalAuthenticationManager;
}
}
@@ -0,0 +1,28 @@
package com.eactive.testmaster.config;
import org.apache.catalina.connector.Connector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ServletConfig {
@Value("${server.port.http}")
private int serverPortHttp;
@Bean
public ServletWebServerFactory serverFactory() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addAdditionalTomcatConnectors(createStandardConnector());
return tomcat;
}
private Connector createStandardConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setPort(serverPortHttp);
return connector;
}
}
@@ -0,0 +1,97 @@
package com.eactive.testmaster.config;
import com.eactive.testmaster.common.interceptor.AuthenticInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.http.CacheControl;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.resource.PathResourceResolver;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
WebMvcConfigurer.super.addViewControllers(registry);
}
private List<String> listAdminAuthPattern() {
List<String> patterns = new ArrayList<>();
patterns.add("/mgmt/users/*.do");
patterns.add("/mgmt/servers/*.do");
return patterns;
}
@Bean
public AuthenticInterceptor authenticInterceptor() {
AuthenticInterceptor authenticInterceptor = new AuthenticInterceptor();
authenticInterceptor.setAdminAuthPatternList(listAdminAuthPattern());
return authenticInterceptor;
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(pageableHandlerMethodArgumentResolver());
}
@Bean
public PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver() {
PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver = new PageableHandlerMethodArgumentResolver();
pageableHandlerMethodArgumentResolver.setOneIndexedParameters(true); //1부터 시작
pageableHandlerMethodArgumentResolver.setFallbackPageable(PageRequest.of(0, 10)); //파라미터 없을 때 기본 페이지
return pageableHandlerMethodArgumentResolver;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authenticInterceptor())
.addPathPatterns(
"/",
"/mgmt/**/*.do")
.excludePathPatterns(
"/h2-console/**",
"/css/**",
"/html/**",
"/images/**",
"/img/**",
"/js/**",
"/login",
"/intro.do",
"/join.do",
"/user_register.do",
"/actionLogin.do",
"/check_id.do",
"/search_id.do",
"/admin_register_view.do",
"/admin_register.do",
"/request_register_auth.do",
"/reset_password.do",
"/forgot_password.do"
);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**").addResourceLocations("/css/", "classpath:/static/css/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver());
registry.addResourceHandler("/fonts/**").addResourceLocations("/fonts/", "classpath:/static/fonts/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver());
registry.addResourceHandler("/font/**").addResourceLocations("/font/", "classpath:/static/fonts/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver());
registry.addResourceHandler("/html/**").addResourceLocations("/html/", "classpath:/static/html/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver());
registry.addResourceHandler("/images/**").addResourceLocations("/images/", "classpath:/static/images/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver());
registry.addResourceHandler("/img/**").addResourceLocations("/img/", "classpath:/static/img/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver());
registry.addResourceHandler("/js/**").addResourceLocations("/js/", "classpath:/static/js/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver());
registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/", "classpath:/static/plugins/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver());
registry.addResourceHandler("/favicon.ico").addResourceLocations("/favicon.ico", "classpath:/static/favicon.ico").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver());
}
}