Skip to content

Commit 15306c1

Browse files
Merge branch '6.1.x' into 6.2.x
2 parents 94f885c + 750cb30 commit 15306c1

File tree

16 files changed

+123
-26
lines changed

16 files changed

+123
-26
lines changed

cas/src/main/java/org/springframework/security/cas/web/CasAuthenticationFilter.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@
2727
import org.apereo.cas.client.validation.TicketValidator;
2828

2929
import org.springframework.core.log.LogMessage;
30-
import org.springframework.security.authentication.AnonymousAuthenticationToken;
3130
import org.springframework.security.authentication.AuthenticationDetailsSource;
31+
import org.springframework.security.authentication.AuthenticationTrustResolver;
32+
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
3233
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
3334
import org.springframework.security.cas.ServiceProperties;
3435
import org.springframework.security.cas.authentication.CasServiceTicketAuthenticationToken;
@@ -199,6 +200,8 @@ public class CasAuthenticationFilter extends AbstractAuthenticationProcessingFil
199200
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
200201
.getContextHolderStrategy();
201202

203+
private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
204+
202205
public CasAuthenticationFilter() {
203206
super("/login/cas");
204207
setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler());
@@ -348,8 +351,7 @@ private boolean proxyTicketRequest(boolean serviceTicketRequest, HttpServletRequ
348351
*/
349352
private boolean authenticated() {
350353
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
351-
return authentication != null && authentication.isAuthenticated()
352-
&& !(authentication instanceof AnonymousAuthenticationToken);
354+
return this.trustResolver.isAuthenticated(authentication);
353355
}
354356

355357
/**

config/src/test/java/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurerTests.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import jakarta.servlet.http.HttpSession;
3030
import org.junit.jupiter.api.Test;
3131
import org.junit.jupiter.api.extension.ExtendWith;
32+
import org.mockito.Answers;
3233

3334
import org.springframework.beans.factory.annotation.Autowired;
3435
import org.springframework.context.annotation.Bean;
@@ -82,6 +83,7 @@
8283
import static org.mockito.Mockito.spy;
8384
import static org.mockito.Mockito.verify;
8485
import static org.mockito.Mockito.verifyNoInteractions;
86+
import static org.mockito.Mockito.withSettings;
8587
import static org.springframework.security.config.Customizer.withDefaults;
8688
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
8789
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
@@ -304,7 +306,8 @@ public void configureWhenRegisteringObjectPostProcessorThenInvokedOnChangeSessio
304306
@Test
305307
public void getWhenAnonymousRequestAndTrustResolverSharedObjectReturnsAnonymousFalseThenSessionIsSaved()
306308
throws Exception {
307-
SharedTrustResolverConfig.TR = mock(AuthenticationTrustResolver.class);
309+
SharedTrustResolverConfig.TR = mock(AuthenticationTrustResolver.class,
310+
withSettings().defaultAnswer(Answers.CALLS_REAL_METHODS));
308311
given(SharedTrustResolverConfig.TR.isAnonymous(any())).willReturn(false);
309312
this.spring.register(SharedTrustResolverConfig.class).autowire();
310313
MvcResult mvcResult = this.mvc.perform(get("/")).andReturn();

config/src/test/kotlin/org/springframework/security/config/annotation/web/SessionManagementDslTests.kt

+4-3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired
2828
import org.springframework.context.annotation.Bean
2929
import org.springframework.context.annotation.Configuration
3030
import org.springframework.mock.web.MockHttpSession
31+
import org.springframework.security.authentication.TestingAuthenticationToken
3132
import org.springframework.security.config.annotation.web.builders.HttpSecurity
3233
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
3334
import org.springframework.security.config.http.SessionCreationPolicy
@@ -118,7 +119,7 @@ class SessionManagementDslTests {
118119
@Test
119120
fun `session management when session authentication error url then redirected to url`() {
120121
this.spring.register(SessionAuthenticationErrorUrlConfig::class.java).autowire()
121-
val authentication: Authentication = mockk()
122+
val authentication: Authentication = TestingAuthenticationToken("user", "password", "ROLE_USER")
122123
val session: MockHttpSession = mockk(relaxed = true)
123124
every { session.changeSessionId() } throws SessionAuthenticationException("any SessionAuthenticationException")
124125
every<Any?> { session.getAttribute(any()) } returns null
@@ -150,7 +151,7 @@ class SessionManagementDslTests {
150151
@Test
151152
fun `session management when session authentication failure handler then handler used`() {
152153
this.spring.register(SessionAuthenticationFailureHandlerConfig::class.java).autowire()
153-
val authentication: Authentication = mockk()
154+
val authentication: Authentication = TestingAuthenticationToken("user", "password", "ROLE_USER")
154155
val session: MockHttpSession = mockk(relaxed = true)
155156
every { session.changeSessionId() } throws SessionAuthenticationException("any SessionAuthenticationException")
156157
every<Any?> { session.getAttribute(any()) } returns null
@@ -210,7 +211,7 @@ class SessionManagementDslTests {
210211
fun `session management when session authentication strategy then strategy used`() {
211212
this.spring.register(SessionAuthenticationStrategyConfig::class.java).autowire()
212213
mockkObject(SessionAuthenticationStrategyConfig.STRATEGY)
213-
val authentication: Authentication = mockk(relaxed = true)
214+
val authentication: Authentication = TestingAuthenticationToken("user", "password", "ROLE_USER")
214215
val session: MockHttpSession = mockk(relaxed = true)
215216
every { session.changeSessionId() } throws SessionAuthenticationException("any SessionAuthenticationException")
216217
every<Any?> { session.getAttribute(any()) } returns null

core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ public final boolean isAnonymous() {
147147

148148
@Override
149149
public final boolean isAuthenticated() {
150-
return !isAnonymous();
150+
return this.trustResolver.isAuthenticated(getAuthentication());
151151
}
152152

153153
@Override

core/src/main/java/org/springframework/security/authentication/AuthenticationTrustResolver.java

+16-4
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,25 @@ public interface AuthenticationTrustResolver {
6161
* <p>
6262
* @param authentication to test (may be <code>null</code> in which case the method
6363
* will always return <code>false</code>)
64-
* @return <code>true</code> the passed authentication token represented an anonymous
65-
* principal and is authenticated using a remember-me token, <code>false</code>
66-
* otherwise
64+
* @return <code>true</code> the passed authentication token represented an
65+
* authenticated user ({@link #isAuthenticated(Authentication)} and not
66+
* {@link #isRememberMe(Authentication)}, <code>false</code> otherwise
6767
* @since 6.1
6868
*/
6969
default boolean isFullyAuthenticated(Authentication authentication) {
70-
return !isAnonymous(authentication) && !isRememberMe(authentication);
70+
return isAuthenticated(authentication) && !isRememberMe(authentication);
71+
}
72+
73+
/**
74+
* Checks if the {@link Authentication} is not null, authenticated, and not anonymous.
75+
* @param authentication the {@link Authentication} to check.
76+
* @return true if the {@link Authentication} is not null,
77+
* {@link #isAnonymous(Authentication)} returns false, &
78+
* {@link Authentication#isAuthenticated()} is true.
79+
* @since 6.1.7
80+
*/
81+
default boolean isAuthenticated(Authentication authentication) {
82+
return authentication != null && authentication.isAuthenticated() && !isAnonymous(authentication);
7183
}
7284

7385
}

core/src/main/java/org/springframework/security/authorization/AuthenticatedAuthorizationManager.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,7 @@ private static class AuthenticatedAuthorizationStrategy extends AbstractAuthoriz
133133

134134
@Override
135135
boolean isGranted(Authentication authentication) {
136-
return authentication != null && !this.trustResolver.isAnonymous(authentication)
137-
&& authentication.isAuthenticated();
136+
return this.trustResolver.isAuthenticated(authentication);
138137
}
139138

140139
}
@@ -143,7 +142,7 @@ private static final class FullyAuthenticatedAuthorizationStrategy extends Authe
143142

144143
@Override
145144
boolean isGranted(Authentication authentication) {
146-
return authentication != null && this.trustResolver.isFullyAuthenticated(authentication);
145+
return this.trustResolver.isFullyAuthenticated(authentication);
147146
}
148147

149148
}

core/src/test/java/org/springframework/security/access/expression/SecurityExpressionRootTests.java

+24
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.springframework.security.core.authority.AuthorityUtils;
2626

2727
import static org.assertj.core.api.Assertions.assertThat;
28+
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
2829
import static org.mockito.BDDMockito.given;
2930
import static org.mockito.Mockito.mock;
3031

@@ -134,4 +135,27 @@ public void hasAuthorityDoesNotAddDefaultPrefix() {
134135
assertThat(this.root.hasAnyAuthority("ROLE_A", "NOT")).isTrue();
135136
}
136137

138+
@Test
139+
void isAuthenticatedWhenAuthenticatedNullThenException() {
140+
this.root = new SecurityExpressionRoot((Authentication) null) {
141+
};
142+
assertThatIllegalArgumentException().isThrownBy(() -> this.root.isAuthenticated());
143+
}
144+
145+
@Test
146+
void isAuthenticatedWhenTrustResolverFalseThenFalse() {
147+
AuthenticationTrustResolver atr = mock(AuthenticationTrustResolver.class);
148+
given(atr.isAuthenticated(JOE)).willReturn(false);
149+
this.root.setTrustResolver(atr);
150+
assertThat(this.root.isAuthenticated()).isFalse();
151+
}
152+
153+
@Test
154+
void isAuthenticatedWhenTrustResolverTrueThenTrue() {
155+
AuthenticationTrustResolver atr = mock(AuthenticationTrustResolver.class);
156+
given(atr.isAuthenticated(JOE)).willReturn(true);
157+
this.root.setTrustResolver(atr);
158+
assertThat(this.root.isAuthenticated()).isTrue();
159+
}
160+
137161
}

core/src/test/java/org/springframework/security/authentication/AuthenticationTrustResolverImplTests.java

+53
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import org.junit.jupiter.api.Test;
2020

21+
import org.springframework.security.core.Authentication;
2122
import org.springframework.security.core.authority.AuthorityUtils;
2223

2324
import static org.assertj.core.api.Assertions.assertThat;
@@ -63,4 +64,56 @@ public void testGettersSetters() {
6364
assertThat(trustResolver.getRememberMeClass()).isEqualTo(TestingAuthenticationToken.class);
6465
}
6566

67+
@Test
68+
void isAuthenticatedWhenAuthenticationNullThenFalse() {
69+
AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
70+
Authentication authentication = null;
71+
assertThat(trustResolver.isAuthenticated(authentication)).isFalse();
72+
}
73+
74+
@Test
75+
void isAuthenticatedWhenAuthenticationNotAuthenticatedThenFalse() {
76+
AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
77+
TestingAuthenticationToken authentication = new TestingAuthenticationToken("user", "password");
78+
assertThat(trustResolver.isAuthenticated(authentication)).isFalse();
79+
}
80+
81+
@Test
82+
void isAuthenticatedWhenAnonymousThenFalse() {
83+
AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
84+
AnonymousAuthenticationToken authentication = new AnonymousAuthenticationToken("key", "principal",
85+
AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"));
86+
assertThat(trustResolver.isAuthenticated(authentication)).isFalse();
87+
}
88+
89+
@Test
90+
void isFullyAuthenticatedWhenAuthenticationNullThenFalse() {
91+
AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
92+
Authentication authentication = null;
93+
assertThat(trustResolver.isFullyAuthenticated(authentication)).isFalse();
94+
}
95+
96+
@Test
97+
void isFullyAuthenticatedWhenAuthenticationNotAuthenticatedThenFalse() {
98+
AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
99+
TestingAuthenticationToken authentication = new TestingAuthenticationToken("user", "password");
100+
assertThat(trustResolver.isFullyAuthenticated(authentication)).isFalse();
101+
}
102+
103+
@Test
104+
void isFullyAuthenticatedWhenAnonymousThenFalse() {
105+
AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
106+
AnonymousAuthenticationToken authentication = new AnonymousAuthenticationToken("key", "principal",
107+
AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"));
108+
assertThat(trustResolver.isFullyAuthenticated(authentication)).isFalse();
109+
}
110+
111+
@Test
112+
void isFullyAuthenticatedWhenRememberMeThenFalse() {
113+
AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
114+
RememberMeAuthenticationToken authentication = new RememberMeAuthenticationToken("key", "user",
115+
AuthorityUtils.createAuthorityList("ROLE_USER"));
116+
assertThat(trustResolver.isFullyAuthenticated(authentication)).isFalse();
117+
}
118+
66119
}

messaging/src/test/java/org/springframework/security/messaging/access/expression/DefaultMessageSecurityExpressionHandlerTests.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.junit.jupiter.api.BeforeEach;
2323
import org.junit.jupiter.api.Test;
2424
import org.junit.jupiter.api.extension.ExtendWith;
25+
import org.mockito.Answers;
2526
import org.mockito.Mock;
2627
import org.mockito.junit.jupiter.MockitoExtension;
2728

@@ -50,7 +51,7 @@
5051
@ExtendWith(MockitoExtension.class)
5152
public class DefaultMessageSecurityExpressionHandlerTests {
5253

53-
@Mock
54+
@Mock(answer = Answers.CALLS_REAL_METHODS)
5455
AuthenticationTrustResolver trustResolver;
5556

5657
@Mock

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthenticatedPrincipalOAuth2AuthorizedClientRepository.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@ public void removeAuthorizedClient(String clientRegistrationId, Authentication p
107107
}
108108

109109
private boolean isPrincipalAuthenticated(Authentication authentication) {
110-
return authentication != null && !this.authenticationTrustResolver.isAnonymous(authentication)
111-
&& authentication.isAuthenticated();
110+
return this.authenticationTrustResolver.isAuthenticated(authentication);
112111
}
113112

114113
}

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,7 @@ public Mono<Void> removeAuthorizedClient(String clientRegistrationId, Authentica
106106
}
107107

108108
private boolean isPrincipalAuthenticated(Authentication authentication) {
109-
return authentication != null && !this.authenticationTrustResolver.isAnonymous(authentication)
110-
&& authentication.isAuthenticated();
109+
return this.authenticationTrustResolver.isAuthenticated(authentication);
111110
}
112111

113112
}

web/src/main/java/org/springframework/security/web/server/authorization/ExceptionTranslationWebFilter.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
5252
return chain.filter(exchange)
5353
.onErrorResume(AccessDeniedException.class, (denied) -> exchange.getPrincipal()
5454
.filter((principal) -> (!(principal instanceof Authentication) || (principal instanceof Authentication
55-
&& !(this.authenticationTrustResolver.isAnonymous((Authentication) principal)))))
55+
&& (this.authenticationTrustResolver.isAuthenticated((Authentication) principal)))))
5656
.switchIfEmpty(commenceAuthentication(exchange,
5757
new InsufficientAuthenticationException(
5858
"Full authentication is required to access this resource")))

web/src/main/java/org/springframework/security/web/servletapi/SecurityContextHolderAwareRequestWrapper.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public SecurityContextHolderAwareRequestWrapper(HttpServletRequest request,
9393
*/
9494
private Authentication getAuthentication() {
9595
Authentication auth = this.securityContextHolderStrategy.getContext().getAuthentication();
96-
return (!this.trustResolver.isAnonymous(auth)) ? auth : null;
96+
return (this.trustResolver.isAuthenticated(auth)) ? auth : null;
9797
}
9898

9999
/**

web/src/main/java/org/springframework/security/web/session/SessionManagementFilter.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ private void doFilter(HttpServletRequest request, HttpServletResponse response,
9494
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
9595
if (!this.securityContextRepository.containsContext(request)) {
9696
Authentication authentication = this.securityContextHolderStrategy.getContext().getAuthentication();
97-
if (authentication != null && !this.trustResolver.isAnonymous(authentication)) {
97+
if (this.trustResolver.isAuthenticated(authentication)) {
9898
// The user has been authenticated during the current request, so call the
9999
// session strategy
100100
try {

web/src/test/java/org/springframework/security/web/servletapi/SecurityContextHolderAwareRequestWrapperTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public void testGetRemoteUserStringWithAuthenticatedPrincipal() {
140140
String username = "authPrincipalUsername";
141141
AuthenticatedPrincipal principal = mock(AuthenticatedPrincipal.class);
142142
given(principal.getName()).willReturn(username);
143-
Authentication auth = new TestingAuthenticationToken(principal, "user");
143+
Authentication auth = new TestingAuthenticationToken(principal, "user", "ROLE_USER");
144144
SecurityContextHolder.getContext().setAuthentication(auth);
145145
MockHttpServletRequest request = new MockHttpServletRequest();
146146
request.setRequestURI("/");

web/src/test/java/org/springframework/security/web/session/SessionManagementFilterTests.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.junit.jupiter.api.AfterEach;
2323
import org.junit.jupiter.api.BeforeEach;
2424
import org.junit.jupiter.api.Test;
25+
import org.mockito.Answers;
2526

2627
import org.springframework.http.HttpStatus;
2728
import org.springframework.mock.web.MockFilterChain;
@@ -45,6 +46,7 @@
4546
import static org.mockito.Mockito.mock;
4647
import static org.mockito.Mockito.verify;
4748
import static org.mockito.Mockito.verifyNoMoreInteractions;
49+
import static org.mockito.Mockito.withSettings;
4850

4951
/**
5052
* @author Luke Taylor
@@ -244,7 +246,8 @@ public void responseIsRedirectedToRequestedUrlIfStatusCodeIsSetAndSessionIsInval
244246

245247
@Test
246248
public void customAuthenticationTrustResolver() throws Exception {
247-
AuthenticationTrustResolver trustResolver = mock(AuthenticationTrustResolver.class);
249+
AuthenticationTrustResolver trustResolver = mock(AuthenticationTrustResolver.class,
250+
withSettings().defaultAnswer(Answers.CALLS_REAL_METHODS));
248251
SecurityContextRepository repo = mock(SecurityContextRepository.class);
249252
SessionManagementFilter filter = new SessionManagementFilter(repo);
250253
filter.setTrustResolver(trustResolver);
@@ -262,7 +265,8 @@ public void setTrustResolverNull() {
262265
}
263266

264267
private void authenticateUser() {
265-
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("user", "pass"));
268+
SecurityContextHolder.getContext()
269+
.setAuthentication(new TestingAuthenticationToken("user", "pass", "ROLE_USER"));
266270
}
267271

268272
}

0 commit comments

Comments
 (0)