GH-1034 Add implementation of ProxyHttpSession, fix Spring Security interaction

This commit is contained in:
Oleg Zhurakousky
2023-05-10 07:47:46 +02:00
parent 74aaadea98
commit 05685c647c
7 changed files with 222 additions and 7 deletions

View File

@@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.cloud.function.test.app.Pet;
import org.springframework.cloud.function.test.app.PetStoreSpringAppConfig;
import org.springframework.http.HttpStatus;
import org.springframework.security.test.context.support.WithMockUser;
import static org.assertj.core.api.Assertions.assertThat;
@@ -77,6 +78,7 @@ public class RequestResponseTests {
assertThat(pets.get(0)).isInstanceOf(Pet.class);
}
@WithMockUser("spring")
@Test
public void validateGetPojo() throws Exception {
HttpServletRequest request = new ProxyHttpServletRequest(null, "GET", "/pets/6e3cc370-892f-4efe-a9eb-82926ff8cc5b");

View File

@@ -17,24 +17,44 @@
package org.springframework.cloud.function.test.app;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.context.SecurityContextHolderFilter;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.web.filter.GenericFilterBean;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
@Configuration
@Import({ PetsController.class })
@EnableWebSecurity
public class PetStoreSpringAppConfig {
/*
* Create required HandlerMapping, to avoid several default HandlerMapping
* instances being created
@@ -53,6 +73,53 @@ public class PetStoreSpringAppConfig {
return new RequestMappingHandlerAdapter();
}
@Bean
public BeanPostProcessor post() {
return new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("securityFilterChain")) {
DefaultSecurityFilterChain chain = (DefaultSecurityFilterChain) bean;
ArrayList<Filter> filters = new ArrayList<>();
chain.getFilters().forEach(f -> {
if (!(f instanceof CsrfFilter)) {
filters.add(f);
}
});
bean = new DefaultSecurityFilterChain(chain.getRequestMatcher(), filters);
}
//System.out.println(beanName);
return bean;
}
};
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.addFilterBefore(new GenericFilterBean() {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
SecurityContext securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(UsernamePasswordAuthenticationToken.authenticated("user", "password",
Collections.singleton(new SimpleGrantedAuthority("USER"))));
HttpSession session = ((HttpServletRequest) request).getSession();
session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
chain.doFilter(request, response);
}
}, SecurityContextHolderFilter.class)
.authorizeHttpRequests((requests) -> requests
.requestMatchers("/", "/pets", "/pets/").permitAll()
.anyRequest().authenticated()
)
.logout((logout) -> logout.permitAll());
return http.build();
}
@Bean
public Filter filter() {
return new Filter() {