MOCK API -> csrf 제외

This commit is contained in:
현성필
2024-04-25 11:31:44 +09:00
parent 852e55ac24
commit eab712bad9
4 changed files with 73 additions and 8 deletions
@@ -2,6 +2,7 @@ package com.eactive.testmaster.api.controller;
import com.eactive.testmaster.api.entity.MockRoute;
import com.eactive.testmaster.api.service.MockRouteService;
import com.eactive.testmaster.config.CsrfExclusionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -27,6 +28,9 @@ public class MockApiHandlerMapping {
@Autowired
private RequestMappingHandlerMapping requestMappingHandlerMapping;
@Autowired
private CsrfExclusionService csrfExclusionService;
@PostConstruct
public void initialize() {
mockRouteService.initAllRoutes();
@@ -43,6 +47,9 @@ public class MockApiHandlerMapping {
try {
requestMappingHandlerMapping.registerMapping(mappingInfo, mockApiController, MockApiController.class.getDeclaredMethod("handleRequest", HttpServletRequest.class));
if (mockRoute.getMethod().equalsIgnoreCase("POST") || mockRoute.getMethod().equalsIgnoreCase("PUT")) {
csrfExclusionService.addExcludedPath(mockRoute.getPathPattern());
}
logger.info("Registered mapping for {} {}", mockRoute.getMethod(), mockRoute.getPathPattern());
} catch (NoSuchMethodException e) {
logger.error("Error registering mapping", e);
@@ -54,7 +61,9 @@ public class MockApiHandlerMapping {
.paths(mockRoute.getPathPattern())
.methods(RequestMethod.valueOf(mockRoute.getMethod()))
.build();
if (mockRoute.getMethod().equalsIgnoreCase("POST") || mockRoute.getMethod().equalsIgnoreCase("PUT")) {
csrfExclusionService.removeExcludedPath(mockRoute.getPathPattern());
}
requestMappingHandlerMapping.unregisterMapping(mappingInfo);
logger.info("Unregistered mapping for {} {}", mockRoute.getMethod(), mockRoute.getPathPattern());
}
@@ -0,0 +1,23 @@
package com.eactive.testmaster.config;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.stereotype.Service;
@Service
public class CsrfExclusionService {
private Set<String> excludedPaths = Collections.newSetFromMap(new ConcurrentHashMap<>());
public void addExcludedPath(String path) {
excludedPaths.add(path);
}
public void removeExcludedPath(String path) {
excludedPaths.remove(path);
}
public boolean shouldExclude(String path) {
return excludedPaths.contains(path);
}
}
@@ -2,6 +2,8 @@ package com.eactive.testmaster.config;
import com.navercorp.lucy.security.xss.servletfilter.XssEscapeServletFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
@@ -12,7 +14,10 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
@Configuration
@EnableWebSecurity
@@ -25,13 +30,14 @@ public class PortalConfigSecurity {
private final PortalAuthenticationManager portalAuthenticationManager;
@Autowired
public PortalConfigSecurity(PortalAuthenticationFailureHandler authenticationFailureHandler,
PortalAuthenticationSuccessHandler authenticationSuccessHandler,
PortalAuthenticationManager portalAuthenticationManager) {
private final CsrfExclusionService csrfExclusionService;
public PortalConfigSecurity(PortalAuthenticationFailureHandler authenticationFailureHandler, PortalAuthenticationSuccessHandler authenticationSuccessHandler, PortalAuthenticationManager portalAuthenticationManager,
CsrfExclusionService csrfExclusionService) {
this.authenticationFailureHandler = authenticationFailureHandler;
this.authenticationSuccessHandler = authenticationSuccessHandler;
this.portalAuthenticationManager = portalAuthenticationManager;
this.csrfExclusionService = csrfExclusionService;
}
@Bean
@@ -44,6 +50,29 @@ public class PortalConfigSecurity {
return registrationBean;
}
@Bean
public CsrfTokenRepository csrfTokenRepository(CsrfExclusionService csrfExclusionService) {
// HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
CookieCsrfTokenRepository repository = new CookieCsrfTokenRepository();
repository.setCookieHttpOnly(false);
return new CsrfTokenRepository() {
@Override
public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response) {
repository.saveToken(token, request, response);
}
@Override
public CsrfToken loadToken(HttpServletRequest request) {
return repository.loadToken(request);
}
@Override
public CsrfToken generateToken(HttpServletRequest request) {
return repository.generateToken(request);
}
};
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
@@ -59,8 +88,11 @@ public class PortalConfigSecurity {
.logoutRequestMatcher(new AntPathRequestMatcher("/actionLogout.do", "GET"))
.logoutSuccessUrl("/"))
.csrf(csrf -> csrf
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringAntMatchers("/h2-console/**")
.csrfTokenRepository(csrfTokenRepository(csrfExclusionService))
.ignoringRequestMatchers(request -> csrfExclusionService.shouldExclude(request.getServletPath()))
.ignoringAntMatchers("/h2-console/**")
// .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
).headers(headers -> headers.frameOptions().sameOrigin())
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
@@ -68,7 +100,6 @@ public class PortalConfigSecurity {
.changeSessionId()
);
return http.build();
}
}
@@ -1,5 +1,6 @@
package com.eactive.testmaster.loadtest.controller;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
@@ -9,6 +10,7 @@ import org.springframework.web.bind.annotation.GetMapping;
public class LoadTestPageController {
@GetMapping("/mgmt/load_tester.do")
@Secured("ROLE_API_TESTER")
public String testView(ModelMap model) {
return "page/tester/loadTester";
}