|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2021 the original author or authors. |
| 2 | + * Copyright 2002-2022 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
16 | 16 |
|
17 | 17 | package org.springframework.security.web.access.intercept;
|
18 | 18 |
|
| 19 | +import java.io.IOException; |
19 | 20 | import java.util.function.Supplier;
|
20 | 21 |
|
| 22 | +import javax.servlet.DispatcherType; |
21 | 23 | import javax.servlet.FilterChain;
|
| 24 | +import javax.servlet.ServletException; |
22 | 25 | import javax.servlet.http.HttpServletRequest;
|
23 | 26 |
|
24 | 27 | import org.junit.jupiter.api.AfterEach;
|
| 28 | +import org.junit.jupiter.api.BeforeEach; |
25 | 29 | import org.junit.jupiter.api.Test;
|
26 | 30 | import org.mockito.ArgumentCaptor;
|
27 | 31 |
|
| 32 | +import org.springframework.mock.web.MockFilterChain; |
28 | 33 | import org.springframework.mock.web.MockHttpServletRequest;
|
29 | 34 | import org.springframework.mock.web.MockHttpServletResponse;
|
30 | 35 | import org.springframework.security.access.AccessDeniedException;
|
|
36 | 41 | import org.springframework.security.core.context.SecurityContext;
|
37 | 42 | import org.springframework.security.core.context.SecurityContextHolder;
|
38 | 43 | import org.springframework.security.core.context.SecurityContextImpl;
|
| 44 | +import org.springframework.test.util.ReflectionTestUtils; |
39 | 45 |
|
40 | 46 | import static org.assertj.core.api.Assertions.assertThat;
|
41 | 47 | import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
42 | 48 | import static org.mockito.ArgumentMatchers.any;
|
43 | 49 | import static org.mockito.ArgumentMatchers.eq;
|
44 | 50 | import static org.mockito.BDDMockito.willThrow;
|
45 | 51 | import static org.mockito.Mockito.mock;
|
| 52 | +import static org.mockito.Mockito.spy; |
46 | 53 | import static org.mockito.Mockito.verify;
|
47 | 54 | import static org.mockito.Mockito.verifyNoInteractions;
|
48 | 55 |
|
|
53 | 60 | */
|
54 | 61 | public class AuthorizationFilterTests {
|
55 | 62 |
|
| 63 | + private static final String ALREADY_FILTERED_ATTRIBUTE_NAME = "org.springframework.security.web.access.intercept.AuthorizationFilter.APPLIED"; |
| 64 | + |
| 65 | + private AuthorizationFilter filter; |
| 66 | + |
| 67 | + private AuthorizationManager<HttpServletRequest> authorizationManager; |
| 68 | + |
| 69 | + private MockHttpServletRequest request = new MockHttpServletRequest(); |
| 70 | + |
| 71 | + private final MockHttpServletResponse response = new MockHttpServletResponse(); |
| 72 | + |
| 73 | + private final FilterChain chain = new MockFilterChain(); |
| 74 | + |
| 75 | + @BeforeEach |
| 76 | + public void setup() { |
| 77 | + this.authorizationManager = mock(AuthorizationManager.class); |
| 78 | + this.filter = new AuthorizationFilter(this.authorizationManager); |
| 79 | + } |
| 80 | + |
56 | 81 | @AfterEach
|
57 | 82 | public void tearDown() {
|
58 | 83 | SecurityContextHolder.clearContext();
|
@@ -132,4 +157,102 @@ public void getAuthorizationManager() {
|
132 | 157 | assertThat(authorizationFilter.getAuthorizationManager()).isSameAs(authorizationManager);
|
133 | 158 | }
|
134 | 159 |
|
| 160 | + @Test |
| 161 | + public void doFilterWhenObserveOncePerRequestTrueAndIsAppliedThenNotInvoked() throws ServletException, IOException { |
| 162 | + setIsAppliedTrue(); |
| 163 | + this.filter.setObserveOncePerRequest(true); |
| 164 | + this.filter.doFilter(this.request, this.response, this.chain); |
| 165 | + verifyNoInteractions(this.authorizationManager); |
| 166 | + } |
| 167 | + |
| 168 | + @Test |
| 169 | + public void doFilterWhenObserveOncePerRequestTrueAndNotAppliedThenInvoked() throws ServletException, IOException { |
| 170 | + this.filter.setObserveOncePerRequest(true); |
| 171 | + this.filter.doFilter(this.request, this.response, this.chain); |
| 172 | + verify(this.authorizationManager).verify(any(), any()); |
| 173 | + } |
| 174 | + |
| 175 | + @Test |
| 176 | + public void doFilterWhenObserveOncePerRequestFalseAndIsAppliedThenInvoked() throws ServletException, IOException { |
| 177 | + setIsAppliedTrue(); |
| 178 | + this.filter.setObserveOncePerRequest(false); |
| 179 | + this.filter.doFilter(this.request, this.response, this.chain); |
| 180 | + verify(this.authorizationManager).verify(any(), any()); |
| 181 | + } |
| 182 | + |
| 183 | + @Test |
| 184 | + public void doFilterWhenObserveOncePerRequestFalseAndNotAppliedThenInvoked() throws ServletException, IOException { |
| 185 | + this.filter.setObserveOncePerRequest(false); |
| 186 | + this.filter.doFilter(this.request, this.response, this.chain); |
| 187 | + verify(this.authorizationManager).verify(any(), any()); |
| 188 | + } |
| 189 | + |
| 190 | + @Test |
| 191 | + public void doFilterWhenFilterErrorDispatchFalseAndIsErrorThenNotInvoked() throws ServletException, IOException { |
| 192 | + this.request.setDispatcherType(DispatcherType.ERROR); |
| 193 | + this.filter.setFilterErrorDispatch(false); |
| 194 | + this.filter.doFilter(this.request, this.response, this.chain); |
| 195 | + verifyNoInteractions(this.authorizationManager); |
| 196 | + } |
| 197 | + |
| 198 | + @Test |
| 199 | + public void doFilterWhenFilterErrorDispatchTrueAndIsErrorThenInvoked() throws ServletException, IOException { |
| 200 | + this.request.setDispatcherType(DispatcherType.ERROR); |
| 201 | + this.filter.setFilterErrorDispatch(true); |
| 202 | + this.filter.doFilter(this.request, this.response, this.chain); |
| 203 | + verify(this.authorizationManager).verify(any(), any()); |
| 204 | + } |
| 205 | + |
| 206 | + @Test |
| 207 | + public void doFilterWhenFilterThenSetAlreadyFilteredAttribute() throws ServletException, IOException { |
| 208 | + this.request = mock(MockHttpServletRequest.class); |
| 209 | + this.filter.doFilter(this.request, this.response, this.chain); |
| 210 | + verify(this.request).setAttribute(ALREADY_FILTERED_ATTRIBUTE_NAME, Boolean.TRUE); |
| 211 | + } |
| 212 | + |
| 213 | + @Test |
| 214 | + public void doFilterWhenFilterThenRemoveAlreadyFilteredAttribute() throws ServletException, IOException { |
| 215 | + this.request = spy(MockHttpServletRequest.class); |
| 216 | + this.filter.doFilter(this.request, this.response, this.chain); |
| 217 | + verify(this.request).setAttribute(ALREADY_FILTERED_ATTRIBUTE_NAME, Boolean.TRUE); |
| 218 | + assertThat(this.request.getAttribute(ALREADY_FILTERED_ATTRIBUTE_NAME)).isNull(); |
| 219 | + } |
| 220 | + |
| 221 | + @Test |
| 222 | + public void doFilterWhenFilterAsyncDispatchTrueAndIsAsyncThenInvoked() throws ServletException, IOException { |
| 223 | + this.request.setDispatcherType(DispatcherType.ASYNC); |
| 224 | + this.filter.setFilterAsyncDispatch(true); |
| 225 | + this.filter.doFilter(this.request, this.response, this.chain); |
| 226 | + verify(this.authorizationManager).verify(any(), any()); |
| 227 | + } |
| 228 | + |
| 229 | + @Test |
| 230 | + public void doFilterWhenFilterAsyncDispatchFalseAndIsAsyncThenNotInvoked() throws ServletException, IOException { |
| 231 | + this.request.setDispatcherType(DispatcherType.ASYNC); |
| 232 | + this.filter.setFilterAsyncDispatch(false); |
| 233 | + this.filter.doFilter(this.request, this.response, this.chain); |
| 234 | + verifyNoInteractions(this.authorizationManager); |
| 235 | + } |
| 236 | + |
| 237 | + @Test |
| 238 | + public void filterWhenFilterErrorDispatchDefaultThenFalse() { |
| 239 | + Boolean filterErrorDispatch = (Boolean) ReflectionTestUtils.getField(this.filter, "filterErrorDispatch"); |
| 240 | + assertThat(filterErrorDispatch).isFalse(); |
| 241 | + } |
| 242 | + |
| 243 | + @Test |
| 244 | + public void filterWhenFilterAsyncDispatchDefaultThenFalse() { |
| 245 | + Boolean filterAsyncDispatch = (Boolean) ReflectionTestUtils.getField(this.filter, "filterAsyncDispatch"); |
| 246 | + assertThat(filterAsyncDispatch).isFalse(); |
| 247 | + } |
| 248 | + |
| 249 | + @Test |
| 250 | + public void filterWhenObserveOncePerRequestDefaultThenTrue() { |
| 251 | + assertThat(this.filter.isObserveOncePerRequest()).isTrue(); |
| 252 | + } |
| 253 | + |
| 254 | + private void setIsAppliedTrue() { |
| 255 | + this.request.setAttribute(ALREADY_FILTERED_ATTRIBUTE_NAME, Boolean.TRUE); |
| 256 | + } |
| 257 | + |
135 | 258 | }
|
0 commit comments