|
1 | 1 | /*
|
2 |
| - * Copyright 2020-2022 the original author or authors. |
| 2 | + * Copyright 2020-2024 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.
|
|
15 | 15 | */
|
16 | 16 | package org.springframework.security.oauth2.server.authorization.web;
|
17 | 17 |
|
18 |
| -import java.time.Duration; |
19 |
| -import java.time.Instant; |
20 |
| -import java.util.Arrays; |
21 |
| -import java.util.HashSet; |
22 |
| -import java.util.function.Consumer; |
23 |
| - |
24 | 18 | import jakarta.servlet.FilterChain;
|
25 | 19 | import jakarta.servlet.http.HttpServletRequest;
|
26 | 20 | import jakarta.servlet.http.HttpServletResponse;
|
27 | 21 | import org.junit.jupiter.api.AfterEach;
|
28 | 22 | import org.junit.jupiter.api.BeforeEach;
|
29 | 23 | import org.junit.jupiter.api.Test;
|
30 |
| - |
31 | 24 | import org.springframework.http.HttpStatus;
|
32 | 25 | import org.springframework.http.converter.HttpMessageConverter;
|
33 | 26 | import org.springframework.mock.http.client.MockClientHttpResponse;
|
34 | 27 | import org.springframework.mock.web.MockHttpServletRequest;
|
35 | 28 | import org.springframework.mock.web.MockHttpServletResponse;
|
| 29 | +import org.springframework.security.authentication.AuthenticationDetailsSource; |
36 | 30 | import org.springframework.security.authentication.AuthenticationManager;
|
37 | 31 | import org.springframework.security.core.Authentication;
|
38 | 32 | import org.springframework.security.core.context.SecurityContext;
|
39 | 33 | import org.springframework.security.core.context.SecurityContextHolder;
|
40 |
| -import org.springframework.security.oauth2.core.ClientAuthenticationMethod; |
41 |
| -import org.springframework.security.oauth2.core.OAuth2AccessToken; |
42 |
| -import org.springframework.security.oauth2.core.OAuth2AuthenticationException; |
43 |
| -import org.springframework.security.oauth2.core.OAuth2Error; |
44 |
| -import org.springframework.security.oauth2.core.OAuth2ErrorCodes; |
| 34 | +import org.springframework.security.oauth2.core.*; |
45 | 35 | import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
46 | 36 | import org.springframework.security.oauth2.core.http.converter.OAuth2ErrorHttpMessageConverter;
|
47 | 37 | import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
|
|
52 | 42 | import org.springframework.security.web.authentication.AuthenticationConverter;
|
53 | 43 | import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
54 | 44 | import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
| 45 | +import org.springframework.security.web.authentication.WebAuthenticationDetails; |
| 46 | + |
| 47 | +import java.time.Duration; |
| 48 | +import java.time.Instant; |
| 49 | +import java.util.Arrays; |
| 50 | +import java.util.HashSet; |
| 51 | +import java.util.function.Consumer; |
55 | 52 |
|
56 | 53 | import static org.assertj.core.api.Assertions.assertThat;
|
57 | 54 | import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
58 | 55 | import static org.mockito.ArgumentMatchers.any;
|
59 | 56 | import static org.mockito.BDDMockito.given;
|
60 |
| -import static org.mockito.Mockito.mock; |
61 |
| -import static org.mockito.Mockito.verify; |
62 |
| -import static org.mockito.Mockito.verifyNoInteractions; |
| 57 | +import static org.mockito.Mockito.*; |
63 | 58 |
|
64 | 59 | /**
|
65 | 60 | * Tests for {@link OAuth2TokenRevocationEndpointFilter}.
|
@@ -102,6 +97,13 @@ public void constructorWhenTokenRevocationEndpointUriNullThenThrowIllegalArgumen
|
102 | 97 | .hasMessage("tokenRevocationEndpointUri cannot be empty");
|
103 | 98 | }
|
104 | 99 |
|
| 100 | + @Test |
| 101 | + public void setAuthenticationDetailsSourceWhenNullThenThrowIllegalArgumentException() { |
| 102 | + assertThatThrownBy(() -> this.filter.setAuthenticationDetailsSource(null)) |
| 103 | + .isInstanceOf(IllegalArgumentException.class) |
| 104 | + .hasMessage("authenticationDetailsSource cannot be null"); |
| 105 | + } |
| 106 | + |
105 | 107 | @Test
|
106 | 108 | public void setAuthenticationConverterWhenNullThenThrowIllegalArgumentException() {
|
107 | 109 | assertThatThrownBy(() -> this.filter.setAuthenticationConverter(null))
|
@@ -198,6 +200,40 @@ public void doFilterWhenTokenRevocationRequestValidThenSuccessResponse() throws
|
198 | 200 | assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
|
199 | 201 | }
|
200 | 202 |
|
| 203 | + @Test |
| 204 | + public void doFilterWhenCustomAuthenticationDetailsSourceThenUsed() throws Exception { |
| 205 | + RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); |
| 206 | + Authentication clientPrincipal = new OAuth2ClientAuthenticationToken(registeredClient, |
| 207 | + ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret()); |
| 208 | + |
| 209 | + MockHttpServletRequest request = createTokenRevocationRequest(); |
| 210 | + |
| 211 | + AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> authenticationDetailsSource = mock( |
| 212 | + AuthenticationDetailsSource.class); |
| 213 | + WebAuthenticationDetails webAuthenticationDetails = new WebAuthenticationDetails(request); |
| 214 | + given(authenticationDetailsSource.buildDetails(any())).willReturn(webAuthenticationDetails); |
| 215 | + this.filter.setAuthenticationDetailsSource(authenticationDetailsSource); |
| 216 | + |
| 217 | + OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "token", |
| 218 | + Instant.now(), Instant.now().plus(Duration.ofHours(1)), |
| 219 | + new HashSet<>(Arrays.asList("scope1", "scope2"))); |
| 220 | + OAuth2TokenRevocationAuthenticationToken tokenRevocationAuthentication = new OAuth2TokenRevocationAuthenticationToken( |
| 221 | + accessToken, clientPrincipal); |
| 222 | + |
| 223 | + given(this.authenticationManager.authenticate(any())).willReturn(tokenRevocationAuthentication); |
| 224 | + |
| 225 | + SecurityContext securityContext = SecurityContextHolder.createEmptyContext(); |
| 226 | + securityContext.setAuthentication(clientPrincipal); |
| 227 | + SecurityContextHolder.setContext(securityContext); |
| 228 | + |
| 229 | + MockHttpServletResponse response = new MockHttpServletResponse(); |
| 230 | + FilterChain filterChain = mock(FilterChain.class); |
| 231 | + |
| 232 | + this.filter.doFilter(request, response, filterChain); |
| 233 | + |
| 234 | + verify(authenticationDetailsSource).buildDetails(any()); |
| 235 | + } |
| 236 | + |
201 | 237 | @Test
|
202 | 238 | public void doFilterWhenCustomAuthenticationConverterThenUsed() throws Exception {
|
203 | 239 | RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
|
|
0 commit comments