초기소스
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
package com.wb.domainserver.security.config;
|
||||
|
||||
|
||||
import com.nhncorp.psinfra.toolkit.SimpleCryptLib;
|
||||
import com.wb.domainserver.interceptor.mngr.MngrAuthInterceptor;
|
||||
import com.wb.domainserver.interceptor.mngr.MngrLoggingInterceptor;
|
||||
import com.wb.domainserver.interceptor.mngr.MngrMenuInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
@ComponentScan(basePackages = {
|
||||
"com.wb.domainserver.domain.mngr"
|
||||
, "com.wb.domainserver.domain.admin"
|
||||
, "com.wb.domainserver.interceptor.mngr"
|
||||
, "com.wb.domainserver.util.file"
|
||||
// , "com.wb.domainserver.domain.mq.controller" /*ERP batch Controller 위치*/
|
||||
// , "com.wb.domainserver.batch.controller" /*batch Controller*/
|
||||
})
|
||||
public class AdminWebMvcConfig implements WebMvcConfigurer {
|
||||
|
||||
private static final String[] ADMIN_INTERCEPTOR_PATH = {"/mngr/**", "/admin/**","/mngr","/admin"};
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
if(!registry.hasMappingForPattern("/webjars/**")){
|
||||
registry.addResourceHandler("/webjars/**")
|
||||
.addResourceLocations("/webjars/").resourceChain(false);
|
||||
}
|
||||
if(!registry.hasMappingForPattern("/**")){
|
||||
registry.addResourceHandler("/**")
|
||||
.addResourceLocations(
|
||||
"classpath:/static",
|
||||
"classpath:/static/admin",
|
||||
"classpath:/static/assets",
|
||||
"classpath:/static/ckeditor",
|
||||
"classpath:/static/crm",
|
||||
"classpath:/static/daumeditor",
|
||||
"classpath:/static/intranet",
|
||||
"classpath:/static/itrnt",
|
||||
"classpath:/static/jchartfx",
|
||||
"classpath:/static/js",
|
||||
"classpath:/static/login",
|
||||
"classpath:/static/mngr",
|
||||
"classpath:/static/css"
|
||||
).resourceChain(false);
|
||||
}
|
||||
if(!registry.hasMappingForPattern("/**.html")){
|
||||
registry.addResourceHandler("/**.html")
|
||||
.addResourceLocations(
|
||||
"classpath:/templates/"
|
||||
).resourceChain(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public SimpleCryptLib simpleCryptLib() {
|
||||
return new SimpleCryptLib();
|
||||
}
|
||||
|
||||
/**
|
||||
* 메뉴 처리 bean 선언
|
||||
*/
|
||||
@Bean
|
||||
public MngrMenuInterceptor mngrMenuInterceptor() {
|
||||
return new MngrMenuInterceptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* logging 처리 bean 선언
|
||||
*/
|
||||
@Bean
|
||||
public MngrLoggingInterceptor mngrLoggingInterceptor() {
|
||||
return new MngrLoggingInterceptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* auth 처리 bean 선언
|
||||
*/
|
||||
@Bean
|
||||
public MngrAuthInterceptor mngrAuthInterceptor() {
|
||||
return new MngrAuthInterceptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
MngrLoggingInterceptor loggingInterceptor = mngrLoggingInterceptor();
|
||||
registry.addInterceptor(loggingInterceptor).addPathPatterns(ADMIN_INTERCEPTOR_PATH)
|
||||
.order(1)
|
||||
.excludePathPatterns("/itrnt/mbr/selectMbrJoinForm")
|
||||
.excludePathPatterns("/itrnt/ntcn/mssage/insertPosMbrSend")
|
||||
.excludePathPatterns("/order/tm_settle")
|
||||
.excludePathPatterns("/order/insertTmOrder")
|
||||
.excludePathPatterns("/order/selectTmOrdrInfo")
|
||||
.excludePathPatterns("/crm/ordr/insertTossKeyInSetleTm")
|
||||
.excludePathPatterns("/crm/ordr/insertKcpSetleTm")
|
||||
.excludePathPatterns("/crm/ordr/insertKcpKeyInSetleTm")
|
||||
.excludePathPatterns("/crm/ordr/insertTossSetleTm")
|
||||
.excludePathPatterns("/crm/ordr/insertSetleTm")
|
||||
.excludePathPatterns("/comm/itrnt/include", "/WEB-INF/views/**", "/**/css/**", "/**/images/**", "/**/js/**", "/**/fonts/**", "/**/*.js", "/**/*.css", "/error", "/**/*.jpg", "/**/*.png", "/**/*.gif", "/favicon.ico");
|
||||
MngrAuthInterceptor authInterceptor = mngrAuthInterceptor();
|
||||
registry.addInterceptor(authInterceptor).addPathPatterns(ADMIN_INTERCEPTOR_PATH)
|
||||
.order(2)
|
||||
.excludePathPatterns("/itrnt/mbr/selectMbrJoinForm")
|
||||
.excludePathPatterns("/itrnt/ntcn/mssage/insertPosMbrSend")
|
||||
.excludePathPatterns("/order/tm_settle")
|
||||
.excludePathPatterns("/order/insertTmOrder")
|
||||
.excludePathPatterns("/order/selectTmOrdrInfo")
|
||||
.excludePathPatterns("/crm/ordr/insertTossKeyInSetleTm")
|
||||
.excludePathPatterns("/crm/ordr/insertKcpSetleTm")
|
||||
.excludePathPatterns("/crm/ordr/insertKcpKeyInSetleTm")
|
||||
.excludePathPatterns("/crm/ordr/insertTossSetleTm")
|
||||
.excludePathPatterns("/crm/ordr/insertSetleTm")
|
||||
.excludePathPatterns("/mngr", "/mngr/login", "/mngr/tokens/refresh", "/mngr/login/page/mngr","/mngr/login/loginCheck","/mngr/login/mngr","/mngr/login/insertPhoneAuth" , "/mngr/login/selectPhoneAuth", "/mngr/login/loginCheck")
|
||||
.excludePathPatterns("/admin", "/admin/login", "/admin/tokens/refresh", "/admin/login/page/admin","/admin/login/loginCheck","/admin/login/admin","/admin/login/insertPhoneAuth" , "/admin/login/selectPhoneAuth", "/admin/login/loginCheck")
|
||||
.excludePathPatterns("/comm/itrnt/include", "/WEB-INF/views/**", "/**/css/**", "/**/images/**", "/**/js/**", "/**/fonts/**", "/**/*.js", "/**/*.css", "/error", "/**/*.jpg", "/**/*.png", "/**/*.gif", "/favicon.ico", "/mngr/vendor/chart.js/chart.umd.js.map", "/ckeditor/ckeditor.js.map");
|
||||
MngrMenuInterceptor menuInterceptor = mngrMenuInterceptor();
|
||||
registry.addInterceptor(menuInterceptor).addPathPatterns(ADMIN_INTERCEPTOR_PATH)
|
||||
.order(3)
|
||||
.excludePathPatterns("/itrnt/mbr/selectMbrJoinForm")
|
||||
.excludePathPatterns("/itrnt/ntcn/mssage/insertPosMbrSend")
|
||||
.excludePathPatterns("/order/tm_settle")
|
||||
.excludePathPatterns("/order/insertTmOrder")
|
||||
.excludePathPatterns("/order/selectTmOrdrInfo")
|
||||
.excludePathPatterns("/crm/ordr/insertTossKeyInSetleTm")
|
||||
.excludePathPatterns("/crm/ordr/insertKcpSetleTm")
|
||||
.excludePathPatterns("/crm/ordr/insertKcpKeyInSetleTm")
|
||||
.excludePathPatterns("/crm/ordr/insertTossSetleTm")
|
||||
.excludePathPatterns("/crm/ordr/insertSetleTm")
|
||||
.excludePathPatterns("/comm/itrnt/include", "/WEB-INF/views/**", "/**/css/**", "/**/images/**", "/**/js/**", "/**/fonts/**", "/**/*.js", "/**/*.css", "/error", "/**/*.jpg", "/**/*.png", "/**/*.gif", "/favicon.ico");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.wb.domainserver.security.config;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.CacheLoader;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.wb.domainserver.realm.RealmResolver;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.cache.caffeine.CaffeineCacheManager;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
public class CacheConfig {
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
|
||||
public CacheConfig(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CaffeineCacheManager cacheManager() {
|
||||
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
|
||||
cacheManager.setCaffeine(caffeineCacheBuilder());
|
||||
cacheManager.setCacheLoader(cacheLoader());
|
||||
return cacheManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Caffeine<Object, Object> caffeineCacheBuilder() {
|
||||
return Caffeine.newBuilder()
|
||||
.expireAfterWrite(10, TimeUnit.MINUTES)
|
||||
.maximumSize(100);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheLoader<Object, Object> cacheLoader() {
|
||||
return new CacheLoader<>() {
|
||||
@Override
|
||||
public Object load(Object key) {
|
||||
return loadAsync(key).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Object> asyncReload(Object key, Object oldValue, Executor executor) {
|
||||
return loadAsync(key);
|
||||
}
|
||||
|
||||
private CompletableFuture<Object> loadAsync(Object key) {
|
||||
String hostUrl = (String) key;
|
||||
RealmResolver realmResolver = applicationContext.getBean(RealmResolver.class);
|
||||
return realmResolver.resolveRealmInternalDirect(hostUrl);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.wb.domainserver.security.config;
|
||||
|
||||
import com.wb.domainserver.common.msg.GconeMessageSource;
|
||||
import com.wb.domainserver.common.ui.pagination.DefaultPaginationManager;
|
||||
import com.wb.domainserver.common.ui.pagination.ImagePaginationRenderer;
|
||||
import com.wb.domainserver.common.ui.pagination.PaginationRenderer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
|
||||
import org.springframework.web.servlet.ViewResolver;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
import org.springframework.web.servlet.view.JstlView;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Configuration
|
||||
public class CommWebMvcConfig {
|
||||
|
||||
|
||||
/**
|
||||
* image pagination 처리를 위한 renderer set
|
||||
* @return ImagePaginationRenderer image pagination renderer
|
||||
*/
|
||||
@Bean
|
||||
public ImagePaginationRenderer imageRenderer() {
|
||||
return new ImagePaginationRenderer();
|
||||
}
|
||||
|
||||
/**
|
||||
* 기본 페이징 처리 bean 선언
|
||||
* @return DefaultPaginationManager 기본 페이징 처리 bean
|
||||
*/
|
||||
@Bean
|
||||
public DefaultPaginationManager paginationManager() {
|
||||
DefaultPaginationManager defaultPaginationManager = new DefaultPaginationManager();
|
||||
|
||||
Map<String, PaginationRenderer> rendererType = new HashMap<>();
|
||||
rendererType.put("image", imageRenderer());
|
||||
defaultPaginationManager.setRendererType(rendererType);
|
||||
|
||||
return defaultPaginationManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ViewResolver getViewResolver() {
|
||||
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
|
||||
resolver.setPrefix("/WEB-INF/views/");
|
||||
resolver.setSuffix(".jsp");
|
||||
resolver.setViewClass(JstlView.class);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ReloadableResourceBundleMessageSource messageSource() {
|
||||
ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource = new ReloadableResourceBundleMessageSource();
|
||||
|
||||
reloadableResourceBundleMessageSource.setBasenames(
|
||||
"classpath:/message/messages");
|
||||
reloadableResourceBundleMessageSource.setCacheSeconds(60);
|
||||
return reloadableResourceBundleMessageSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public GconeMessageSource gconeMessageSource() {
|
||||
GconeMessageSource gconeMessageSource = new GconeMessageSource();
|
||||
gconeMessageSource.setReloadableResourceBundleMessageSource(messageSource());
|
||||
return gconeMessageSource;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.wb.domainserver.security.config;
|
||||
|
||||
import com.wb.domainserver.realm.RealmResolver;
|
||||
import com.wb.domainserver.realm.filter.RealmFilter;
|
||||
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.core.Ordered;
|
||||
|
||||
@Configuration
|
||||
public class RealmFilterConfig {
|
||||
|
||||
@Autowired
|
||||
RealmResolver realmResolver;
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean<RealmFilter> realmFilter() {
|
||||
FilterRegistrationBean<RealmFilter> registrationBean = new FilterRegistrationBean<>();
|
||||
registrationBean.setFilter(new RealmFilter(realmResolver));
|
||||
registrationBean.addUrlPatterns("/*");
|
||||
registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
|
||||
return registrationBean;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright 2020-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.wb.domainserver.security.config;
|
||||
|
||||
import com.wb.domainserver.domain.sopmal.oauth.service.CustomOAuth2UserService;
|
||||
import com.wb.domainserver.exception.response.CustomOauthFailureException;
|
||||
import com.wb.domainserver.realm.RealmResolver;
|
||||
import com.wb.domainserver.realm.filter.RealmFilter;
|
||||
import com.wb.domainserver.response.CustomAuthenticationSuccessHandler;
|
||||
import com.wb.domainserver.security.authentication.CustomAccessDeniedEntryPoint;
|
||||
import com.wb.domainserver.security.authentication.CustomAuthenticationEntryPoint;
|
||||
import com.wb.domainserver.security.authorization.WnbtAuthorizationManager;
|
||||
import com.wb.domainserver.security.filter.CustomXssFilter;
|
||||
import com.wb.domainserver.security.filter.JwtAuthenticationFilter;
|
||||
import com.wb.domainserver.security.handler.CustomLogoutSuccessHandler;
|
||||
import com.wb.domainserver.security.user.SecurityUserDetailService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.support.JdkRegexpMethodPointcut;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Role;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
||||
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.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.logout.LogoutFilter;
|
||||
import org.springframework.security.web.header.HeaderWriterFilter;
|
||||
import org.springframework.security.web.savedrequest.RequestCacheAwareFilter;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
import org.springframework.security.web.util.matcher.OrRequestMatcher;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.springframework.beans.factory.config.BeanDefinition.ROLE_INFRASTRUCTURE;
|
||||
|
||||
@EnableWebSecurity(debug = true)
|
||||
@Configuration
|
||||
//@EnableMethodSecurity
|
||||
public class ResourceServerConfig {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ResourceServerConfig.class);
|
||||
|
||||
@Autowired
|
||||
private RealmResolver realmResolver;
|
||||
|
||||
@Autowired
|
||||
private SecurityUserDetailService userDetailService;
|
||||
|
||||
@Autowired
|
||||
private CustomAuthenticationEntryPoint authenticationEntryPoint;
|
||||
|
||||
@Autowired
|
||||
private CustomAccessDeniedEntryPoint accessDeniedEntryPoint;
|
||||
|
||||
@Autowired
|
||||
private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
|
||||
|
||||
@Autowired
|
||||
private CustomOAuth2UserService customOAuth2UserService;
|
||||
|
||||
@Bean
|
||||
@Role(ROLE_INFRASTRUCTURE)
|
||||
public Advisor authorizationManagerBeforeMethodInterception(WnbtAuthorizationManager<?> authorizationManager) {
|
||||
JdkRegexpMethodPointcut pattern = new JdkRegexpMethodPointcut();
|
||||
pattern.setPattern("com.wb.domainserver.*.controller.*");
|
||||
return new AuthorizationManagerBeforeMethodInterceptor(pattern, authorizationManager);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Order(1)
|
||||
SecurityFilterChain sopmalSecurityFilterChain(HttpSecurity http, SecurityPathProperties securityProperties) throws Exception {
|
||||
|
||||
RequestMatcher logoutRequestMatcher = new OrRequestMatcher(
|
||||
new AntPathRequestMatcher("/sopmal/logout")
|
||||
);
|
||||
|
||||
//사용자 권한
|
||||
List<RequestMatcher> anonymousPath = securityProperties.getSolmal().getAnonmymous().stream()
|
||||
.map(AntPathRequestMatcher::new)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<RequestMatcher> authPath = securityProperties.getSolmal().getAuthenticated().stream()
|
||||
.map(AntPathRequestMatcher::new)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<RequestMatcher> resourcePath = securityProperties.getCommon().getResources().stream()
|
||||
.map(AntPathRequestMatcher::new)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
OrRequestMatcher anonymoushMatchers = new OrRequestMatcher(anonymousPath);
|
||||
OrRequestMatcher authMatchers = new OrRequestMatcher(authPath);
|
||||
OrRequestMatcher resourceMatchers = new OrRequestMatcher(resourcePath);
|
||||
|
||||
return http
|
||||
.csrf(AbstractHttpConfigurer::disable)
|
||||
.securityMatcher("/sopmal/**", "/oauth2/**", "/login/oauth2/**")
|
||||
.authorizeHttpRequests(authorize ->
|
||||
authorize
|
||||
.requestMatchers(authMatchers).authenticated()
|
||||
.requestMatchers(anonymoushMatchers).anonymous()
|
||||
.requestMatchers(resourceMatchers).permitAll()
|
||||
.requestMatchers(
|
||||
new AntPathRequestMatcher("/oauth2/**"),
|
||||
new AntPathRequestMatcher("/login/oauth2/**")
|
||||
).permitAll()
|
||||
.anyRequest().permitAll()
|
||||
)
|
||||
.oauth2Login(oauth2 -> oauth2 //sns oauth
|
||||
.loginPage("/sopmal/login")
|
||||
.successHandler(customAuthenticationSuccessHandler) //인증성공시 로그인 혹은 연동처리
|
||||
.userInfoEndpoint(userInfo -> userInfo //인증처리
|
||||
.userService(customOAuth2UserService)
|
||||
)
|
||||
.failureHandler(new CustomOauthFailureException()) //인증 실패시
|
||||
)
|
||||
.addFilterAfter(new CustomXssFilter(), RequestCacheAwareFilter.class)
|
||||
.addFilterBefore(new JwtAuthenticationFilter(userDetailService), LogoutFilter.class)
|
||||
.addFilterAfter(new RealmFilter(realmResolver), HeaderWriterFilter.class)
|
||||
.exceptionHandling(exceptions -> exceptions
|
||||
.authenticationEntryPoint(authenticationEntryPoint)
|
||||
.accessDeniedHandler(accessDeniedEntryPoint)
|
||||
).logout(logout
|
||||
-> logout.logoutRequestMatcher(logoutRequestMatcher)
|
||||
.deleteCookies("JSESSIONID")
|
||||
.logoutSuccessHandler(new CustomLogoutSuccessHandler())
|
||||
)
|
||||
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Order(2)
|
||||
SecurityFilterChain adminSecurityFilterChain(HttpSecurity http, SecurityPathProperties securityProperties) throws Exception {
|
||||
|
||||
// 설정된 로그아웃 URL
|
||||
RequestMatcher logoutRequestMatcher = new OrRequestMatcher(
|
||||
new AntPathRequestMatcher("/mngr/logout"),
|
||||
new AntPathRequestMatcher("/admin/logout"),
|
||||
new AntPathRequestMatcher("/crm/logout")
|
||||
);
|
||||
|
||||
|
||||
List<RequestMatcher> anonmyPath = securityProperties.getAdmin().getAnonmymous().stream()
|
||||
.map(AntPathRequestMatcher::new)
|
||||
.collect(Collectors.toList());
|
||||
List<RequestMatcher> authPath = securityProperties.getAdmin().getAuthenticated().stream()
|
||||
.map(AntPathRequestMatcher::new)
|
||||
.collect(Collectors.toList());
|
||||
List<RequestMatcher> resourcePath = securityProperties.getCommon().getResources().stream()
|
||||
.map(AntPathRequestMatcher::new)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
OrRequestMatcher authMatchers = new OrRequestMatcher(authPath);
|
||||
OrRequestMatcher resourceMatchers = new OrRequestMatcher(resourcePath);
|
||||
|
||||
return http
|
||||
.csrf(AbstractHttpConfigurer::disable)
|
||||
.securityMatcher("/mngr/**","/mngr","/admin/**","/admin","/admin/**","/crm/**","/itrnt/**", logoutRequestMatcher.toString()) //"/*/mq/**", "/api/batch/schedulerloader/**", 제외
|
||||
.authorizeHttpRequests(authorize ->
|
||||
authorize
|
||||
// .requestMatchers(AntPathRequestMatcher.antMatcher("/*/mq/**")).anonymous() //ERP 호출 허용을 위해
|
||||
// .requestMatchers(AntPathRequestMatcher.antMatcher("/api/batch/schedulerloader/**")).anonymous() //batch 스케줄 동적기동
|
||||
.requestMatchers(AntPathRequestMatcher.antMatcher("/admin")).permitAll()
|
||||
.requestMatchers(AntPathRequestMatcher.antMatcher("/mngr")).permitAll()
|
||||
.requestMatchers(AntPathRequestMatcher.antMatcher("/mngr/login/**")).permitAll()
|
||||
.requestMatchers(AntPathRequestMatcher.antMatcher("/admin/login/**")).permitAll()
|
||||
.requestMatchers(AntPathRequestMatcher.antMatcher("/mngr/tokens/**")).anonymous()
|
||||
.requestMatchers(AntPathRequestMatcher.antMatcher("/admin/tokens/**")).anonymous()
|
||||
.requestMatchers(resourceMatchers).permitAll()
|
||||
.requestMatchers(authMatchers).authenticated()
|
||||
.anyRequest().permitAll()
|
||||
)
|
||||
.addFilterBefore(new JwtAuthenticationFilter(userDetailService), LogoutFilter.class)
|
||||
.addFilterAfter(new RealmFilter(realmResolver), HeaderWriterFilter.class)
|
||||
.exceptionHandling(exceptions -> exceptions
|
||||
.authenticationEntryPoint(authenticationEntryPoint)
|
||||
.accessDeniedHandler(accessDeniedEntryPoint)
|
||||
).logout(logout
|
||||
-> logout.logoutRequestMatcher(logoutRequestMatcher)
|
||||
.deleteCookies("JSESSIONID")
|
||||
.logoutSuccessHandler(new CustomLogoutSuccessHandler())
|
||||
)
|
||||
|
||||
.build();
|
||||
}
|
||||
|
||||
//
|
||||
// private String customBearerTokenResolver(HttpServletRequest request) {
|
||||
// String authorization = request.getHeader("Authorization");
|
||||
// if (StringUtils.hasText(authorization) && authorization.startsWith("Bearer ")) {
|
||||
// return authorization.substring(7);
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// private String determineIssuerUri(String token) {
|
||||
// return String.format(issuerUri+"/%s", RealmContextHolder.getRealm());
|
||||
// }
|
||||
|
||||
@Bean
|
||||
public BCryptPasswordEncoder bCryptPasswordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.wb.domainserver.security.config;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Component
|
||||
@PropertySource(value = "classpath:/secured-config.yml", factory = SecurityPathPropertySourceFactory.class)
|
||||
@ConfigurationProperties(prefix = "secured.path")
|
||||
public class SecurityPathProperties {
|
||||
|
||||
private Solmal solmal;
|
||||
private Admin admin;
|
||||
private Common common;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class Solmal {
|
||||
private List<String> anonmymous;
|
||||
private List<String> authenticated;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class Admin {
|
||||
private List<String> anonmymous;
|
||||
private List<String> authenticated;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class Common {
|
||||
private List<String> resources;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.wb.domainserver.security.config;
|
||||
|
||||
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
|
||||
import org.springframework.core.env.PropertiesPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.io.support.EncodedResource;
|
||||
import org.springframework.core.io.support.PropertySourceFactory;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
public class SecurityPathPropertySourceFactory implements PropertySourceFactory {
|
||||
@Override
|
||||
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
|
||||
Properties propertiesFromYaml = loadYamlIntoProperties(resource);
|
||||
String sourceName = name != null ? name : resource.getResource().getFilename();
|
||||
return new PropertiesPropertySource(sourceName, propertiesFromYaml);
|
||||
}
|
||||
|
||||
private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException {
|
||||
try {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setResources(resource.getResource());
|
||||
factory.afterPropertiesSet();
|
||||
return factory.getObject();
|
||||
} catch (IllegalStateException e) {
|
||||
// for ignoreResourceNotFound
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof FileNotFoundException)
|
||||
throw (FileNotFoundException) e.getCause();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.wb.domainserver.security.config;
|
||||
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class TomcatWebCustomConfig implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>{
|
||||
|
||||
@Override
|
||||
public void customize(TomcatServletWebServerFactory factory) {
|
||||
factory.addConnectorCustomizers(connector -> connector.setProperty("relaxedQueryChars", "[]"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2020-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.wb.domainserver.security.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
@Configuration
|
||||
public class WebClientConfig {
|
||||
|
||||
@Bean
|
||||
public WebClient webClient(WebClient.Builder builder) {
|
||||
builder.codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1));
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.wb.domainserver.security.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**")
|
||||
.allowedOrigins("*")
|
||||
.allowedMethods("*")
|
||||
.allowedHeaders("*")
|
||||
.exposedHeaders("Authorization");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package com.wb.domainserver.security.config;
|
||||
|
||||
|
||||
import com.wb.domainserver.interceptor.sopmal.*;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
@ComponentScan(basePackages = {
|
||||
"com.wb.domainserver.domain.sopmal"
|
||||
, "com.wb.domainserver.domain.log"
|
||||
, "com.wb.domainserver.interceptor.sopmal"})
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
|
||||
private static final String[] SOPMAL_INTERCEPTOR_PATH = {"/","/index","/sopmal/**"};
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
if(!registry.hasMappingForPattern("/webjars/**")){
|
||||
registry.addResourceHandler("/webjars/**")
|
||||
.addResourceLocations("/webjars/").resourceChain(false);
|
||||
}
|
||||
if(!registry.hasMappingForPattern("/**")){
|
||||
registry.addResourceHandler("/**")
|
||||
.addResourceLocations(
|
||||
"classpath:/static",
|
||||
"classpath:/static/js",
|
||||
"classpath:/static/img",
|
||||
"classpath:/static/login",
|
||||
"classpath:/static/css").resourceChain(false);
|
||||
}
|
||||
if(!registry.hasMappingForPattern("/**.html")){
|
||||
registry.addResourceHandler("/**.html")
|
||||
.addResourceLocations(
|
||||
"classpath:/templates/"
|
||||
).resourceChain(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
DeviceHandlerInterceptor deviceHandlerInterceptor = deviceHandlerInterceptor();
|
||||
registry.addInterceptor(deviceHandlerInterceptor).addPathPatterns();
|
||||
|
||||
LoggingInterceptor loggingInterceptor = loggingInterceptor();
|
||||
registry.addInterceptor(loggingInterceptor).addPathPatterns(SOPMAL_INTERCEPTOR_PATH)
|
||||
.order(1)
|
||||
.excludePathPatterns("/**/css/**", "/**/images/**", "/**/js/**", "/**/fonts/**", "/**/*.js", "/**/*.css", "/error", "/**/*.jpg", "/**/*.png", "/**/*.gif");
|
||||
OperInterceptor operInterceptor = operInterceptor();
|
||||
registry.addInterceptor(operInterceptor).addPathPatterns(SOPMAL_INTERCEPTOR_PATH)
|
||||
.order(2)
|
||||
.excludePathPatterns("/**/css/**", "/**/images/**", "/**/js/**", "/**/fonts/**", "/**/*.js", "/**/*.css", "/error", "/**/*.jpg", "/**/*.png", "/**/*.gif", "/oper");
|
||||
LoginChkInterceptor loginChkInterceptor = loginChkInterceptor();
|
||||
registry.addInterceptor(loginChkInterceptor).addPathPatterns(SOPMAL_INTERCEPTOR_PATH)
|
||||
.order(3)
|
||||
.excludePathPatterns("/**/css/**", "/**/images/**", "/**/js/**", "/**/fonts/**", "/**/*.js", "/**/*.css", "/error", "/**/*.jpg", "/**/*.png", "/**/*.gif");
|
||||
AuthInterceptor authInterceptor = authInterceptor();
|
||||
registry.addInterceptor(authInterceptor).addPathPatterns(SOPMAL_INTERCEPTOR_PATH)
|
||||
.order(4)
|
||||
.excludePathPatterns("/**/css/**", "/**/images/**", "/**/js/**", "/**/fonts/**", "/**/*.js", "/**/*.css", "/error", "/**/*.jpg", "/**/*.png", "/**/*.gif");
|
||||
MenuInterceptor menuInterceptor = menuInterceptor();
|
||||
registry.addInterceptor(menuInterceptor).addPathPatterns(SOPMAL_INTERCEPTOR_PATH)
|
||||
.order(5)
|
||||
.excludePathPatterns("/**/css/**", "/**/images/**", "/**/js/**", "/**/fonts/**", "/**/*.js", "/**/*.css", "/error", "/**/*.jpg", "/**/*.png", "/**/*.gif");
|
||||
FooterInterceptor footerInterceptor = footerInterceptor();
|
||||
registry.addInterceptor(footerInterceptor).addPathPatterns(SOPMAL_INTERCEPTOR_PATH)
|
||||
.order(6)
|
||||
.excludePathPatterns("/**/css/**", "/**/images/**", "/**/js/**", "/**/fonts/**", "/**/*.js", "/**/*.css", "/error", "/**/*.jpg", "/**/*.png", "/**/*.gif");
|
||||
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DeviceHandlerInterceptor deviceHandlerInterceptor() {
|
||||
return new DeviceHandlerInterceptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* 메뉴 처리 bean 선언
|
||||
*/
|
||||
@Bean
|
||||
public MenuInterceptor menuInterceptor() {
|
||||
return new MenuInterceptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* footer 처리 bean 선언
|
||||
*/
|
||||
@Bean
|
||||
public FooterInterceptor footerInterceptor() {
|
||||
return new FooterInterceptor();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * logging 처리 bean 선언
|
||||
// */
|
||||
@Bean
|
||||
public LoggingInterceptor loggingInterceptor() {
|
||||
return new LoggingInterceptor();
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * 사용자 권한 처리 bean 선언
|
||||
// */
|
||||
@Bean
|
||||
public AuthInterceptor authInterceptor() {
|
||||
return new AuthInterceptor();
|
||||
}
|
||||
|
||||
// /**
|
||||
// *쇼핑몰 운영 처리 bean 선언
|
||||
// */
|
||||
@Bean
|
||||
public OperInterceptor operInterceptor() {
|
||||
return new OperInterceptor();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 로그인 확인 bean 선언
|
||||
// */
|
||||
@Bean
|
||||
public LoginChkInterceptor loginChkInterceptor() {
|
||||
return new LoginChkInterceptor();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user