parent
3182883e2e
commit
fa4806dbcc
|
@ -12,6 +12,7 @@ dependencies {
|
||||||
api 'io.micrometer:micrometer-observation'
|
api 'io.micrometer:micrometer-observation'
|
||||||
|
|
||||||
optional project(':spring-security-messaging')
|
optional project(':spring-security-messaging')
|
||||||
|
optional project(':spring-security-web')
|
||||||
optional 'org.springframework:spring-websocket'
|
optional 'org.springframework:spring-websocket'
|
||||||
optional 'com.fasterxml.jackson.core:jackson-databind'
|
optional 'com.fasterxml.jackson.core:jackson-databind'
|
||||||
optional 'io.micrometer:context-propagation'
|
optional 'io.micrometer:context-propagation'
|
||||||
|
@ -22,6 +23,9 @@ dependencies {
|
||||||
optional 'org.springframework:spring-tx'
|
optional 'org.springframework:spring-tx'
|
||||||
optional 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor'
|
optional 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor'
|
||||||
|
|
||||||
|
provided 'jakarta.servlet:jakarta.servlet-api'
|
||||||
|
|
||||||
|
testImplementation project(path : ':spring-security-web', configuration : 'tests')
|
||||||
testImplementation 'commons-collections:commons-collections'
|
testImplementation 'commons-collections:commons-collections'
|
||||||
testImplementation 'io.projectreactor:reactor-test'
|
testImplementation 'io.projectreactor:reactor-test'
|
||||||
testImplementation "org.assertj:assertj-core"
|
testImplementation "org.assertj:assertj-core"
|
||||||
|
|
|
@ -16,9 +16,13 @@
|
||||||
|
|
||||||
package org.springframework.security.web.access;
|
package org.springframework.security.web.access;
|
||||||
|
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.ArgumentMatchers;
|
||||||
|
import org.mockito.BDDMockito;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.mock.web.MockServletContext;
|
import org.springframework.mock.web.MockServletContext;
|
||||||
|
@ -33,15 +37,6 @@ import org.springframework.security.web.FilterInvocation;
|
||||||
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
|
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
|
||||||
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
|
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyList;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.BDDMockito.given;
|
|
||||||
import static org.mockito.BDDMockito.willThrow;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests
|
* Tests
|
||||||
* {@link org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator}.
|
* {@link org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator}.
|
||||||
|
@ -61,43 +56,45 @@ public class DefaultWebInvocationPrivilegeEvaluatorTests {
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public final void setUp() {
|
public final void setUp() {
|
||||||
this.interceptor = new FilterSecurityInterceptor();
|
this.interceptor = new FilterSecurityInterceptor();
|
||||||
this.ods = mock(FilterInvocationSecurityMetadataSource.class);
|
this.ods = Mockito.mock(FilterInvocationSecurityMetadataSource.class);
|
||||||
this.adm = mock(AccessDecisionManager.class);
|
this.adm = Mockito.mock(AccessDecisionManager.class);
|
||||||
this.ram = mock(RunAsManager.class);
|
this.ram = Mockito.mock(RunAsManager.class);
|
||||||
this.interceptor.setAuthenticationManager(mock(AuthenticationManager.class));
|
this.interceptor.setAuthenticationManager(Mockito.mock(AuthenticationManager.class));
|
||||||
this.interceptor.setSecurityMetadataSource(this.ods);
|
this.interceptor.setSecurityMetadataSource(this.ods);
|
||||||
this.interceptor.setAccessDecisionManager(this.adm);
|
this.interceptor.setAccessDecisionManager(this.adm);
|
||||||
this.interceptor.setRunAsManager(this.ram);
|
this.interceptor.setRunAsManager(this.ram);
|
||||||
this.interceptor.setApplicationEventPublisher(mock(ApplicationEventPublisher.class));
|
this.interceptor.setApplicationEventPublisher(Mockito.mock(ApplicationEventPublisher.class));
|
||||||
SecurityContextHolder.clearContext();
|
SecurityContextHolder.clearContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void permitsAccessIfNoMatchingAttributesAndPublicInvocationsAllowed() {
|
public void permitsAccessIfNoMatchingAttributesAndPublicInvocationsAllowed() {
|
||||||
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
|
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
|
||||||
given(this.ods.getAttributes(any())).willReturn(null);
|
BDDMockito.given(this.ods.getAttributes(ArgumentMatchers.any())).willReturn(null);
|
||||||
assertThat(wipe.isAllowed("/context", "/foo/index.jsp", "GET", mock(Authentication.class))).isTrue();
|
Assertions.assertThat(wipe.isAllowed("/context", "/foo/index.jsp", "GET", Mockito.mock(Authentication.class)))
|
||||||
|
.isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deniesAccessIfNoMatchingAttributesAndPublicInvocationsNotAllowed() {
|
public void deniesAccessIfNoMatchingAttributesAndPublicInvocationsNotAllowed() {
|
||||||
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
|
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
|
||||||
given(this.ods.getAttributes(any())).willReturn(null);
|
BDDMockito.given(this.ods.getAttributes(ArgumentMatchers.any())).willReturn(null);
|
||||||
this.interceptor.setRejectPublicInvocations(true);
|
this.interceptor.setRejectPublicInvocations(true);
|
||||||
assertThat(wipe.isAllowed("/context", "/foo/index.jsp", "GET", mock(Authentication.class))).isFalse();
|
Assertions.assertThat(wipe.isAllowed("/context", "/foo/index.jsp", "GET", Mockito.mock(Authentication.class)))
|
||||||
|
.isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deniesAccessIfAuthenticationIsNull() {
|
public void deniesAccessIfAuthenticationIsNull() {
|
||||||
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
|
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
|
||||||
assertThat(wipe.isAllowed("/foo/index.jsp", null)).isFalse();
|
Assertions.assertThat(wipe.isAllowed("/foo/index.jsp", null)).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void allowsAccessIfAccessDecisionManagerDoes() {
|
public void allowsAccessIfAccessDecisionManagerDoes() {
|
||||||
Authentication token = new TestingAuthenticationToken("test", "Password", "MOCK_INDEX");
|
Authentication token = new TestingAuthenticationToken("test", "Password", "MOCK_INDEX");
|
||||||
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
|
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
|
||||||
assertThat(wipe.isAllowed("/foo/index.jsp", token)).isTrue();
|
Assertions.assertThat(wipe.isAllowed("/foo/index.jsp", token)).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -105,8 +102,10 @@ public class DefaultWebInvocationPrivilegeEvaluatorTests {
|
||||||
public void deniesAccessIfAccessDecisionManagerDoes() {
|
public void deniesAccessIfAccessDecisionManagerDoes() {
|
||||||
Authentication token = new TestingAuthenticationToken("test", "Password", "MOCK_INDEX");
|
Authentication token = new TestingAuthenticationToken("test", "Password", "MOCK_INDEX");
|
||||||
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
|
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
|
||||||
willThrow(new AccessDeniedException("")).given(this.adm).decide(any(Authentication.class), any(), anyList());
|
BDDMockito.willThrow(new AccessDeniedException(""))
|
||||||
assertThat(wipe.isAllowed("/foo/index.jsp", token)).isFalse();
|
.given(this.adm)
|
||||||
|
.decide(ArgumentMatchers.any(Authentication.class), ArgumentMatchers.any(), ArgumentMatchers.anyList());
|
||||||
|
Assertions.assertThat(wipe.isAllowed("/foo/index.jsp", token)).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -118,8 +117,9 @@ public class DefaultWebInvocationPrivilegeEvaluatorTests {
|
||||||
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
|
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
|
||||||
wipe.setServletContext(servletContext);
|
wipe.setServletContext(servletContext);
|
||||||
wipe.isAllowed("/foo/index.jsp", token);
|
wipe.isAllowed("/foo/index.jsp", token);
|
||||||
verify(this.adm).decide(eq(token), filterInvocationArgumentCaptor.capture(), any());
|
Mockito.verify(this.adm)
|
||||||
assertThat(filterInvocationArgumentCaptor.getValue().getRequest().getServletContext()).isNotNull();
|
.decide(ArgumentMatchers.eq(token), filterInvocationArgumentCaptor.capture(), ArgumentMatchers.any());
|
||||||
|
Assertions.assertThat(filterInvocationArgumentCaptor.getValue().getRequest().getServletContext()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -23,6 +23,7 @@ import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
@ -85,7 +86,7 @@ public class ChannelDecisionManagerImplTests {
|
||||||
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
|
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
|
||||||
List<ConfigAttribute> cad = SecurityConfig.createList("xyz");
|
List<ConfigAttribute> cad = SecurityConfig.createList("xyz");
|
||||||
cdm.decide(fi, cad);
|
cdm.decide(fi, cad);
|
||||||
assertThat(fi.getResponse().isCommitted()).isTrue();
|
Assertions.assertThat(fi.getResponse().isCommitted()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -100,7 +101,7 @@ public class ChannelDecisionManagerImplTests {
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
|
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
|
||||||
cdm.decide(fi, SecurityConfig.createList(new String[] { "abc", "ANY_CHANNEL" }));
|
cdm.decide(fi, SecurityConfig.createList(new String[] { "abc", "ANY_CHANNEL" }));
|
||||||
assertThat(fi.getResponse().isCommitted()).isFalse();
|
Assertions.assertThat(fi.getResponse().isCommitted()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -117,7 +118,7 @@ public class ChannelDecisionManagerImplTests {
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
|
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
|
||||||
cdm.decide(fi, SecurityConfig.createList("SOME_ATTRIBUTE_NO_PROCESSORS_SUPPORT"));
|
cdm.decide(fi, SecurityConfig.createList("SOME_ATTRIBUTE_NO_PROCESSORS_SUPPORT"));
|
||||||
assertThat(fi.getResponse().isCommitted()).isFalse();
|
Assertions.assertThat(fi.getResponse().isCommitted()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
|
@ -28,11 +28,11 @@ import org.springframework.security.access.ConfigAttribute;
|
||||||
import org.springframework.security.access.SecurityConfig;
|
import org.springframework.security.access.SecurityConfig;
|
||||||
import org.springframework.security.web.FilterInvocation;
|
import org.springframework.security.web.FilterInvocation;
|
||||||
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
|
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
|
||||||
|
import org.springframework.security.web.servlet.TestMockHttpServletRequests;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.springframework.security.web.servlet.TestMockHttpServletRequests.get;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link ChannelProcessingFilter}.
|
* Tests {@link ChannelProcessingFilter}.
|
||||||
|
@ -82,7 +82,7 @@ public class ChannelProcessingFilterTests {
|
||||||
filter.setChannelDecisionManager(new MockChannelDecisionManager(true, "SOME_ATTRIBUTE"));
|
filter.setChannelDecisionManager(new MockChannelDecisionManager(true, "SOME_ATTRIBUTE"));
|
||||||
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SOME_ATTRIBUTE");
|
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SOME_ATTRIBUTE");
|
||||||
filter.setSecurityMetadataSource(fids);
|
filter.setSecurityMetadataSource(fids);
|
||||||
MockHttpServletRequest request = get("/path").build();
|
MockHttpServletRequest request = TestMockHttpServletRequests.get("/path").build();
|
||||||
request.setQueryString("info=now");
|
request.setQueryString("info=now");
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
filter.doFilter(request, response, mock(FilterChain.class));
|
filter.doFilter(request, response, mock(FilterChain.class));
|
||||||
|
@ -94,7 +94,7 @@ public class ChannelProcessingFilterTests {
|
||||||
filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "SOME_ATTRIBUTE"));
|
filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "SOME_ATTRIBUTE"));
|
||||||
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SOME_ATTRIBUTE");
|
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SOME_ATTRIBUTE");
|
||||||
filter.setSecurityMetadataSource(fids);
|
filter.setSecurityMetadataSource(fids);
|
||||||
MockHttpServletRequest request = get("/path").build();
|
MockHttpServletRequest request = TestMockHttpServletRequests.get("/path").build();
|
||||||
request.setQueryString("info=now");
|
request.setQueryString("info=now");
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
filter.doFilter(request, response, mock(FilterChain.class));
|
filter.doFilter(request, response, mock(FilterChain.class));
|
||||||
|
@ -106,7 +106,7 @@ public class ChannelProcessingFilterTests {
|
||||||
filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "NOT_USED"));
|
filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "NOT_USED"));
|
||||||
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "NOT_USED");
|
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "NOT_USED");
|
||||||
filter.setSecurityMetadataSource(fids);
|
filter.setSecurityMetadataSource(fids);
|
||||||
MockHttpServletRequest request = get("/PATH_NOT_MATCHING_CONFIG_ATTRIBUTE").build();
|
MockHttpServletRequest request = TestMockHttpServletRequests.get("/PATH_NOT_MATCHING_CONFIG_ATTRIBUTE").build();
|
||||||
request.setQueryString("info=now");
|
request.setQueryString("info=now");
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
filter.doFilter(request, response, mock(FilterChain.class));
|
filter.doFilter(request, response, mock(FilterChain.class));
|
|
@ -17,17 +17,18 @@
|
||||||
package org.springframework.security.web.access.channel;
|
package org.springframework.security.web.access.channel;
|
||||||
|
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
import org.springframework.mock.web.MockHttpServletResponse;
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
import org.springframework.security.access.SecurityConfig;
|
import org.springframework.security.access.SecurityConfig;
|
||||||
import org.springframework.security.web.FilterInvocation;
|
import org.springframework.security.web.FilterInvocation;
|
||||||
|
import org.springframework.security.web.servlet.TestMockHttpServletRequests;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.springframework.security.web.servlet.TestMockHttpServletRequests.get;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link InsecureChannelProcessor}.
|
* Tests {@link InsecureChannelProcessor}.
|
||||||
|
@ -38,19 +39,21 @@ public class InsecureChannelProcessorTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDecideDetectsAcceptableChannel() throws Exception {
|
public void testDecideDetectsAcceptableChannel() throws Exception {
|
||||||
MockHttpServletRequest request = get("http://localhost:8080").requestUri("/bigapp", "/servlet", null)
|
MockHttpServletRequest request = TestMockHttpServletRequests.get("http://localhost:8080")
|
||||||
|
.requestUri("/bigapp", "/servlet", null)
|
||||||
.queryString("info=true")
|
.queryString("info=true")
|
||||||
.build();
|
.build();
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
|
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
|
||||||
InsecureChannelProcessor processor = new InsecureChannelProcessor();
|
InsecureChannelProcessor processor = new InsecureChannelProcessor();
|
||||||
processor.decide(fi, SecurityConfig.createList("SOME_IGNORED_ATTRIBUTE", "REQUIRES_INSECURE_CHANNEL"));
|
processor.decide(fi, SecurityConfig.createList("SOME_IGNORED_ATTRIBUTE", "REQUIRES_INSECURE_CHANNEL"));
|
||||||
assertThat(fi.getResponse().isCommitted()).isFalse();
|
Assertions.assertThat(fi.getResponse().isCommitted()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDecideDetectsUnacceptableChannel() throws Exception {
|
public void testDecideDetectsUnacceptableChannel() throws Exception {
|
||||||
MockHttpServletRequest request = get("https://localhost:8443").requestUri("/bigapp", "/servlet", null)
|
MockHttpServletRequest request = TestMockHttpServletRequests.get("https://localhost:8443")
|
||||||
|
.requestUri("/bigapp", "/servlet", null)
|
||||||
.queryString("info=true")
|
.queryString("info=true")
|
||||||
.build();
|
.build();
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
@ -58,7 +61,7 @@ public class InsecureChannelProcessorTests {
|
||||||
InsecureChannelProcessor processor = new InsecureChannelProcessor();
|
InsecureChannelProcessor processor = new InsecureChannelProcessor();
|
||||||
processor.decide(fi,
|
processor.decide(fi,
|
||||||
SecurityConfig.createList(new String[] { "SOME_IGNORED_ATTRIBUTE", "REQUIRES_INSECURE_CHANNEL" }));
|
SecurityConfig.createList(new String[] { "SOME_IGNORED_ATTRIBUTE", "REQUIRES_INSECURE_CHANNEL" }));
|
||||||
assertThat(fi.getResponse().isCommitted()).isTrue();
|
Assertions.assertThat(fi.getResponse().isCommitted()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
|
@ -17,17 +17,18 @@
|
||||||
package org.springframework.security.web.access.channel;
|
package org.springframework.security.web.access.channel;
|
||||||
|
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
import org.springframework.mock.web.MockHttpServletResponse;
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
import org.springframework.security.access.SecurityConfig;
|
import org.springframework.security.access.SecurityConfig;
|
||||||
import org.springframework.security.web.FilterInvocation;
|
import org.springframework.security.web.FilterInvocation;
|
||||||
|
import org.springframework.security.web.servlet.TestMockHttpServletRequests;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.springframework.security.web.servlet.TestMockHttpServletRequests.get;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link SecureChannelProcessor}.
|
* Tests {@link SecureChannelProcessor}.
|
||||||
|
@ -38,19 +39,21 @@ public class SecureChannelProcessorTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDecideDetectsAcceptableChannel() throws Exception {
|
public void testDecideDetectsAcceptableChannel() throws Exception {
|
||||||
MockHttpServletRequest request = get("https://localhost:8443").requestUri("/bigapp", "/servlet", null)
|
MockHttpServletRequest request = TestMockHttpServletRequests.get("https://localhost:8443")
|
||||||
|
.requestUri("/bigapp", "/servlet", null)
|
||||||
.queryString("info=true")
|
.queryString("info=true")
|
||||||
.build();
|
.build();
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
|
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
|
||||||
SecureChannelProcessor processor = new SecureChannelProcessor();
|
SecureChannelProcessor processor = new SecureChannelProcessor();
|
||||||
processor.decide(fi, SecurityConfig.createList("SOME_IGNORED_ATTRIBUTE", "REQUIRES_SECURE_CHANNEL"));
|
processor.decide(fi, SecurityConfig.createList("SOME_IGNORED_ATTRIBUTE", "REQUIRES_SECURE_CHANNEL"));
|
||||||
assertThat(fi.getResponse().isCommitted()).isFalse();
|
Assertions.assertThat(fi.getResponse().isCommitted()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDecideDetectsUnacceptableChannel() throws Exception {
|
public void testDecideDetectsUnacceptableChannel() throws Exception {
|
||||||
MockHttpServletRequest request = get("http://localhost:8080").requestUri("/bigapp", "/servlet", null)
|
MockHttpServletRequest request = TestMockHttpServletRequests.get("http://localhost:8080")
|
||||||
|
.requestUri("/bigapp", "/servlet", null)
|
||||||
.queryString("info=true")
|
.queryString("info=true")
|
||||||
.build();
|
.build();
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
@ -58,7 +61,7 @@ public class SecureChannelProcessorTests {
|
||||||
SecureChannelProcessor processor = new SecureChannelProcessor();
|
SecureChannelProcessor processor = new SecureChannelProcessor();
|
||||||
processor.decide(fi,
|
processor.decide(fi,
|
||||||
SecurityConfig.createList(new String[] { "SOME_IGNORED_ATTRIBUTE", "REQUIRES_SECURE_CHANNEL" }));
|
SecurityConfig.createList(new String[] { "SOME_IGNORED_ATTRIBUTE", "REQUIRES_SECURE_CHANNEL" }));
|
||||||
assertThat(fi.getResponse().isCommitted()).isTrue();
|
Assertions.assertThat(fi.getResponse().isCommitted()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
|
@ -28,12 +28,12 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
import org.springframework.security.access.ConfigAttribute;
|
import org.springframework.security.access.ConfigAttribute;
|
||||||
import org.springframework.security.access.SecurityConfig;
|
import org.springframework.security.access.SecurityConfig;
|
||||||
import org.springframework.security.web.FilterInvocation;
|
import org.springframework.security.web.FilterInvocation;
|
||||||
|
import org.springframework.security.web.servlet.TestMockHttpServletRequests;
|
||||||
|
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
|
||||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.springframework.security.web.servlet.TestMockHttpServletRequests.request;
|
|
||||||
import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link DefaultFilterInvocationSecurityMetadataSource}.
|
* Tests {@link DefaultFilterInvocationSecurityMetadataSource}.
|
||||||
|
@ -48,7 +48,7 @@ public class DefaultFilterInvocationSecurityMetadataSourceTests {
|
||||||
|
|
||||||
private void createFids(String pattern, HttpMethod method) {
|
private void createFids(String pattern, HttpMethod method) {
|
||||||
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = new LinkedHashMap<>();
|
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = new LinkedHashMap<>();
|
||||||
requestMap.put(pathPattern(method, pattern), this.def);
|
requestMap.put(PathPatternRequestMatcher.pathPattern(method, pattern), this.def);
|
||||||
this.fids = new DefaultFilterInvocationSecurityMetadataSource(requestMap);
|
this.fids = new DefaultFilterInvocationSecurityMetadataSource(requestMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,8 +117,9 @@ public class DefaultFilterInvocationSecurityMetadataSourceTests {
|
||||||
public void mixingPatternsWithAndWithoutHttpMethodsIsSupported() {
|
public void mixingPatternsWithAndWithoutHttpMethodsIsSupported() {
|
||||||
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = new LinkedHashMap<>();
|
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = new LinkedHashMap<>();
|
||||||
Collection<ConfigAttribute> userAttrs = SecurityConfig.createList("A");
|
Collection<ConfigAttribute> userAttrs = SecurityConfig.createList("A");
|
||||||
requestMap.put(pathPattern("/user/**"), userAttrs);
|
requestMap.put(PathPatternRequestMatcher.pathPattern("/user/**"), userAttrs);
|
||||||
requestMap.put(pathPattern(HttpMethod.GET, "/teller/**"), SecurityConfig.createList("B"));
|
requestMap.put(PathPatternRequestMatcher.pathPattern(HttpMethod.GET, "/teller/**"),
|
||||||
|
SecurityConfig.createList("B"));
|
||||||
this.fids = new DefaultFilterInvocationSecurityMetadataSource(requestMap);
|
this.fids = new DefaultFilterInvocationSecurityMetadataSource(requestMap);
|
||||||
FilterInvocation fi = createFilterInvocation("/user", null, null, "GET");
|
FilterInvocation fi = createFilterInvocation("/user", null, null, "GET");
|
||||||
Collection<ConfigAttribute> attrs = this.fids.getAttributes(fi);
|
Collection<ConfigAttribute> attrs = this.fids.getAttributes(fi);
|
||||||
|
@ -141,7 +142,8 @@ public class DefaultFilterInvocationSecurityMetadataSourceTests {
|
||||||
|
|
||||||
private FilterInvocation createFilterInvocation(String servletPath, String pathInfo, String queryString,
|
private FilterInvocation createFilterInvocation(String servletPath, String pathInfo, String queryString,
|
||||||
String method) {
|
String method) {
|
||||||
MockHttpServletRequest request = request(method).requestUri(null, servletPath, pathInfo)
|
MockHttpServletRequest request = TestMockHttpServletRequests.request(method)
|
||||||
|
.requestUri(null, servletPath, pathInfo)
|
||||||
.queryString(queryString)
|
.queryString(queryString)
|
||||||
.build();
|
.build();
|
||||||
return new FilterInvocation(request, new MockHttpServletResponse(), mock(FilterChain.class));
|
return new FilterInvocation(request, new MockHttpServletResponse(), mock(FilterChain.class));
|
|
@ -39,6 +39,7 @@ import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.web.FilterInvocation;
|
import org.springframework.security.web.FilterInvocation;
|
||||||
|
import org.springframework.security.web.servlet.TestMockHttpServletRequests;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
|
@ -53,7 +54,6 @@ import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
import static org.springframework.security.web.servlet.TestMockHttpServletRequests.get;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link FilterSecurityInterceptor}.
|
* Tests {@link FilterSecurityInterceptor}.
|
||||||
|
@ -189,7 +189,7 @@ public class FilterSecurityInterceptorTests {
|
||||||
|
|
||||||
private FilterInvocation createinvocation() {
|
private FilterInvocation createinvocation() {
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
MockHttpServletRequest request = get("/secure/page.html").build();
|
MockHttpServletRequest request = TestMockHttpServletRequests.get("/secure/page.html").build();
|
||||||
FilterChain chain = mock(FilterChain.class);
|
FilterChain chain = mock(FilterChain.class);
|
||||||
FilterInvocation fi = new FilterInvocation(request, response, chain);
|
FilterInvocation fi = new FilterInvocation(request, response, chain);
|
||||||
return fi;
|
return fi;
|
|
@ -21,6 +21,7 @@ dependencies {
|
||||||
|
|
||||||
testRuntimeOnly 'jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api'
|
testRuntimeOnly 'jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api'
|
||||||
|
|
||||||
|
testImplementation project(':spring-security-access')
|
||||||
testImplementation "org.assertj:assertj-core"
|
testImplementation "org.assertj:assertj-core"
|
||||||
testImplementation "org.junit.jupiter:junit-jupiter-api"
|
testImplementation "org.junit.jupiter:junit-jupiter-api"
|
||||||
testImplementation "org.junit.jupiter:junit-jupiter-params"
|
testImplementation "org.junit.jupiter:junit-jupiter-params"
|
||||||
|
|
|
@ -39,7 +39,6 @@ dependencies {
|
||||||
api 'org.springframework:spring-expression'
|
api 'org.springframework:spring-expression'
|
||||||
api 'org.springframework:spring-web'
|
api 'org.springframework:spring-web'
|
||||||
|
|
||||||
optional project(':spring-security-access')
|
|
||||||
optional 'com.fasterxml.jackson.core:jackson-databind'
|
optional 'com.fasterxml.jackson.core:jackson-databind'
|
||||||
optional 'io.micrometer:context-propagation'
|
optional 'io.micrometer:context-propagation'
|
||||||
optional 'io.projectreactor:reactor-core'
|
optional 'io.projectreactor:reactor-core'
|
||||||
|
|
|
@ -32,10 +32,10 @@ import org.springframework.expression.EvaluationContext;
|
||||||
import org.springframework.expression.Expression;
|
import org.springframework.expression.Expression;
|
||||||
import org.springframework.expression.ExpressionParser;
|
import org.springframework.expression.ExpressionParser;
|
||||||
import org.springframework.expression.TypedValue;
|
import org.springframework.expression.TypedValue;
|
||||||
import org.springframework.security.access.SecurityConfig;
|
|
||||||
import org.springframework.security.access.expression.SecurityExpressionRoot;
|
import org.springframework.security.access.expression.SecurityExpressionRoot;
|
||||||
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
|
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
|
||||||
|
|
||||||
|
@ -73,15 +73,15 @@ public class DefaultHttpSecurityExpressionHandlerTests {
|
||||||
@Test
|
@Test
|
||||||
public void expressionPropertiesAreResolvedAgainstAppContextBeans() {
|
public void expressionPropertiesAreResolvedAgainstAppContextBeans() {
|
||||||
StaticApplicationContext appContext = new StaticApplicationContext();
|
StaticApplicationContext appContext = new StaticApplicationContext();
|
||||||
RootBeanDefinition bean = new RootBeanDefinition(SecurityConfig.class);
|
RootBeanDefinition bean = new RootBeanDefinition(SimpleGrantedAuthority.class);
|
||||||
bean.getConstructorArgumentValues().addGenericArgumentValue("ROLE_A");
|
bean.getConstructorArgumentValues().addGenericArgumentValue("ROLE_A");
|
||||||
appContext.registerBeanDefinition("role", bean);
|
appContext.registerBeanDefinition("role", bean);
|
||||||
this.handler.setApplicationContext(appContext);
|
this.handler.setApplicationContext(appContext);
|
||||||
EvaluationContext ctx = this.handler.createEvaluationContext(mock(Authentication.class),
|
EvaluationContext ctx = this.handler.createEvaluationContext(mock(Authentication.class),
|
||||||
mock(RequestAuthorizationContext.class));
|
mock(RequestAuthorizationContext.class));
|
||||||
ExpressionParser parser = this.handler.getExpressionParser();
|
ExpressionParser parser = this.handler.getExpressionParser();
|
||||||
assertThat(parser.parseExpression("@role.getAttribute() == 'ROLE_A'").getValue(ctx, Boolean.class)).isTrue();
|
assertThat(parser.parseExpression("@role.getAuthority() == 'ROLE_A'").getValue(ctx, Boolean.class)).isTrue();
|
||||||
assertThat(parser.parseExpression("@role.attribute == 'ROLE_A'").getValue(ctx, Boolean.class)).isTrue();
|
assertThat(parser.parseExpression("@role.authority == 'ROLE_A'").getValue(ctx, Boolean.class)).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue