From af3f82270268cb54beadcaafc1e335a070c8b108 Mon Sep 17 00:00:00 2001 From: mjkhan21 Date: Sun, 11 Jun 2023 17:02:32 +0900 Subject: [PATCH] =?UTF-8?q?=EC=B5=9C=EC=B4=88=20=EC=BB=A4=EB=B0=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 127 +++++++++++++++ .../java/cokr/xit/base/boot/MvcConfig2.java | 39 +++++ .../cokr/xit/base/boot/SecurityConfig.java | 145 ++++++++++++++++++ .../xit/base/boot/XitBaseApplication.java | 14 ++ .../java/cokr/xit/base/boot/XitBaseTest.java | 8 + .../java/cokr/xit/base/boot/package-info.java | 6 + 6 files changed, 339 insertions(+) create mode 100644 pom.xml create mode 100644 src/main/java/cokr/xit/base/boot/MvcConfig2.java create mode 100644 src/main/java/cokr/xit/base/boot/SecurityConfig.java create mode 100644 src/main/java/cokr/xit/base/boot/XitBaseApplication.java create mode 100644 src/main/java/cokr/xit/base/boot/XitBaseTest.java create mode 100644 src/main/java/cokr/xit/base/boot/package-info.java diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..415d16b --- /dev/null +++ b/pom.xml @@ -0,0 +1,127 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.7.12 + + + + cokr.xit.boot + xit-base-starter + 23.04.01-SNAPSHOT + jar + xit-base-starter + xit-base module for Spring Boot + + + 17 + ${java.version} + ${java.version} + + + + + mvn2 + http://repo1.maven.org/maven2/ + + true + + + true + + + + egovframe + http://www.egovframe.go.kr/maven/ + + true + + + false + + + + egovframe2 + http://maven.egovframe.kr:8080/maven/ + + true + + + false + + + + maven-public + http://xit.xit-nexus.com:8081/repository/maven-public/ + + + + + + + + cokr.xit.boot + xit-foundation-starter + 23.04.01-SNAPSHOT + + + + cokr.xit.base + xit-base + 23.04.01-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security + spring-security-test + test + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + **/*.class + + + + + + + + + maven-snapshot + http://xit.xit-nexus.com:8081/repository/maven-snapshots/ + + + + maven-release + http://xit.xit-nexus.com:8081/repository/maven-releases/ + + + + \ No newline at end of file diff --git a/src/main/java/cokr/xit/base/boot/MvcConfig2.java b/src/main/java/cokr/xit/base/boot/MvcConfig2.java new file mode 100644 index 0000000..db3e6fe --- /dev/null +++ b/src/main/java/cokr/xit/base/boot/MvcConfig2.java @@ -0,0 +1,39 @@ +package cokr.xit.base.boot; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; + +import cokr.xit.base.file.web.DownloadView; +import cokr.xit.base.menu.web.MenuInjector; +import cokr.xit.foundation.boot.MvcConfig; + +/**web mvc 설정(기존 dispatcher servlet) 클래스 + * @author mjkhan + */ +@Configuration +public class MvcConfig2 extends MvcConfig { + /**MenuInjector를 반환한다. + * @return MenuInjector + */ + @Bean + public MenuInjector menuInjector() { + return new MenuInjector(); + } + + /**MenuInjector를 interceptor로 추가한다. + */ + @Override + public void addInterceptors(InterceptorRegistry registry) { + super.addInterceptors(registry); + registry.addInterceptor(menuInjector()).addPathPatterns(URL_PATTERNS); + } + + /**DownloadView를 반환한다. + * @return DownloadView + */ + @Bean + public DownloadView downloadView() { + return new DownloadView(); + } +} \ No newline at end of file diff --git a/src/main/java/cokr/xit/base/boot/SecurityConfig.java b/src/main/java/cokr/xit/base/boot/SecurityConfig.java new file mode 100644 index 0000000..f058704 --- /dev/null +++ b/src/main/java/cokr/xit/base/boot/SecurityConfig.java @@ -0,0 +1,145 @@ +package cokr.xit.base.boot; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.authorization.AuthorizationManager; +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.web.SecurityFilterChain; +import org.springframework.security.web.access.intercept.RequestAuthorizationContext; + +import cokr.xit.base.security.access.ApplicationAccess; +import cokr.xit.base.security.authentication.service.bean.AuthenticationServiceBean; +import cokr.xit.base.security.authentication.service.bean.PasswordEncoder; +import cokr.xit.base.security.authentication.web.AuthenticationExtraDetailsSource; +import cokr.xit.base.security.authentication.web.AuthenticationFailure; +import cokr.xit.base.security.authentication.web.AuthenticationSuccess; +import cokr.xit.base.security.authentication.web.LogoutSuccess; +import cokr.xit.foundation.web.ExceptionController; + +/**spring security 관련 설정 클래스 + * @author mjkhan + */ +@Configuration +@EnableWebSecurity +public class SecurityConfig { + /**SecurityFilterChain을 반환한다. + * @param http http-security 설정 + * @return SecurityFilterChain + * @throws Exception + */ + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http.authorizeHttpRequests(conf -> + conf.antMatchers("/resources/**", "/login.do", "/logout.do", "/error/*.do").permitAll() + .antMatchers("/**/*.do").access(authorizationManager()) + .anyRequest().authenticated() + ) + .formLogin(conf -> + conf.loginPage("/login.do") + .usernameParameter("account") + .passwordParameter("password") + .loginProcessingUrl("/login.do") + .authenticationDetailsSource(authenticationDetailsSource()) + .successHandler(authenticationSuccess()) + .failureHandler(authenticationFailure()) + ) + .logout(conf -> + conf.logoutUrl("/logout.do") + .logoutSuccessHandler(logoutSuccess()) + ) + .sessionManagement(conf -> + conf.invalidSessionUrl("/error/invalidSession.do") + .sessionConcurrency(config -> + config.expiredUrl("/error/sessionExpired.do") + ) + ) + .authenticationManager(authenticationManager()) + .exceptionHandling().accessDeniedHandler((hreq, hresp, e) -> + exceptionController.accessDenied(hreq, hresp) + ); + + return http.build(); + } + + @Autowired + private ExceptionController exceptionController; + + /**WebSecurityCustomizer를 반환한다.
+ * 모든 정적 파일에 대한 접근 url은 /resources/**로 한다. + * @return WebSecurityCustomizer + */ + @Bean + public WebSecurityCustomizer webSecurityCustomizer() { + return conf -> conf.ignoring().antMatchers("/resources/**"); + } + + /**AuthenticationSuccess(로그인 성공 핸들러)를 반환한다. + * @return AuthenticationSuccess + */ + @Bean + public AuthenticationSuccess authenticationSuccess() { + return new AuthenticationSuccess(); + } + + /**AuthenticationFailure(로그인 실패 핸들러)를 반환한다. + * @return AuthenticationFailure + */ + @Bean + public AuthenticationFailure authenticationFailure() { + return new AuthenticationFailure(); + } + + /**LogoutSuccess(로그아웃 성공 핸들러)를 반환한다. + * @return LogoutSuccess + */ + @Bean + public LogoutSuccess logoutSuccess() { + return new LogoutSuccess(); + } + + /**AuthenticationExtraDetailsSource(사용자 인증 시 필요한 정보 핸들러)를 반환한다. + * @return AuthenticationExtraDetailsSource + */ + @Bean + public AuthenticationExtraDetailsSource authenticationDetailsSource() { + return new AuthenticationExtraDetailsSource(); + } + + /**PasswordEncoder를 반환한다. + * @return PasswordEncoder + */ + @Bean + public PasswordEncoder passwordEncoder() { + return new PasswordEncoder(); + } + + /**AuthenticationServiceBean(인증 서비스)를 반환한다. + * @return AuthenticationServiceBean + */ + @Bean + public AuthenticationServiceBean authenticationService() { + AuthenticationServiceBean bean = new AuthenticationServiceBean(); + bean.setPasswordEncoder(passwordEncoder()); + return bean; + } + + /**ProviderManager(인증 서비스 제공자)를 반환한다. + * @return ProviderManager + */ + @Bean + public ProviderManager authenticationManager() { + return new ProviderManager(authenticationService()); + } + + /**AuthorizationManager(접근 관리자)를 반환한다. + * @return AuthorizationManager + */ + @Bean + public AuthorizationManager authorizationManager() { + return new ApplicationAccess(); + } +} \ No newline at end of file diff --git a/src/main/java/cokr/xit/base/boot/XitBaseApplication.java b/src/main/java/cokr/xit/base/boot/XitBaseApplication.java new file mode 100644 index 0000000..c5f4362 --- /dev/null +++ b/src/main/java/cokr/xit/base/boot/XitBaseApplication.java @@ -0,0 +1,14 @@ +package cokr.xit.base.boot; + +import org.springframework.context.annotation.Import; + +import cokr.xit.foundation.boot.FoundationApplication; + +/**xit-base 모듈에 의존하는 spring boot 애플리케이션의 베이스 클래스 + * @author mjkhan + */ +@Import({ + MvcConfig2.class, + SecurityConfig.class, +}) +public class XitBaseApplication extends FoundationApplication {} \ No newline at end of file diff --git a/src/main/java/cokr/xit/base/boot/XitBaseTest.java b/src/main/java/cokr/xit/base/boot/XitBaseTest.java new file mode 100644 index 0000000..8d24e97 --- /dev/null +++ b/src/main/java/cokr/xit/base/boot/XitBaseTest.java @@ -0,0 +1,8 @@ +package cokr.xit.base.boot; + +import cokr.xit.foundation.boot.FoundationTest; + +/**Spring Boot에서 xit-base를 사용하는 클래스의 단위 테스트 작성을 위한 베이스 클래스. + * @author mjkhan + */ +public class XitBaseTest extends FoundationTest {} \ No newline at end of file diff --git a/src/main/java/cokr/xit/base/boot/package-info.java b/src/main/java/cokr/xit/base/boot/package-info.java new file mode 100644 index 0000000..6074d06 --- /dev/null +++ b/src/main/java/cokr/xit/base/boot/package-info.java @@ -0,0 +1,6 @@ +/**xit-base 모듈을 Spring Boot 애플리케이션에서 사용할 수 있도록 지원 + * + */ +package cokr.xit.base.boot; \ No newline at end of file