1
0
mirror of synced 2026-08-05 17:57:15 +00:00

Revert unnecessary merges on 6.0.x

This commit removes unnecessary main-branch merges starting from
8750608b5b and adds the following
needed commit(s) that were made afterward:

- 5dce82c48b
This commit is contained in:
Steve Riesenberg
2023-10-31 15:11:45 -05:00
parent e9d4223402
commit 9db33f33c7
676 changed files with 6306 additions and 43249 deletions
@@ -38,7 +38,8 @@ public class SecurityConfig implements ConfigAttribute {
@Override
public boolean equals(Object obj) {
if (obj instanceof ConfigAttribute attr) {
if (obj instanceof ConfigAttribute) {
ConfigAttribute attr = (ConfigAttribute) obj;
return this.attrib.equals(attr.getAttribute());
}
return false;
@@ -89,7 +89,8 @@ public class Jsr250MethodSecurityMetadataSource extends AbstractFallbackMethodSe
attributes.add(Jsr250SecurityConfig.PERMIT_ALL_ATTRIBUTE);
return attributes;
}
if (annotation instanceof RolesAllowed ra) {
if (annotation instanceof RolesAllowed) {
RolesAllowed ra = (RolesAllowed) annotation;
for (String allowed : ra.value()) {
String defaultedAllowed = getRoleWithDefaultPrefix(allowed);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,7 +28,6 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.util.Assert;
import org.springframework.util.function.SingletonSupplier;
/**
* Base root object for use in Spring Security expression evaluations.
@@ -87,11 +86,7 @@ public abstract class SecurityExpressionRoot implements SecurityExpressionOperat
* @since 5.8
*/
public SecurityExpressionRoot(Supplier<Authentication> authentication) {
this.authentication = SingletonSupplier.of(() -> {
Authentication value = authentication.get();
Assert.notNull(value, "Authentication object cannot be null");
return value;
});
this.authentication = new AuthenticationSupplier(authentication);
}
@Override
@@ -158,7 +153,7 @@ public abstract class SecurityExpressionRoot implements SecurityExpressionOperat
@Override
public final boolean isFullyAuthenticated() {
Authentication authentication = getAuthentication();
return this.trustResolver.isFullyAuthenticated(authentication);
return !this.trustResolver.isAnonymous(authentication) && !this.trustResolver.isRememberMe(authentication);
}
/**
@@ -241,4 +236,27 @@ public abstract class SecurityExpressionRoot implements SecurityExpressionOperat
return defaultRolePrefix + role;
}
private static final class AuthenticationSupplier implements Supplier<Authentication> {
private Authentication value;
private final Supplier<Authentication> delegate;
private AuthenticationSupplier(Supplier<Authentication> delegate) {
Assert.notNull(delegate, "delegate cannot be null");
this.delegate = delegate;
}
@Override
public Authentication get() {
if (this.value == null) {
Authentication authentication = this.delegate.get();
Assert.notNull(authentication, "Authentication object cannot be null");
this.value = authentication;
}
return this.value;
}
}
}
@@ -43,7 +43,8 @@ public abstract class AbstractMethodSecurityMetadataSource implements MethodSecu
@Override
public final Collection<ConfigAttribute> getAttributes(Object object) {
if (object instanceof MethodInvocation mi) {
if (object instanceof MethodInvocation) {
MethodInvocation mi = (MethodInvocation) object;
Object target = mi.getThis();
Class<?> targetClass = null;
if (target != null) {
@@ -264,7 +264,8 @@ public class MapBasedMethodSecurityMetadataSource extends AbstractFallbackMethod
if (this == obj) {
return true;
}
if (obj instanceof RegisteredMethod rhs) {
if (obj != null && obj instanceof RegisteredMethod) {
RegisteredMethod rhs = (RegisteredMethod) obj;
return this.method.equals(rhs.method) && this.registeredJavaType.equals(rhs.registeredJavaType);
}
return false;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,8 @@ package org.springframework.security.access.prepost;
import java.lang.reflect.Method;
import java.util.Collection;
import kotlin.coroutines.Continuation;
import kotlinx.coroutines.reactive.AwaitKt;
import kotlinx.coroutines.reactive.ReactiveFlowKt;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
@@ -27,6 +29,7 @@ import reactor.core.Exceptions;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.core.CoroutinesUtils;
import org.springframework.core.KotlinDetector;
import org.springframework.core.MethodParameter;
import org.springframework.core.ReactiveAdapter;
@@ -123,23 +126,34 @@ public class PrePostAdviceReactiveMethodInterceptor implements MethodInterceptor
.map((r) -> (attr != null) ? this.postAdvice.after(auth, invocation, attr, r) : r));
}
if (hasFlowReturnType) {
Flux<?> response;
if (isSuspendingFunction) {
return toInvoke
.flatMapMany((auth) -> Flux.from(PrePostAdviceReactiveMethodInterceptor.proceed(invocation))
.map((r) -> (attr != null) ? this.postAdvice.after(auth, invocation, attr, r) : r));
response = toInvoke.flatMapMany((auth) -> Flux
.from(CoroutinesUtils.invokeSuspendingFunction(invocation.getMethod(), invocation.getThis(),
invocation.getArguments()))
.map((r) -> (attr != null) ? this.postAdvice.after(auth, invocation, attr, r) : r));
}
else {
ReactiveAdapter adapter = ReactiveAdapterRegistry.getSharedInstance().getAdapter(returnType);
Assert.state(adapter != null, () -> "The returnType " + returnType + " on " + method
+ " must have a org.springframework.core.ReactiveAdapter registered");
Flux<?> response = toInvoke.flatMapMany((auth) -> Flux
response = toInvoke.flatMapMany((auth) -> Flux
.from(adapter.toPublisher(PrePostAdviceReactiveMethodInterceptor.flowProceed(invocation)))
.map((r) -> (attr != null) ? this.postAdvice.after(auth, invocation, attr, r) : r));
return KotlinDelegate.asFlow(response);
}
return KotlinDelegate.asFlow(response);
}
return toInvoke.flatMap((auth) -> Mono.from(PrePostAdviceReactiveMethodInterceptor.proceed(invocation))
.map((r) -> (attr != null) ? this.postAdvice.after(auth, invocation, attr, r) : r));
if (isSuspendingFunction) {
Mono<?> response = toInvoke.flatMap((auth) -> Mono
.from(CoroutinesUtils.invokeSuspendingFunction(invocation.getMethod(), invocation.getThis(),
invocation.getArguments()))
.map((r) -> (attr != null) ? this.postAdvice.after(auth, invocation, attr, r) : r));
return KotlinDelegate.awaitSingleOrNull(response,
invocation.getArguments()[invocation.getArguments().length - 1]);
}
return toInvoke
.flatMapMany((auth) -> Flux.from(PrePostAdviceReactiveMethodInterceptor.<Publisher<?>>proceed(invocation))
.map((r) -> (attr != null) ? this.postAdvice.after(auth, invocation, attr, r) : r));
}
private static <T extends Publisher<?>> T proceed(final MethodInvocation invocation) {
@@ -187,6 +201,10 @@ public class PrePostAdviceReactiveMethodInterceptor implements MethodInterceptor
return ReactiveFlowKt.asFlow(publisher);
}
private static Object awaitSingleOrNull(Publisher<?> publisher, Object continuation) {
return AwaitKt.awaitSingleOrNull(publisher, (Continuation<Object>) continuation);
}
}
}
@@ -71,10 +71,14 @@ public class ConsensusBased extends AbstractAccessDecisionManager {
for (AccessDecisionVoter voter : getDecisionVoters()) {
int result = voter.vote(authentication, object, configAttributes);
switch (result) {
case AccessDecisionVoter.ACCESS_GRANTED -> grant++;
case AccessDecisionVoter.ACCESS_DENIED -> deny++;
default -> {
}
case AccessDecisionVoter.ACCESS_GRANTED:
grant++;
break;
case AccessDecisionVoter.ACCESS_DENIED:
deny++;
break;
default:
break;
}
}
if (grant > deny) {
@@ -68,14 +68,14 @@ public abstract class AbstractAuthenticationToken implements Authentication, Cre
@Override
public String getName() {
if (this.getPrincipal() instanceof UserDetails userDetails) {
return userDetails.getUsername();
if (this.getPrincipal() instanceof UserDetails) {
return ((UserDetails) this.getPrincipal()).getUsername();
}
if (this.getPrincipal() instanceof AuthenticatedPrincipal authenticatedPrincipal) {
return authenticatedPrincipal.getName();
if (this.getPrincipal() instanceof AuthenticatedPrincipal) {
return ((AuthenticatedPrincipal) this.getPrincipal()).getName();
}
if (this.getPrincipal() instanceof Principal principal) {
return principal.getName();
if (this.getPrincipal() instanceof Principal) {
return ((Principal) this.getPrincipal()).getName();
}
return (this.getPrincipal() == null) ? "" : this.getPrincipal().toString();
}
@@ -119,9 +119,10 @@ public abstract class AbstractAuthenticationToken implements Authentication, Cre
@Override
public boolean equals(Object obj) {
if (!(obj instanceof AbstractAuthenticationToken test)) {
if (!(obj instanceof AbstractAuthenticationToken)) {
return false;
}
AbstractAuthenticationToken test = (AbstractAuthenticationToken) obj;
if (!this.authorities.equals(test.authorities)) {
return false;
}
@@ -74,7 +74,8 @@ public class AnonymousAuthenticationToken extends AbstractAuthenticationToken im
if (!super.equals(obj)) {
return false;
}
if (obj instanceof AnonymousAuthenticationToken test) {
if (obj instanceof AnonymousAuthenticationToken) {
AnonymousAuthenticationToken test = (AnonymousAuthenticationToken) obj;
return (this.getKeyHash() == test.getKeyHash());
}
return false;
@@ -53,21 +53,4 @@ public interface AuthenticationTrustResolver {
*/
boolean isRememberMe(Authentication authentication);
/**
* Indicates whether the passed <code>Authentication</code> token represents a fully
* authenticated user (that is, neither anonymous or remember-me). This is a
* composition of <code>isAnonymous</code> and <code>isRememberMe</code>
* implementation
* <p>
* @param authentication to test (may be <code>null</code> in which case the method
* will always return <code>false</code>)
* @return <code>true</code> the passed authentication token represented an anonymous
* principal and is authenticated using a remember-me token, <code>false</code>
* otherwise
* @since 6.1
*/
default boolean isFullyAuthenticated(Authentication authentication) {
return !isAnonymous(authentication) && !isRememberMe(authentication);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
package org.springframework.security.authentication;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationConvention;
import io.micrometer.observation.ObservationRegistry;
import org.springframework.security.core.Authentication;
@@ -36,7 +35,7 @@ public final class ObservationAuthenticationManager implements AuthenticationMan
private final AuthenticationManager delegate;
private ObservationConvention<AuthenticationObservationContext> convention = new AuthenticationObservationConvention();
private final AuthenticationObservationConvention convention = new AuthenticationObservationConvention();
public ObservationAuthenticationManager(ObservationRegistry registry, AuthenticationManager delegate) {
Assert.notNull(registry, "observationRegistry cannot be null");
@@ -57,15 +56,4 @@ public final class ObservationAuthenticationManager implements AuthenticationMan
});
}
/**
* Use the provided convention for reporting observation data
* @param convention The provided convention
*
* @since 6.1
*/
public void setObservationConvention(ObservationConvention<AuthenticationObservationContext> convention) {
Assert.notNull(convention, "The observation convention cannot be null");
this.convention = convention;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,14 +17,12 @@
package org.springframework.security.authentication;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationConvention;
import io.micrometer.observation.ObservationRegistry;
import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor;
import reactor.core.publisher.Mono;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.util.Assert;
/**
* An {@link ReactiveAuthenticationManager} that observes the authentication
@@ -38,7 +36,7 @@ public class ObservationReactiveAuthenticationManager implements ReactiveAuthent
private final ReactiveAuthenticationManager delegate;
private ObservationConvention<AuthenticationObservationContext> convention = new AuthenticationObservationConvention();
private final AuthenticationObservationConvention convention = new AuthenticationObservationConvention();
public ObservationReactiveAuthenticationManager(ObservationRegistry registry,
ReactiveAuthenticationManager delegate) {
@@ -65,15 +63,4 @@ public class ObservationReactiveAuthenticationManager implements ReactiveAuthent
});
}
/**
* Use the provided convention for reporting observation data
* @param convention The provided convention
*
* @since 6.1
*/
public void setObservationConvention(ObservationConvention<AuthenticationObservationContext> convention) {
Assert.notNull(convention, "The observation convention cannot be null");
this.convention = convention;
}
}
@@ -256,7 +256,8 @@ public class ProviderManager implements AuthenticationManager, MessageSourceAwar
* @param dest the destination authentication object
*/
private void copyDetails(Authentication source, Authentication dest) {
if ((dest instanceof AbstractAuthenticationToken token) && (dest.getDetails() == null)) {
if ((dest instanceof AbstractAuthenticationToken) && (dest.getDetails() == null)) {
AbstractAuthenticationToken token = (AbstractAuthenticationToken) dest;
token.setDetails(source.getDetails());
}
}
@@ -94,8 +94,12 @@ public class RememberMeAuthenticationToken extends AbstractAuthenticationToken {
if (!super.equals(obj)) {
return false;
}
if (obj instanceof RememberMeAuthenticationToken other) {
return this.getKeyHash() == other.getKeyHash();
if (obj instanceof RememberMeAuthenticationToken) {
RememberMeAuthenticationToken other = (RememberMeAuthenticationToken) obj;
if (this.getKeyHash() != other.getKeyHash()) {
return false;
}
return true;
}
return false;
}
@@ -16,7 +16,6 @@
package org.springframework.security.authentication;
import java.util.Collection;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
@@ -48,13 +47,7 @@ public class TestingAuthenticationToken extends AbstractAuthenticationToken {
this(principal, credentials, AuthorityUtils.createAuthorityList(authorities));
}
public TestingAuthenticationToken(Object principal, Object credentials,
List<? extends GrantedAuthority> authorities) {
this(principal, credentials, (Collection<? extends GrantedAuthority>) authorities);
}
public TestingAuthenticationToken(Object principal, Object credentials,
Collection<? extends GrantedAuthority> authorities) {
public TestingAuthenticationToken(Object principal, Object credentials, List<GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
@@ -160,9 +160,10 @@ public abstract class AbstractJaasAuthenticationProvider implements Authenticati
*/
@Override
public Authentication authenticate(Authentication auth) throws AuthenticationException {
if (!(auth instanceof UsernamePasswordAuthenticationToken request)) {
if (!(auth instanceof UsernamePasswordAuthenticationToken)) {
return null;
}
UsernamePasswordAuthenticationToken request = (UsernamePasswordAuthenticationToken) auth;
Set<GrantedAuthority> authorities;
try {
// Create the LoginContext object, and pass our InternallCallbackHandler
@@ -232,7 +233,8 @@ public abstract class AbstractJaasAuthenticationProvider implements Authenticati
}
for (SecurityContext context : contexts) {
Authentication auth = context.getAuthentication();
if ((auth instanceof JaasAuthenticationToken token)) {
if ((auth != null) && (auth instanceof JaasAuthenticationToken)) {
JaasAuthenticationToken token = (JaasAuthenticationToken) auth;
try {
LoginContext loginContext = token.getLoginContext();
logout(token, loginContext);
@@ -58,8 +58,9 @@ public final class JaasGrantedAuthority implements GrantedAuthority {
if (this == obj) {
return true;
}
if (obj instanceof JaasGrantedAuthority jga) {
return this.role.equals(jga.getAuthority()) && this.principal.equals(jga.getPrincipal());
if (obj instanceof JaasGrantedAuthority) {
JaasGrantedAuthority jga = (JaasGrantedAuthority) obj;
return this.role.equals(jga.role) && this.principal.equals(jga.principal);
}
return false;
}
@@ -71,6 +71,7 @@ public class SecurityContextLoginModule implements LoginModule {
* <code>Authentication</code>.
* @return true if this method succeeded, or false if this <code>LoginModule</code>
* should be ignored.
* @exception LoginException if the abort fails
*/
@Override
public boolean abort() {
@@ -86,6 +87,7 @@ public class SecurityContextLoginModule implements LoginModule {
* <code>Authentication</code> to the <code>Subject</code>'s principals.
* @return true if this method succeeded, or false if this <code>LoginModule</code>
* should be ignored.
* @exception LoginException if the commit fails
*/
@Override
public boolean commit() {
@@ -159,6 +161,7 @@ public class SecurityContextLoginModule implements LoginModule {
* Log out the <code>Subject</code>.
* @return true if this method succeeded, or false if this <code>LoginModule</code>
* should be ignored.
* @exception LoginException if the logout fails
*/
@Override
public boolean logout() {
@@ -143,7 +143,7 @@ public final class AuthenticatedAuthorizationManager<T> implements Authorization
@Override
boolean isGranted(Authentication authentication) {
return authentication != null && this.trustResolver.isFullyAuthenticated(authentication);
return super.isGranted(authentication) && !this.trustResolver.isRememberMe(authentication);
}
}
@@ -1,81 +0,0 @@
/*
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.authorization;
import java.util.Collection;
import java.util.function.Supplier;
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.util.Assert;
/**
* An {@link AuthorizationManager} that determines if the current user is authorized by
* evaluating if the {@link Authentication} contains any of the specified authorities.
*
* @author Evgeniy Cheban
* @since 6.1
*/
public final class AuthoritiesAuthorizationManager implements AuthorizationManager<Collection<String>> {
private RoleHierarchy roleHierarchy = new NullRoleHierarchy();
/**
* Sets the {@link RoleHierarchy} to be used. Default is {@link NullRoleHierarchy}.
* Cannot be null.
* @param roleHierarchy the {@link RoleHierarchy} to use
*/
public void setRoleHierarchy(RoleHierarchy roleHierarchy) {
Assert.notNull(roleHierarchy, "roleHierarchy cannot be null");
this.roleHierarchy = roleHierarchy;
}
/**
* Determines if the current user is authorized by evaluating if the
* {@link Authentication} contains any of specified authorities.
* @param authentication the {@link Supplier} of the {@link Authentication} to check
* @param authorities the collection of authority strings to check
* @return an {@link AuthorityAuthorizationDecision}
*/
@Override
public AuthorityAuthorizationDecision check(Supplier<Authentication> authentication,
Collection<String> authorities) {
boolean granted = isGranted(authentication.get(), authorities);
return new AuthorityAuthorizationDecision(granted, AuthorityUtils.createAuthorityList(authorities));
}
private boolean isGranted(Authentication authentication, Collection<String> authorities) {
return authentication != null && isAuthorized(authentication, authorities);
}
private boolean isAuthorized(Authentication authentication, Collection<String> authorities) {
for (GrantedAuthority grantedAuthority : getGrantedAuthorities(authentication)) {
if (authorities.contains(grantedAuthority.getAuthority())) {
return true;
}
}
return false;
}
private Collection<? extends GrantedAuthority> getGrantedAuthorities(Authentication authentication) {
return this.roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities());
}
}
@@ -16,12 +16,16 @@
package org.springframework.security.authorization;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.util.Assert;
/**
@@ -36,12 +40,12 @@ public final class AuthorityAuthorizationManager<T> implements AuthorizationMana
private static final String ROLE_PREFIX = "ROLE_";
private final AuthoritiesAuthorizationManager delegate = new AuthoritiesAuthorizationManager();
private final List<GrantedAuthority> authorities;
private final Set<String> authorities;
private RoleHierarchy roleHierarchy = new NullRoleHierarchy();
private AuthorityAuthorizationManager(String... authorities) {
this.authorities = Set.of(authorities);
this.authorities = AuthorityUtils.createAuthorityList(authorities);
}
/**
@@ -51,7 +55,8 @@ public final class AuthorityAuthorizationManager<T> implements AuthorizationMana
* @since 5.8
*/
public void setRoleHierarchy(RoleHierarchy roleHierarchy) {
this.delegate.setRoleHierarchy(roleHierarchy);
Assert.notNull(roleHierarchy, "roleHierarchy cannot be null");
this.roleHierarchy = roleHierarchy;
}
/**
@@ -142,7 +147,26 @@ public final class AuthorityAuthorizationManager<T> implements AuthorizationMana
*/
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, T object) {
return this.delegate.check(authentication, this.authorities);
boolean granted = isGranted(authentication.get());
return new AuthorityAuthorizationDecision(granted, this.authorities);
}
private boolean isGranted(Authentication authentication) {
return authentication != null && authentication.isAuthenticated() && isAuthorized(authentication);
}
private boolean isAuthorized(Authentication authentication) {
Set<String> authorities = AuthorityUtils.authorityListToSet(this.authorities);
for (GrantedAuthority grantedAuthority : getGrantedAuthorities(authentication)) {
if (authorities.contains(grantedAuthority.getAuthority())) {
return true;
}
}
return false;
}
private Collection<? extends GrantedAuthority> getGrantedAuthorities(Authentication authentication) {
return this.roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities());
}
@Override
@@ -26,7 +26,7 @@ import org.springframework.security.core.Authentication;
* An Authorization manager which can determine if an {@link Authentication} has access to
* a specific object.
*
* @param <T> the type of object that the authorization check is being done on.
* @param <T> the type of object that the authorization check is being done one.
* @author Evgeniy Cheban
*/
@FunctionalInterface
@@ -95,9 +95,6 @@ public final class AuthorizationObservationConvention
if (className.contains("Message")) {
return "message";
}
if (className.contains("Exchange")) {
return "exchange";
}
return className;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,16 +19,10 @@ package org.springframework.security.authorization;
import java.util.function.Supplier;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationConvention;
import io.micrometer.observation.ObservationRegistry;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.util.Assert;
/**
* An {@link AuthorizationManager} that observes the authorization
@@ -36,15 +30,13 @@ import org.springframework.util.Assert;
* @author Josh Cummings
* @since 6.0
*/
public final class ObservationAuthorizationManager<T> implements AuthorizationManager<T>, MessageSourceAware {
public final class ObservationAuthorizationManager<T> implements AuthorizationManager<T> {
private final ObservationRegistry registry;
private final AuthorizationManager<T> delegate;
private ObservationConvention<AuthorizationObservationContext<?>> convention = new AuthorizationObservationConvention();
private MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
private final AuthorizationObservationConvention convention = new AuthorizationObservationConvention();
public ObservationAuthorizationManager(ObservationRegistry registry, AuthorizationManager<T> delegate) {
this.registry = registry;
@@ -63,8 +55,7 @@ public final class ObservationAuthorizationManager<T> implements AuthorizationMa
AuthorizationDecision decision = this.delegate.check(wrapped, object);
context.setDecision(decision);
if (decision != null && !decision.isGranted()) {
observation.error(new AccessDeniedException(
this.messages.getMessage("AbstractAccessDecisionManager.accessDenied", "Access Denied")));
observation.error(new AccessDeniedException("Access Denied"));
}
return decision;
}
@@ -77,25 +68,4 @@ public final class ObservationAuthorizationManager<T> implements AuthorizationMa
}
}
/**
* Use the provided convention for reporting observation data
* @param convention The provided convention
*
* @since 6.1
*/
public void setObservationConvention(ObservationConvention<AuthorizationObservationContext<?>> convention) {
Assert.notNull(convention, "The observation convention cannot be null");
this.convention = convention;
}
/**
* Set the MessageSource that this object runs in.
* @param messageSource The message source to be used by this object
* @since 6.2
*/
@Override
public void setMessageSource(final MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,14 +17,12 @@
package org.springframework.security.authorization;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationConvention;
import io.micrometer.observation.ObservationRegistry;
import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor;
import reactor.core.publisher.Mono;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.util.Assert;
/**
* An {@link ReactiveAuthorizationManager} that observes the authentication
@@ -38,7 +36,7 @@ public final class ObservationReactiveAuthorizationManager<T> implements Reactiv
private final ReactiveAuthorizationManager<T> delegate;
private ObservationConvention<AuthorizationObservationContext<?>> convention = new AuthorizationObservationConvention();
private final AuthorizationObservationConvention convention = new AuthorizationObservationConvention();
public ObservationReactiveAuthorizationManager(ObservationRegistry registry,
ReactiveAuthorizationManager<T> delegate) {
@@ -70,15 +68,4 @@ public final class ObservationReactiveAuthorizationManager<T> implements Reactiv
});
}
/**
* Use the provided convention for reporting observation data
* @param convention The provided convention
*
* @since 6.1
*/
public void setObservationConvention(ObservationConvention<AuthorizationObservationContext<?>> convention) {
Assert.notNull(convention, "The observation convention cannot be null");
this.convention = convention;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package org.springframework.security.authorization.method;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Supplier;
@@ -31,7 +30,7 @@ import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.AopUtils;
import org.springframework.core.annotation.AnnotationConfigurationException;
import org.springframework.lang.NonNull;
import org.springframework.security.authorization.AuthoritiesAuthorizationManager;
import org.springframework.security.authorization.AuthorityAuthorizationManager;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
@@ -58,23 +57,8 @@ public final class Jsr250AuthorizationManager implements AuthorizationManager<Me
private final Jsr250AuthorizationManagerRegistry registry = new Jsr250AuthorizationManagerRegistry();
private AuthorizationManager<Collection<String>> authoritiesAuthorizationManager = new AuthoritiesAuthorizationManager();
private String rolePrefix = "ROLE_";
/**
* Sets an {@link AuthorizationManager} that accepts a collection of authority
* strings.
* @param authoritiesAuthorizationManager the {@link AuthorizationManager} that
* accepts a collection of authority strings to use
* @since 6.2
*/
public void setAuthoritiesAuthorizationManager(
AuthorizationManager<Collection<String>> authoritiesAuthorizationManager) {
Assert.notNull(authoritiesAuthorizationManager, "authoritiesAuthorizationManager cannot be null");
this.authoritiesAuthorizationManager = authoritiesAuthorizationManager;
}
/**
* Sets the role prefix. Defaults to "ROLE_".
* @param rolePrefix the role prefix to use
@@ -111,9 +95,10 @@ public final class Jsr250AuthorizationManager implements AuthorizationManager<Me
if (annotation instanceof PermitAll) {
return (a, o) -> new AuthorizationDecision(true);
}
if (annotation instanceof RolesAllowed rolesAllowed) {
return (a, o) -> Jsr250AuthorizationManager.this.authoritiesAuthorizationManager.check(a,
getAllowedRolesWithPrefix(rolesAllowed));
if (annotation instanceof RolesAllowed) {
RolesAllowed rolesAllowed = (RolesAllowed) annotation;
return AuthorityAuthorizationManager.hasAnyRole(Jsr250AuthorizationManager.this.rolePrefix,
rolesAllowed.value());
}
return NULL_MANAGER;
}
@@ -160,14 +145,6 @@ public final class Jsr250AuthorizationManager implements AuthorizationManager<Me
return annotations.iterator().next();
}
private Set<String> getAllowedRolesWithPrefix(RolesAllowed rolesAllowed) {
Set<String> roles = new HashSet<>();
for (int i = 0; i < rolesAllowed.value().length; i++) {
roles.add(Jsr250AuthorizationManager.this.rolePrefix + rolesAllowed.value()[i]);
}
return roles;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,23 +17,17 @@
package org.springframework.security.authorization.method;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.AopUtils;
import org.springframework.core.MethodClassKey;
import org.springframework.lang.NonNull;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.authorization.AuthoritiesAuthorizationManager;
import org.springframework.security.authorization.AuthorityAuthorizationManager;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.util.Assert;
/**
* An {@link AuthorizationManager} which can determine if an {@link Authentication} may
@@ -45,22 +39,7 @@ import org.springframework.util.Assert;
*/
public final class SecuredAuthorizationManager implements AuthorizationManager<MethodInvocation> {
private AuthorizationManager<Collection<String>> authoritiesAuthorizationManager = new AuthoritiesAuthorizationManager();
private final Map<MethodClassKey, Set<String>> cachedAuthorities = new ConcurrentHashMap<>();
/**
* Sets an {@link AuthorizationManager} that accepts a collection of authority
* strings.
* @param authoritiesAuthorizationManager the {@link AuthorizationManager} that
* accepts a collection of authority strings to use
* @since 6.1
*/
public void setAuthoritiesAuthorizationManager(
AuthorizationManager<Collection<String>> authoritiesAuthorizationManager) {
Assert.notNull(authoritiesAuthorizationManager, "authoritiesAuthorizationManager cannot be null");
this.authoritiesAuthorizationManager = authoritiesAuthorizationManager;
}
private final SecuredAuthorizationManagerRegistry registry = new SecuredAuthorizationManagerRegistry();
/**
* Determine if an {@link Authentication} has access to a method by evaluating the
@@ -72,28 +51,26 @@ public final class SecuredAuthorizationManager implements AuthorizationManager<M
*/
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, MethodInvocation mi) {
Set<String> authorities = getAuthorities(mi);
return authorities.isEmpty() ? null : this.authoritiesAuthorizationManager.check(authentication, authorities);
AuthorizationManager<MethodInvocation> delegate = this.registry.getManager(mi);
return delegate.check(authentication, mi);
}
private Set<String> getAuthorities(MethodInvocation methodInvocation) {
Method method = methodInvocation.getMethod();
Object target = methodInvocation.getThis();
Class<?> targetClass = (target != null) ? target.getClass() : null;
MethodClassKey cacheKey = new MethodClassKey(method, targetClass);
return this.cachedAuthorities.computeIfAbsent(cacheKey, (k) -> resolveAuthorities(method, targetClass));
}
private static final class SecuredAuthorizationManagerRegistry extends AbstractAuthorizationManagerRegistry {
private Set<String> resolveAuthorities(Method method, Class<?> targetClass) {
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
Secured secured = findSecuredAnnotation(specificMethod);
return (secured != null) ? Set.of(secured.value()) : Collections.emptySet();
}
@NonNull
@Override
AuthorizationManager<MethodInvocation> resolveManager(Method method, Class<?> targetClass) {
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
Secured secured = findSecuredAnnotation(specificMethod);
return (secured != null) ? AuthorityAuthorizationManager.hasAnyAuthority(secured.value()) : NULL_MANAGER;
}
private Secured findSecuredAnnotation(Method method) {
Secured secured = AuthorizationAnnotationUtils.findUniqueAnnotation(method, Secured.class);
return (secured != null) ? secured
: AuthorizationAnnotationUtils.findUniqueAnnotation(method.getDeclaringClass(), Secured.class);
}
private Secured findSecuredAnnotation(Method method) {
Secured secured = AuthorizationAnnotationUtils.findUniqueAnnotation(method, Secured.class);
return (secured != null) ? secured
: AuthorizationAnnotationUtils.findUniqueAnnotation(method.getDeclaringClass(), Secured.class);
}
}
@@ -130,13 +130,23 @@ class ComparableVersion implements Comparable<ComparableVersion> {
return (value == 0) ? 0 : 1; // 1.0 == 1, 1.1 > 1
}
return switch (item.getType()) {
case INT_ITEM -> Integer.compare(value, ((IntItem) item).value);
case LONG_ITEM, BIGINTEGER_ITEM -> -1;
case STRING_ITEM -> 1; // 1.1 > 1-sp
case LIST_ITEM -> 1; // 1.1 > 1-1
default -> throw new IllegalStateException("invalid item: " + item.getClass());
};
switch (item.getType()) {
case INT_ITEM:
int itemValue = ((IntItem) item).value;
return (value < itemValue) ? -1 : ((value == itemValue) ? 0 : 1);
case LONG_ITEM:
case BIGINTEGER_ITEM:
return -1;
case STRING_ITEM:
return 1; // 1.1 > 1-sp
case LIST_ITEM:
return 1; // 1.1 > 1-1
default:
throw new IllegalStateException("invalid item: " + item.getClass());
}
}
@Override
@@ -194,14 +204,24 @@ class ComparableVersion implements Comparable<ComparableVersion> {
return (value == 0) ? 0 : 1; // 1.0 == 1, 1.1 > 1
}
return switch (item.getType()) {
case INT_ITEM -> 1;
case LONG_ITEM -> Long.compare(value, ((LongItem) item).value);
case BIGINTEGER_ITEM -> -1;
case STRING_ITEM -> 1; // 1.1 > 1-sp
case LIST_ITEM -> 1; // 1.1 > 1-1
default -> throw new IllegalStateException("invalid item: " + item.getClass());
};
switch (item.getType()) {
case INT_ITEM:
return 1;
case LONG_ITEM:
long itemValue = ((LongItem) item).value;
return (value < itemValue) ? -1 : ((value == itemValue) ? 0 : 1);
case BIGINTEGER_ITEM:
return -1;
case STRING_ITEM:
return 1; // 1.1 > 1-sp
case LIST_ITEM:
return 1; // 1.1 > 1-1
default:
throw new IllegalStateException("invalid item: " + item.getClass());
}
}
@Override
@@ -258,13 +278,23 @@ class ComparableVersion implements Comparable<ComparableVersion> {
return BigInteger.ZERO.equals(value) ? 0 : 1; // 1.0 == 1, 1.1 > 1
}
return switch (item.getType()) {
case INT_ITEM, LONG_ITEM -> 1;
case BIGINTEGER_ITEM -> value.compareTo(((BigIntegerItem) item).value);
case STRING_ITEM -> 1; // 1.1 > 1-sp
case LIST_ITEM -> 1; // 1.1 > 1-1
default -> throw new IllegalStateException("invalid item: " + item.getClass());
};
switch (item.getType()) {
case INT_ITEM:
case LONG_ITEM:
return 1;
case BIGINTEGER_ITEM:
return value.compareTo(((BigIntegerItem) item).value);
case STRING_ITEM:
return 1; // 1.1 > 1-sp
case LIST_ITEM:
return 1; // 1.1 > 1-1
default:
throw new IllegalStateException("invalid item: " + item.getClass());
}
}
@Override
@@ -321,12 +351,18 @@ class ComparableVersion implements Comparable<ComparableVersion> {
StringItem(String value, boolean followedByDigit) {
if (followedByDigit && value.length() == 1) {
// a1 = alpha-1, b1 = beta-1, m1 = milestone-1
value = switch (value.charAt(0)) {
case 'a' -> "alpha";
case 'b' -> "beta";
case 'm' -> "milestone";
default -> value;
};
switch (value.charAt(0)) {
case 'a':
value = "alpha";
break;
case 'b':
value = "beta";
break;
case 'm':
value = "milestone";
break;
default:
}
}
this.value = ALIASES.getProperty(value, value);
}
@@ -366,13 +402,21 @@ class ComparableVersion implements Comparable<ComparableVersion> {
// 1-rc < 1, 1-ga > 1
return comparableQualifier(value).compareTo(RELEASE_VERSION_INDEX);
}
return switch (item.getType()) {
case INT_ITEM, LONG_ITEM, BIGINTEGER_ITEM -> -1; // 1.any < 1.1 ?
case STRING_ITEM ->
comparableQualifier(value).compareTo(comparableQualifier(((StringItem) item).value));
case LIST_ITEM -> -1; // 1.any < 1-1
default -> throw new IllegalStateException("invalid item: " + item.getClass());
};
switch (item.getType()) {
case INT_ITEM:
case LONG_ITEM:
case BIGINTEGER_ITEM:
return -1; // 1.any < 1.1 ?
case STRING_ITEM:
return comparableQualifier(value).compareTo(comparableQualifier(((StringItem) item).value));
case LIST_ITEM:
return -1; // 1.any < 1-1
default:
throw new IllegalStateException("invalid item: " + item.getClass());
}
}
@Override
@@ -440,12 +484,19 @@ class ComparableVersion implements Comparable<ComparableVersion> {
Item first = get(0);
return first.compareTo(null);
}
return switch (item.getType()) {
case INT_ITEM, LONG_ITEM, BIGINTEGER_ITEM -> -1; // 1-1 < 1.0.x
case STRING_ITEM -> 1; // 1-1 > 1-sp
case LIST_ITEM -> {
switch (item.getType()) {
case INT_ITEM:
case LONG_ITEM:
case BIGINTEGER_ITEM:
return -1; // 1-1 < 1.0.x
case STRING_ITEM:
return 1; // 1-1 > 1-sp
case LIST_ITEM:
Iterator<Item> left = iterator();
Iterator<Item> right = ((ListItem) item).iterator();
while (left.hasNext() || right.hasNext()) {
Item l = left.hasNext() ? left.next() : null;
Item r = right.hasNext() ? right.next() : null;
@@ -454,13 +505,15 @@ class ComparableVersion implements Comparable<ComparableVersion> {
int result = l == null ? (r == null ? 0 : -1 * r.compareTo(l)) : l.compareTo(r);
if (result != 0) {
yield result;
return result;
}
}
yield 0;
}
default -> throw new IllegalStateException("invalid item: " + item.getClass());
};
return 0;
default:
throw new IllegalStateException("invalid item: " + item.getClass());
}
}
@Override
@@ -43,7 +43,7 @@ public final class SpringSecurityCoreVersion {
* N.B. Classes are not intended to be serializable between different versions. See
* SEC-1709 for why we still need a serial version.
*/
public static final long SERIAL_VERSION_UID = 620L;
public static final long SERIAL_VERSION_UID = 600L;
static final String MIN_SPRING_VERSION = getSpringVersion();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,7 +33,6 @@ import org.springframework.util.StringUtils;
* Mainly intended for internal use.
*
* @author Luke Taylor
* @author Evgeniy Cheban
*/
public final class AuthorityUtils {
@@ -79,18 +78,4 @@ public final class AuthorityUtils {
return grantedAuthorities;
}
/**
* Converts authorities into a List of GrantedAuthority objects.
* @param authorities the authorities to convert
* @return a List of GrantedAuthority objects
* @since 6.1
*/
public static List<GrantedAuthority> createAuthorityList(Collection<String> authorities) {
List<GrantedAuthority> grantedAuthorities = new ArrayList<>(authorities.size());
for (String authority : authorities) {
grantedAuthorities.add(new SimpleGrantedAuthority(authority));
}
return grantedAuthorities;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,8 +50,8 @@ public final class SimpleGrantedAuthority implements GrantedAuthority {
if (this == obj) {
return true;
}
if (obj instanceof SimpleGrantedAuthority sga) {
return this.role.equals(sga.getAuthority());
if (obj instanceof SimpleGrantedAuthority) {
return this.role.equals(((SimpleGrantedAuthority) obj).role);
}
return false;
}
@@ -117,6 +117,7 @@ public class MapBasedAttributes2GrantedAuthoritiesMapper
* Convert the given value to a collection of Granted Authorities, adding the result
* to the given result collection.
* @param value The value to convert to a GrantedAuthority Collection
* @return Collection containing the GrantedAuthority Collection
*/
private void addGrantedAuthorityCollection(Collection<GrantedAuthority> result, Object value) {
if (value == null) {
@@ -48,7 +48,7 @@ public interface SecurityContextHolderStrategy {
* @since 5.8
*/
default Supplier<SecurityContext> getDeferredContext() {
return this::getContext;
return () -> getContext();
}
/**
@@ -42,7 +42,8 @@ public class SecurityContextImpl implements SecurityContext {
@Override
public boolean equals(Object obj) {
if (obj instanceof SecurityContextImpl other) {
if (obj instanceof SecurityContextImpl) {
SecurityContextImpl other = (SecurityContextImpl) obj;
if ((this.getAuthentication() == null) && (other.getAuthentication() == null)) {
return true;
}
@@ -180,6 +180,7 @@ public class AnnotationParameterNameDiscoverer implements ParameterNameDiscovere
/**
* Gets the {@link Annotation}s at a specified index
* @param t
* @param index
* @return
*/
Annotation[][] findParameterAnnotations(T t);
@@ -22,6 +22,7 @@ import java.util.List;
import java.util.Set;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.PrioritizedParameterNameDiscoverer;
import org.springframework.util.Assert;
@@ -35,6 +36,11 @@ import org.springframework.util.ClassUtils;
* <li>Will use an instance of {@link AnnotationParameterNameDiscoverer} with {@link P} as
* a valid annotation. If, Spring Data is on the classpath will also add Param annotation.
* </li>
* <li>If Spring 4 is on the classpath, then DefaultParameterNameDiscoverer is added. This
* attempts to use JDK 8 information first and falls back to
* {@link LocalVariableTableParameterNameDiscoverer}.</li>
* <li>If Spring 4 is not on the classpath, then
* {@link LocalVariableTableParameterNameDiscoverer} is added directly.</li>
* </ul>
*
* @author Rob Winch
@@ -100,11 +100,13 @@ public class SessionRegistryImpl implements SessionRegistry, ApplicationListener
@Override
public void onApplicationEvent(AbstractSessionEvent event) {
if (event instanceof SessionDestroyedEvent sessionDestroyedEvent) {
if (event instanceof SessionDestroyedEvent) {
SessionDestroyedEvent sessionDestroyedEvent = (SessionDestroyedEvent) event;
String sessionId = sessionDestroyedEvent.getId();
removeSessionInformation(sessionId);
}
else if (event instanceof SessionIdChangedEvent sessionIdChangedEvent) {
else if (event instanceof SessionIdChangedEvent) {
SessionIdChangedEvent sessionIdChangedEvent = (SessionIdChangedEvent) event;
String oldSessionId = sessionIdChangedEvent.getOldSessionId();
if (this.sessionIds.containsKey(oldSessionId)) {
Object principal = this.sessionIds.get(oldSessionId).getPrincipal();
@@ -59,7 +59,8 @@ public class DefaultToken implements Token {
@Override
public boolean equals(Object obj) {
if (obj instanceof DefaultToken rhs) {
if (obj != null && obj instanceof DefaultToken) {
DefaultToken rhs = (DefaultToken) obj;
return this.key.equals(rhs.key) && this.keyCreationTime == rhs.keyCreationTime
&& this.extendedInformation.equals(rhs.extendedInformation);
}
@@ -70,7 +71,7 @@ public class DefaultToken implements Token {
public int hashCode() {
int code = 979;
code = code * this.key.hashCode();
code = code * Long.valueOf(this.keyCreationTime).hashCode();
code = code * new Long(this.keyCreationTime).hashCode();
code = code * this.extendedInformation.hashCode();
return code;
}
@@ -142,7 +142,7 @@ public class KeyBasedPersistenceTokenService implements TokenService, Initializi
}
private String computeServerSecretApplicableAt(long time) {
return this.serverSecret + ":" + Long.valueOf(time % this.serverInteger).intValue();
return this.serverSecret + ":" + new Long(time % this.serverInteger).intValue();
}
/**
@@ -179,8 +179,8 @@ public class User implements UserDetails, CredentialsContainer {
*/
@Override
public boolean equals(Object obj) {
if (obj instanceof User user) {
return this.username.equals(user.getUsername());
if (obj instanceof User) {
return this.username.equals(((User) obj).username);
}
return false;
}
@@ -201,14 +201,14 @@ public class User implements UserDetails, CredentialsContainer {
sb.append("Password=[PROTECTED], ");
sb.append("Enabled=").append(this.enabled).append(", ");
sb.append("AccountNonExpired=").append(this.accountNonExpired).append(", ");
sb.append("CredentialsNonExpired=").append(this.credentialsNonExpired).append(", ");
sb.append("credentialsNonExpired=").append(this.credentialsNonExpired).append(", ");
sb.append("AccountNonLocked=").append(this.accountNonLocked).append(", ");
sb.append("Granted Authorities=").append(this.authorities).append("]");
return sb.toString();
}
/**
* Creates a UserBuilder with a specified username
* Creates a UserBuilder with a specified user name
* @param username the username to use
* @return the UserBuilder
*/
@@ -329,7 +329,7 @@ public class User implements UserDetails, CredentialsContainer {
private String password;
private List<GrantedAuthority> authorities = new ArrayList<>();
private List<GrantedAuthority> authorities;
private boolean accountExpired;
@@ -427,7 +427,6 @@ public class User implements UserDetails, CredentialsContainer {
* @see #roles(String...)
*/
public UserBuilder authorities(GrantedAuthority... authorities) {
Assert.notNull(authorities, "authorities cannot be null");
return authorities(Arrays.asList(authorities));
}
@@ -440,7 +439,6 @@ public class User implements UserDetails, CredentialsContainer {
* @see #roles(String...)
*/
public UserBuilder authorities(Collection<? extends GrantedAuthority> authorities) {
Assert.notNull(authorities, "authorities cannot be null");
this.authorities = new ArrayList<>(authorities);
return this;
}
@@ -454,7 +452,6 @@ public class User implements UserDetails, CredentialsContainer {
* @see #roles(String...)
*/
public UserBuilder authorities(String... authorities) {
Assert.notNull(authorities, "authorities cannot be null");
return authorities(AuthorityUtils.createAuthorityList(authorities));
}
@@ -127,7 +127,7 @@ public final class SecurityJackson2Modules {
Class<? extends Module> securityModule = (Class<? extends Module>) ClassUtils.forName(className, loader);
if (securityModule != null) {
logger.debug(LogMessage.format("Loaded module %s, now registering", className));
return securityModule.getConstructor().newInstance();
return securityModule.newInstance();
}
}
catch (Exception ex) {
@@ -44,7 +44,8 @@ class UnmodifiableListDeserializer extends JsonDeserializer<List> {
JsonNode node = mapper.readTree(jp);
List<Object> result = new ArrayList<>();
if (node != null) {
if (node instanceof ArrayNode arrayNode) {
if (node instanceof ArrayNode) {
ArrayNode arrayNode = (ArrayNode) node;
for (JsonNode elementNode : arrayNode) {
result.add(mapper.readValue(elementNode.traverse(mapper), Object.class));
}
@@ -44,7 +44,8 @@ class UnmodifiableSetDeserializer extends JsonDeserializer<Set> {
JsonNode node = mapper.readTree(jp);
Set<Object> resultSet = new HashSet<>();
if (node != null) {
if (node instanceof ArrayNode arrayNode) {
if (node instanceof ArrayNode) {
ArrayNode arrayNode = (ArrayNode) node;
for (JsonNode elementNode : arrayNode) {
resultSet.add(mapper.readValue(elementNode.traverse(mapper), Object.class));
}
@@ -60,7 +60,8 @@ public final class MethodInvocationUtils {
// Determine the type that declares the requested method,
// taking into account proxies
Class<?> target = AopUtils.getTargetClass(object);
if (object instanceof Advised a) {
if (object instanceof Advised) {
Advised a = (Advised) object;
if (!a.isProxyTargetClass()) {
Class<?>[] possibleInterfaces = a.getProxiedInterfaces();
for (Class<?> possibleInterface : possibleInterfaces) {
@@ -1,102 +0,0 @@
/*
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
/**
* @author Steve Riesenberg
*/
public final class DelegatingSecurityContextTestUtils {
private DelegatingSecurityContextTestUtils() {
}
public static <T extends Executor> SecurityContext runAndReturn(ThreadFactory threadFactory,
Function<ScheduledExecutorService, T> factory, BiConsumer<T, Runnable> fn) throws Exception {
CountDownLatch countDownLatch = new CountDownLatch(1);
AtomicReference<SecurityContext> result = new AtomicReference<>();
ScheduledExecutorService delegate = Executors.newSingleThreadScheduledExecutor(threadFactory);
try {
T executor = factory.apply(delegate);
Runnable task = () -> {
result.set(SecurityContextHolder.getContext());
countDownLatch.countDown();
};
fn.accept(executor, task);
countDownLatch.await();
return result.get();
}
finally {
delegate.shutdown();
}
}
public static <T extends TaskScheduler> SecurityContext runAndReturn(ThreadFactory threadFactory,
Function<ScheduledExecutorService, T> factory, BiFunction<T, Runnable, ScheduledFuture<?>> fn)
throws Exception {
CountDownLatch countDownLatch = new CountDownLatch(1);
AtomicReference<SecurityContext> result = new AtomicReference<>();
ScheduledExecutorService delegate = Executors.newSingleThreadScheduledExecutor(threadFactory);
try {
T taskScheduler = factory.apply(delegate);
Runnable task = () -> {
result.set(SecurityContextHolder.getContext());
countDownLatch.countDown();
};
ScheduledFuture<?> future = fn.apply(taskScheduler, task);
countDownLatch.await();
future.cancel(false);
return result.get();
}
finally {
delegate.shutdown();
}
}
public static <T extends Executor> SecurityContext callAndReturn(ThreadFactory threadFactory,
Function<ScheduledExecutorService, T> factory,
BiFunction<T, Callable<SecurityContext>, Future<SecurityContext>> fn) throws Exception {
ScheduledExecutorService delegate = Executors.newSingleThreadScheduledExecutor(threadFactory);
try {
T executor = factory.apply(delegate);
Callable<SecurityContext> task = SecurityContextHolder::getContext;
return fn.apply(executor, task).get();
}
finally {
delegate.shutdown();
}
}
}
@@ -16,6 +16,7 @@
package org.springframework.security.access.intercept;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.security.authentication.BadCredentialsException;
@@ -49,7 +50,7 @@ public class RunAsImplAuthenticationProviderTests {
RunAsImplAuthenticationProvider provider = new RunAsImplAuthenticationProvider();
provider.setKey("my_password");
Authentication result = provider.authenticate(token);
assertThat(result instanceof RunAsUserToken).as("Should have returned RunAsUserToken").isTrue();
Assertions.assertTrue(result instanceof RunAsUserToken, "Should have returned RunAsUserToken");
RunAsUserToken resultCast = (RunAsUserToken) result;
assertThat(resultCast.getKeyHash()).isEqualTo("my_password".hashCode());
}
@@ -66,9 +66,9 @@ public class RunAsManagerImplTests {
assertThat(result.getPrincipal()).isEqualTo(inputToken.getPrincipal());
assertThat(result.getCredentials()).isEqualTo(inputToken.getCredentials());
Set<String> authorities = AuthorityUtils.authorityListToSet(result.getAuthorities());
assertThat(authorities).contains("FOOBAR_RUN_AS_SOMETHING");
assertThat(authorities).contains("ONE");
assertThat(authorities).contains("TWO");
assertThat(authorities.contains("FOOBAR_RUN_AS_SOMETHING")).isTrue();
assertThat(authorities.contains("ONE")).isTrue();
assertThat(authorities.contains("TWO")).isTrue();
RunAsUserToken resultCast = (RunAsUserToken) result;
assertThat(resultCast.getKeyHash()).isEqualTo("my_password".hashCode());
}
@@ -87,9 +87,9 @@ public class RunAsManagerImplTests {
assertThat(result.getPrincipal()).isEqualTo(inputToken.getPrincipal());
assertThat(result.getCredentials()).isEqualTo(inputToken.getCredentials());
Set<String> authorities = AuthorityUtils.authorityListToSet(result.getAuthorities());
assertThat(authorities).contains("ROLE_RUN_AS_SOMETHING");
assertThat(authorities).contains("ROLE_ONE");
assertThat(authorities).contains("ROLE_TWO");
assertThat(authorities.contains("ROLE_RUN_AS_SOMETHING")).isTrue();
assertThat(authorities.contains("ROLE_ONE")).isTrue();
assertThat(authorities.contains("ROLE_TWO")).isTrue();
RunAsUserToken resultCast = (RunAsUserToken) result;
assertThat(resultCast.getKeyHash()).isEqualTo("my_password".hashCode());
}
@@ -50,7 +50,7 @@ public class DelegatingMethodSecurityMetadataSourceTests {
sources.add(delegate);
this.mds = new DelegatingMethodSecurityMetadataSource(sources);
assertThat(this.mds.getMethodSecurityMetadataSources()).isSameAs(sources);
assertThat(this.mds.getAllConfigAttributes()).isEmpty();
assertThat(this.mds.getAllConfigAttributes().isEmpty()).isTrue();
MethodInvocation mi = new SimpleMethodInvocation(null, String.class.getMethod("toString"));
assertThat(this.mds.getAttributes(mi)).isEqualTo(Collections.emptyList());
// Exercise the cached case
@@ -68,7 +68,7 @@ public class DelegatingMethodSecurityMetadataSourceTests {
sources.add(delegate);
this.mds = new DelegatingMethodSecurityMetadataSource(sources);
assertThat(this.mds.getMethodSecurityMetadataSources()).isSameAs(sources);
assertThat(this.mds.getAllConfigAttributes()).isEmpty();
assertThat(this.mds.getAllConfigAttributes().isEmpty()).isTrue();
MethodInvocation mi = new SimpleMethodInvocation("", toString);
assertThat(this.mds.getAttributes(mi)).isSameAs(attributes);
// Exercise the cached case
@@ -17,6 +17,7 @@
package org.springframework.security.access.vote;
import java.util.Collection;
import java.util.Iterator;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
@@ -46,7 +47,9 @@ public class DenyAgainVoter implements AccessDecisionVoter<Object> {
@Override
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
for (ConfigAttribute attribute : attributes) {
Iterator<ConfigAttribute> iter = attributes.iterator();
while (iter.hasNext()) {
ConfigAttribute attribute = iter.next();
if (this.supports(attribute)) {
return ACCESS_DENIED;
}
@@ -17,6 +17,7 @@
package org.springframework.security.access.vote;
import java.util.Collection;
import java.util.Iterator;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
@@ -48,7 +49,9 @@ public class DenyVoter implements AccessDecisionVoter<Object> {
@Override
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
for (ConfigAttribute attribute : attributes) {
Iterator<ConfigAttribute> iter = attributes.iterator();
while (iter.hasNext()) {
ConfigAttribute attribute = iter.next();
if (this.supports(attribute)) {
return ACCESS_DENIED;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -93,10 +93,4 @@ public class ObservationAuthenticationManagerTests {
assertThat(context.getAuthenticationResult()).isNull();
}
@Test
void setObservationConventionWhenNullThenException() {
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.tested.setObservationConvention(null));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -96,10 +96,4 @@ public class ObservationReactiveAuthenticationManagerTests {
assertThat(context.getAuthenticationResult()).isNull();
}
@Test
void setObservationConventionWhenNullThenException() {
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.tested.setObservationConvention(null));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,23 +17,15 @@
package org.springframework.security.authentication;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.PasswordEncodedUser;
import org.springframework.security.core.userdetails.UserDetails;
/**
* @author Rob Winch
* @author Evgeniy Cheban
* @since 5.0
*/
public class TestAuthentication extends PasswordEncodedUser {
private static final Authentication ANONYMOUS = new AnonymousAuthenticationToken("key", "anonymous",
AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"));
private static final RememberMeAuthenticationToken REMEMBER_ME = new RememberMeAuthenticationToken("key", "user",
AuthorityUtils.createAuthorityList("ROLE_USER"));
public static Authentication authenticatedAdmin() {
return autheticated(admin());
}
@@ -46,12 +38,4 @@ public class TestAuthentication extends PasswordEncodedUser {
return UsernamePasswordAuthenticationToken.authenticated(user, null, user.getAuthorities());
}
public static Authentication anonymousUser() {
return ANONYMOUS;
}
public static Authentication rememberMeUser() {
return REMEMBER_ME;
}
}
@@ -222,13 +222,16 @@ public class DefaultJaasAuthenticationProviderTests {
public void javadocExample() {
String resName = "/" + getClass().getName().replace('.', '/') + ".xml";
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(resName);
try (context) {
context.registerShutdownHook();
context.registerShutdownHook();
try {
this.provider = context.getBean(DefaultJaasAuthenticationProvider.class);
Authentication auth = this.provider.authenticate(this.token);
assertThat(auth.isAuthenticated()).isEqualTo(true);
assertThat(auth.getPrincipal()).isEqualTo(this.token.getPrincipal());
}
finally {
context.close();
}
}
private void verifyFailedLogin() {
@@ -174,7 +174,8 @@ public class JaasAuthenticationProviderTests {
assertThat(set.contains("ROLE_TEST2")).withFailMessage("GrantedAuthorities should contain ROLE_TEST2").isTrue();
boolean foundit = false;
for (GrantedAuthority a : list) {
if (a instanceof JaasGrantedAuthority grant) {
if (a instanceof JaasGrantedAuthority) {
JaasGrantedAuthority grant = (JaasGrantedAuthority) a;
assertThat(grant.getPrincipal()).withFailMessage("Principal was null on JaasGrantedAuthority")
.isNotNull();
foundit = true;
@@ -30,7 +30,8 @@ public class TestCallbackHandler implements JaasAuthenticationCallbackHandler {
@Override
public void handle(Callback callback, Authentication auth) {
if (callback instanceof TextInputCallback tic) {
if (callback instanceof TextInputCallback) {
TextInputCallback tic = (TextInputCallback) callback;
tic.setText(auth.getPrincipal().toString());
}
}
@@ -89,7 +89,7 @@ public class InMemoryConfigurationTests {
public void mappedNonnullDefault() {
InMemoryConfiguration configuration = new InMemoryConfiguration(this.mappedEntries, this.defaultEntries);
assertThat(this.defaultEntries).isEqualTo(configuration.getAppConfigurationEntry("missing"));
assertThat(this.mappedEntries).containsEntry("name", configuration.getAppConfigurationEntry("name"));
assertThat(this.mappedEntries.get("name")).isEqualTo(configuration.getAppConfigurationEntry("name"));
}
@Test
@@ -1,87 +0,0 @@
/*
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.authorization;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* Tests for {@link AuthoritiesAuthorizationManager}.
*
* @author Evgeniy Cheban
*/
class AuthoritiesAuthorizationManagerTests {
@Test
void setRoleHierarchyWhenNullThenIllegalArgumentException() {
AuthoritiesAuthorizationManager manager = new AuthoritiesAuthorizationManager();
assertThatIllegalArgumentException().isThrownBy(() -> manager.setRoleHierarchy(null))
.withMessage("roleHierarchy cannot be null");
}
@Test
void setRoleHierarchyWhenNotNullThenVerifyRoleHierarchy() {
AuthoritiesAuthorizationManager manager = new AuthoritiesAuthorizationManager();
RoleHierarchy roleHierarchy = new RoleHierarchyImpl();
manager.setRoleHierarchy(roleHierarchy);
assertThat(manager).extracting("roleHierarchy").isEqualTo(roleHierarchy);
}
@Test
void getRoleHierarchyWhenNotSetThenDefaultsToNullRoleHierarchy() {
AuthoritiesAuthorizationManager manager = new AuthoritiesAuthorizationManager();
assertThat(manager).extracting("roleHierarchy").isInstanceOf(NullRoleHierarchy.class);
}
@Test
void checkWhenUserHasAnyAuthorityThenGrantedDecision() {
AuthoritiesAuthorizationManager manager = new AuthoritiesAuthorizationManager();
Supplier<Authentication> authentication = () -> new TestingAuthenticationToken("user", "password", "USER");
assertThat(manager.check(authentication, Arrays.asList("ADMIN", "USER")).isGranted()).isTrue();
}
@Test
void checkWhenUserHasNotAnyAuthorityThenDeniedDecision() {
AuthoritiesAuthorizationManager manager = new AuthoritiesAuthorizationManager();
Supplier<Authentication> authentication = () -> new TestingAuthenticationToken("user", "password", "ANONYMOUS");
assertThat(manager.check(authentication, Arrays.asList("ADMIN", "USER")).isGranted()).isFalse();
}
@Test
void checkWhenRoleHierarchySetThenGreaterRoleTakesPrecedence() {
AuthoritiesAuthorizationManager manager = new AuthoritiesAuthorizationManager();
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");
manager.setRoleHierarchy(roleHierarchy);
Supplier<Authentication> authentication = () -> new TestingAuthenticationToken("user", "password",
"ROLE_ADMIN");
assertThat(manager.check(authentication, Collections.singleton("ROLE_USER")).isGranted()).isTrue();
}
}
@@ -245,13 +245,13 @@ public class AuthorityAuthorizationManagerTests {
AuthorityAuthorizationManager<Object> manager = AuthorityAuthorizationManager.hasRole("USER");
RoleHierarchy roleHierarchy = new RoleHierarchyImpl();
manager.setRoleHierarchy(roleHierarchy);
assertThat(manager).extracting("delegate").extracting("roleHierarchy").isEqualTo(roleHierarchy);
assertThat(manager).extracting("roleHierarchy").isEqualTo(roleHierarchy);
}
@Test
public void getRoleHierarchyWhenNotSetThenDefaultsToNullRoleHierarchy() {
AuthorityAuthorizationManager<Object> manager = AuthorityAuthorizationManager.hasRole("USER");
assertThat(manager).extracting("delegate").extracting("roleHierarchy").isInstanceOf(NullRoleHierarchy.class);
assertThat(manager).extracting("roleHierarchy").isInstanceOf(NullRoleHierarchy.class);
}
@Test
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package org.springframework.security.authorization;
import java.util.Optional;
import java.util.function.Supplier;
import io.micrometer.observation.Observation;
@@ -26,7 +25,6 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.context.MessageSource;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
@@ -34,7 +32,6 @@ import org.springframework.security.core.Authentication;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -88,20 +85,14 @@ public class ObservationAuthorizationManagerTests {
@Test
void verifyWhenErrorsThenObserves() {
MessageSource source = mock(MessageSource.class);
this.tested.setMessageSource(source);
given(this.handler.supportsContext(any())).willReturn(true);
given(this.authorizationManager.check(any(), any())).willReturn(this.deny);
given(source.getMessage(eq("AbstractAccessDecisionManager.accessDenied"), any(), any(), any()))
.willReturn("accessDenied");
assertThatExceptionOfType(AccessDeniedException.class)
.isThrownBy(() -> this.tested.verify(this.token, this.object));
ArgumentCaptor<Observation.Context> captor = ArgumentCaptor.forClass(Observation.Context.class);
verify(this.handler).onStart(captor.capture());
assertThat(captor.getValue().getName()).isEqualTo(AuthorizationObservationConvention.OBSERVATION_NAME);
assertThat(captor.getValue().getError()).isInstanceOf(AccessDeniedException.class);
assertThat(Optional.ofNullable(captor.getValue().getError()).map(Throwable::getMessage).orElse(""))
.isEqualTo("accessDenied");
assertThat(captor.getValue()).isInstanceOf(AuthorizationObservationContext.class);
AuthorizationObservationContext<?> context = (AuthorizationObservationContext<?>) captor.getValue();
assertThat(context.getAuthentication()).isNull();
@@ -127,10 +118,4 @@ public class ObservationAuthorizationManagerTests {
assertThat(context.getDecision()).isEqualTo(this.grant);
}
@Test
void setObservationConventionWhenNullThenException() {
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.tested.setObservationConvention(null));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -117,10 +117,4 @@ public class ObservationReactiveAuthorizationManagerTests {
assertThat(context.getDecision()).isEqualTo(this.grant);
}
@Test
void setObservationConventionWhenNullThenException() {
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.tested.setObservationConvention(null));
}
}
@@ -38,7 +38,7 @@ import static org.mockito.Mockito.verifyNoInteractions;
*/
public class SpringAuthorizationEventPublisherTests {
Supplier<Authentication> authentication = TestAuthentication::authenticatedUser;
Supplier<Authentication> authentication = () -> TestAuthentication.authenticatedUser();
ApplicationEventPublisher applicationEventPublisher;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,8 +18,6 @@ package org.springframework.security.authorization.method;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collection;
import java.util.Set;
import java.util.function.Supplier;
import jakarta.annotation.security.DenyAll;
@@ -32,14 +30,11 @@ import org.springframework.security.access.intercept.method.MockMethodInvocation
import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link Jsr250AuthorizationManager}.
@@ -68,27 +63,6 @@ public class Jsr250AuthorizationManagerTests {
assertThat(manager).extracting("rolePrefix").isEqualTo("CUSTOM_");
}
@Test
public void setAuthoritiesAuthorizationManagerWhenNullThenException() {
Jsr250AuthorizationManager manager = new Jsr250AuthorizationManager();
assertThatIllegalArgumentException().isThrownBy(() -> manager.setAuthoritiesAuthorizationManager(null))
.withMessage("authoritiesAuthorizationManager cannot be null");
}
@Test
public void setAuthoritiesAuthorizationManagerWhenNotNullThenVerifyUsage() throws Exception {
AuthorizationManager<Collection<String>> authoritiesAuthorizationManager = mock(AuthorizationManager.class);
Jsr250AuthorizationManager manager = new Jsr250AuthorizationManager();
manager.setAuthoritiesAuthorizationManager(authoritiesAuthorizationManager);
MockMethodInvocation methodInvocation = new MockMethodInvocation(new ClassLevelAnnotations(),
ClassLevelAnnotations.class, "rolesAllowedAdmin");
Supplier<Authentication> authentication = () -> new TestingAuthenticationToken("user", "password",
"ROLE_ADMIN");
AuthorizationDecision decision = manager.check(authentication, methodInvocation);
assertThat(decision).isNull();
verify(authoritiesAuthorizationManager).check(authentication, Set.of("ROLE_ADMIN"));
}
@Test
public void checkDoSomethingWhenNoJsr250AnnotationsThenNullDecision() throws Exception {
MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
@@ -149,7 +123,7 @@ public class Jsr250AuthorizationManagerTests {
}
@Test
public void checkMultipleMethodAnnotationsWhenInvokedThenAnnotationConfigurationException() throws Exception {
public void checkMultipleAnnotationsWhenInvokedThenAnnotationConfigurationException() throws Exception {
Supplier<Authentication> authentication = () -> new TestingAuthenticationToken("user", "password",
"ROLE_ANONYMOUS");
MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
@@ -159,16 +133,6 @@ public class Jsr250AuthorizationManagerTests {
.isThrownBy(() -> manager.check(authentication, methodInvocation));
}
@Test
public void checkMultipleClassAnnotationsWhenInvokedThenAnnotationConfigurationException() throws Exception {
Supplier<Authentication> authentication = () -> new TestingAuthenticationToken("user", "password", "ROLE_USER");
MockMethodInvocation methodInvocation = new MockMethodInvocation(new ClassLevelIllegalAnnotations(),
ClassLevelIllegalAnnotations.class, "inheritedAnnotations");
Jsr250AuthorizationManager manager = new Jsr250AuthorizationManager();
assertThatExceptionOfType(AnnotationConfigurationException.class)
.isThrownBy(() -> manager.check(authentication, methodInvocation));
}
@Test
public void checkRequiresAdminWhenClassAnnotationsThenMethodAnnotationsTakePrecedence() throws Exception {
Supplier<Authentication> authentication = () -> new TestingAuthenticationToken("user", "password", "ROLE_USER");
@@ -283,15 +247,6 @@ public class Jsr250AuthorizationManagerTests {
}
@MyIllegalRolesAllowed
public static class ClassLevelIllegalAnnotations {
public void inheritedAnnotations() {
}
}
public interface InterfaceAnnotationsOne {
@RolesAllowed("ADMIN")
@@ -319,11 +274,4 @@ public class Jsr250AuthorizationManagerTests {
}
@DenyAll
@RolesAllowed("USER")
@Retention(RetentionPolicy.RUNTIME)
public @interface MyIllegalRolesAllowed {
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,8 +18,6 @@ package org.springframework.security.authorization.method;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collection;
import java.util.Set;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
@@ -31,14 +29,10 @@ import org.springframework.security.access.intercept.method.MockMethodInvocation
import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link SecuredAuthorizationManager}.
@@ -47,26 +41,6 @@ import static org.mockito.Mockito.verify;
*/
public class SecuredAuthorizationManagerTests {
@Test
public void setAuthoritiesAuthorizationManagerWhenNullThenException() {
SecuredAuthorizationManager manager = new SecuredAuthorizationManager();
assertThatIllegalArgumentException().isThrownBy(() -> manager.setAuthoritiesAuthorizationManager(null))
.withMessage("authoritiesAuthorizationManager cannot be null");
}
@Test
public void setAuthoritiesAuthorizationManagerWhenNotNullThenVerifyUsage() throws Exception {
AuthorizationManager<Collection<String>> authoritiesAuthorizationManager = mock(AuthorizationManager.class);
SecuredAuthorizationManager manager = new SecuredAuthorizationManager();
manager.setAuthoritiesAuthorizationManager(authoritiesAuthorizationManager);
MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"securedUserOrAdmin");
Supplier<Authentication> authentication = TestAuthentication::authenticatedUser;
AuthorizationDecision decision = manager.check(authentication, methodInvocation);
assertThat(decision).isNull();
verify(authoritiesAuthorizationManager).check(authentication, Set.of("ROLE_USER", "ROLE_ADMIN"));
}
@Test
public void checkDoSomethingWhenNoSecuredAnnotationThenNullDecision() throws Exception {
MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
@@ -1,75 +0,0 @@
/*
* Copyright 2020-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.concurrent;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.JRE;
import org.springframework.core.task.VirtualThreadTaskExecutor;
import org.springframework.security.DelegatingSecurityContextTestUtils;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Steve Riesenberg
*/
public class DelegatingSecurityContextExecutorIntegrationTests {
@Test
public void executeWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void executeWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeAndReturn(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext executeAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.runAndReturn(
threadFactory,
this::createExecutor,
Executor::execute
);
// @formatter:on
}
private DelegatingSecurityContextExecutor createExecutor(ScheduledExecutorService delegate) {
return new DelegatingSecurityContextExecutor(delegate, securityContext());
}
private static SecurityContext securityContext() {
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(new TestingAuthenticationToken("user", null));
return securityContext;
}
}
@@ -1,98 +0,0 @@
/*
* Copyright 2020-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.concurrent;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.JRE;
import org.springframework.core.task.VirtualThreadTaskExecutor;
import org.springframework.security.DelegatingSecurityContextTestUtils;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Steve Riesenberg
*/
public class DelegatingSecurityContextExecutorServiceIntegrationTests {
@Test
public void executeWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void executeWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeAndReturn(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext executeAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.runAndReturn(
threadFactory,
this::createExecutor,
ExecutorService::execute
);
// @formatter:on
}
@Test
public void submitWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = submitAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void submitWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = submitAndReturn(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext submitAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.callAndReturn(
threadFactory,
this::createExecutor,
ExecutorService::submit
);
// @formatter:on
}
private DelegatingSecurityContextExecutorService createExecutor(ScheduledExecutorService delegate) {
return new DelegatingSecurityContextExecutorService(delegate, securityContext());
}
private static SecurityContext securityContext() {
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(new TestingAuthenticationToken("user", null));
return securityContext;
}
}
@@ -1,121 +0,0 @@
/*
* Copyright 2020-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.concurrent;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.JRE;
import org.springframework.core.task.VirtualThreadTaskExecutor;
import org.springframework.security.DelegatingSecurityContextTestUtils;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Steve Riesenberg
*/
public class DelegatingSecurityContextScheduledExecutorServiceIntegrationTests {
@Test
public void executeWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void executeWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeAndReturn(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext executeAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.runAndReturn(
threadFactory,
this::createExecutor,
ScheduledExecutorService::execute
);
// @formatter:on
}
@Test
public void submitWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = submitAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void submitWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = submitAndReturn(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext submitAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.callAndReturn(
threadFactory,
this::createExecutor,
ScheduledExecutorService::submit
);
// @formatter:on
}
@Test
public void scheduleWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = scheduleAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void scheduleWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = scheduleAndReturn(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext scheduleAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.callAndReturn(
threadFactory,
this::createExecutor,
(executor, task) -> executor.schedule(task, 50, TimeUnit.MILLISECONDS)
);
// @formatter:on
}
private DelegatingSecurityContextScheduledExecutorService createExecutor(ScheduledExecutorService delegate) {
return new DelegatingSecurityContextScheduledExecutorService(delegate, securityContext());
}
private static SecurityContext securityContext() {
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(new TestingAuthenticationToken("user", null));
return securityContext;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,11 +32,11 @@ public class JavaVersionTests {
private static final int JDK17_CLASS_VERSION = 61;
@Test
public void authenticationWhenJdk17ThenCorrectJdkCompatibility() throws Exception {
assertClassVersion(Authentication.class, JDK17_CLASS_VERSION);
public void authenticationCorrectJdkCompatibility() throws Exception {
assertClassVersion(Authentication.class);
}
private void assertClassVersion(Class<?> clazz, int classVersion) throws Exception {
private void assertClassVersion(Class<?> clazz) throws Exception {
String classResourceName = clazz.getName().replaceAll("\\.", "/") + ".class";
try (InputStream input = Thread.currentThread()
.getContextClassLoader()
@@ -45,7 +45,7 @@ public class JavaVersionTests {
data.readInt();
data.readShort(); // minor
int major = data.readShort();
assertThat(major).isEqualTo(classVersion);
assertThat(major).isEqualTo(JDK17_CLASS_VERSION);
}
}
@@ -68,7 +68,13 @@ final class StaticFinalReflectionUtils {
field.set(null, newValue);
}
}
catch (SecurityException | IllegalAccessException | IllegalArgumentException ex) {
catch (SecurityException ex) {
throw new RuntimeException(ex);
}
catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
}
catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package org.springframework.security.core.authority;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
@@ -28,7 +27,6 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Luke Taylor
* @author Evgeniy Cheban
*/
public class AuthorityUtilsTests {
@@ -37,21 +35,11 @@ public class AuthorityUtilsTests {
List<GrantedAuthority> authorityArray = AuthorityUtils
.commaSeparatedStringToAuthorityList(" ROLE_A, B, C, ROLE_D\n,\n E ");
Set<String> authorities = AuthorityUtils.authorityListToSet(authorityArray);
assertThat(authorities).contains("B");
assertThat(authorities).contains("C");
assertThat(authorities).contains("E");
assertThat(authorities).contains("ROLE_A");
assertThat(authorities).contains("ROLE_D");
}
@Test
public void createAuthorityList() {
List<GrantedAuthority> authorities = AuthorityUtils
.createAuthorityList(Arrays.asList("ROLE_A", "ROLE_B", "ROLE_C"));
assertThat(authorities).hasSize(3);
assertThat(authorities).element(0).extracting(GrantedAuthority::getAuthority).isEqualTo("ROLE_A");
assertThat(authorities).element(1).extracting(GrantedAuthority::getAuthority).isEqualTo("ROLE_B");
assertThat(authorities).element(2).extracting(GrantedAuthority::getAuthority).isEqualTo("ROLE_C");
assertThat(authorities.contains("B")).isTrue();
assertThat(authorities.contains("C")).isTrue();
assertThat(authorities.contains("E")).isTrue();
assertThat(authorities.contains("ROLE_A")).isTrue();
assertThat(authorities.contains("ROLE_D")).isTrue();
}
}
@@ -45,8 +45,8 @@ public class SimpleAuthoritiesMapperTests {
SimpleAuthorityMapper mapper = new SimpleAuthorityMapper();
Set<String> mapped = AuthorityUtils
.authorityListToSet(mapper.mapAuthorities(AuthorityUtils.createAuthorityList("AaA", "ROLE_bbb")));
assertThat(mapped).contains("ROLE_AaA");
assertThat(mapped).contains("ROLE_bbb");
assertThat(mapped.contains("ROLE_AaA")).isTrue();
assertThat(mapped.contains("ROLE_bbb")).isTrue();
}
@Test
@@ -56,19 +56,19 @@ public class SimpleAuthoritiesMapperTests {
List<GrantedAuthority> toMap = AuthorityUtils.createAuthorityList("AaA", "Bbb");
Set<String> mapped = AuthorityUtils.authorityListToSet(mapper.mapAuthorities(toMap));
assertThat(mapped).hasSize(2);
assertThat(mapped).contains("AaA");
assertThat(mapped).contains("Bbb");
assertThat(mapped.contains("AaA")).isTrue();
assertThat(mapped.contains("Bbb")).isTrue();
mapper.setConvertToLowerCase(true);
mapped = AuthorityUtils.authorityListToSet(mapper.mapAuthorities(toMap));
assertThat(mapped).hasSize(2);
assertThat(mapped).contains("aaa");
assertThat(mapped).contains("bbb");
assertThat(mapped.contains("aaa")).isTrue();
assertThat(mapped.contains("bbb")).isTrue();
mapper.setConvertToLowerCase(false);
mapper.setConvertToUpperCase(true);
mapped = AuthorityUtils.authorityListToSet(mapper.mapAuthorities(toMap));
assertThat(mapped).hasSize(2);
assertThat(mapped).contains("AAA");
assertThat(mapped).contains("BBB");
assertThat(mapped.contains("AAA")).isTrue();
assertThat(mapped.contains("BBB")).isTrue();
}
@Test
@@ -86,7 +86,7 @@ public class SimpleAuthoritiesMapperTests {
mapper.setDefaultAuthority("ROLE_USER");
Set<String> mapped = AuthorityUtils.authorityListToSet(mapper.mapAuthorities(AuthorityUtils.NO_AUTHORITIES));
assertThat(mapped).hasSize(1);
assertThat(mapped).contains("ROLE_USER");
assertThat(mapped.contains("ROLE_USER")).isTrue();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,17 +16,10 @@
package org.springframework.security.core.context;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.JRE;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import reactor.test.StepVerifier;
import org.springframework.core.task.VirtualThreadTaskExecutor;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
@@ -106,53 +99,4 @@ public class ReactiveSecurityContextHolderTests {
// @formatter:on
}
@Test
public void getContextWhenThreadFactoryIsPlatformThenPropagated() {
verifySecurityContextIsPropagated(Executors.defaultThreadFactory());
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void getContextWhenThreadFactoryIsVirtualThenPropagated() {
verifySecurityContextIsPropagated(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
}
private static void verifySecurityContextIsPropagated(ThreadFactory threadFactory) {
Authentication authentication = new TestingAuthenticationToken("user", null);
// @formatter:off
Mono<Authentication> publisher = ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication)
.contextWrite((context) -> ReactiveSecurityContextHolder.withAuthentication(authentication))
.subscribeOn(Schedulers.newSingle(threadFactory));
// @formatter:on
StepVerifier.create(publisher).expectNext(authentication).verifyComplete();
}
@Test
public void clearContextWhenThreadFactoryIsPlatformThenCleared() {
verifySecurityContextIsCleared(Executors.defaultThreadFactory());
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void clearContextWhenThreadFactoryIsVirtualThenCleared() {
verifySecurityContextIsCleared(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
}
private static void verifySecurityContextIsCleared(ThreadFactory threadFactory) {
Authentication authentication = new TestingAuthenticationToken("user", null);
// @formatter:off
Mono<Authentication> publisher = ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication)
.contextWrite(ReactiveSecurityContextHolder.clearContext())
.contextWrite((context) -> ReactiveSecurityContextHolder.withAuthentication(authentication))
.subscribeOn(Schedulers.newSingle(threadFactory));
// @formatter:on
StepVerifier.create(publisher).verifyComplete();
}
}
@@ -57,7 +57,7 @@ class ThreadLocalSecurityContextHolderStrategyTests {
void deferredContextValidates() {
this.strategy.setDeferredContext(() -> null);
Supplier<SecurityContext> deferredContext = this.strategy.getDeferredContext();
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(deferredContext::get);
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> deferredContext.get());
}
@Test
@@ -24,8 +24,8 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.StandardReflectionParameterNameDiscoverer;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
@@ -60,11 +60,11 @@ public class DefaultSecurityParameterNameDiscovererTests {
@Test
public void constructorDiscoverers() {
this.discoverer = new DefaultSecurityParameterNameDiscoverer(
Arrays.asList(new StandardReflectionParameterNameDiscoverer()));
Arrays.asList(new LocalVariableTableParameterNameDiscoverer()));
List<ParameterNameDiscoverer> discoverers = (List<ParameterNameDiscoverer>) ReflectionTestUtils
.getField(this.discoverer, "parameterNameDiscoverers");
assertThat(discoverers).hasSize(3);
assertThat(discoverers.get(0)).isInstanceOf(StandardReflectionParameterNameDiscoverer.class);
assertThat(discoverers.get(0)).isInstanceOf(LocalVariableTableParameterNameDiscoverer.class);
ParameterNameDiscoverer annotationDisc = discoverers.get(1);
assertThat(annotationDisc).isInstanceOf(AnnotationParameterNameDiscoverer.class);
Set<String> annotationsToUse = (Set<String>) ReflectionTestUtils.getField(annotationDisc,
@@ -97,8 +97,8 @@ public class SessionRegistryImplTests {
this.sessionRegistry.registerNewSession(sessionId2, principal1);
this.sessionRegistry.registerNewSession(sessionId3, principal2);
assertThat(this.sessionRegistry.getAllPrincipals()).hasSize(2);
assertThat(this.sessionRegistry.getAllPrincipals()).contains(principal1);
assertThat(this.sessionRegistry.getAllPrincipals()).contains(principal2);
assertThat(this.sessionRegistry.getAllPrincipals().contains(principal1)).isTrue();
assertThat(this.sessionRegistry.getAllPrincipals().contains(principal2)).isTrue();
}
@Test
@@ -18,17 +18,12 @@ package org.springframework.security.core.userdetails;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.NullSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
@@ -42,7 +37,6 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
* Tests {@link User}.
*
* @author Ben Alex
* @author Ilya Starchenko
*/
public class UserTests {
@@ -74,70 +68,6 @@ public class UserTests {
.isThrownBy(() -> User.class.getDeclaredConstructor((Class[]) null));
}
@Test
public void testBuildUserWithNoAuthorities() {
UserDetails user = User.builder().username("user").password("password").build();
assertThat(user.getAuthorities()).isEmpty();
}
@Test
public void testNullWithinUserAuthoritiesIsRejected() {
assertThatIllegalArgumentException().isThrownBy(() -> User.builder()
.username("user")
.password("password")
.authorities((Collection<? extends GrantedAuthority>) null)
.build());
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(null);
authorities.add(null);
assertThatIllegalArgumentException()
.isThrownBy(() -> User.builder().username("user").password("password").authorities(authorities).build());
assertThatIllegalArgumentException().isThrownBy(() -> User.builder()
.username("user")
.password("password")
.authorities((GrantedAuthority[]) null)
.build());
assertThatIllegalArgumentException().isThrownBy(() -> User.builder()
.username("user")
.password("password")
.authorities(new GrantedAuthority[] { null, null })
.build());
assertThatIllegalArgumentException().isThrownBy(
() -> User.builder().username("user").password("password").authorities((String[]) null).build());
assertThatIllegalArgumentException().isThrownBy(() -> User.builder()
.username("user")
.password("password")
.authorities(new String[] { null, null })
.build());
}
// gh-12533
@ParameterizedTest
@NullSource
@ValueSource(strings = { "ROLE_USER,ROLE_ADMIN,read", "read" })
public void withUserDetailsWhenAuthoritiesThenOverridesPreviousAuthorities(String arg) {
// @formatter:off
UserDetails parent = User.builder()
.username("user")
.password("password")
.authorities("one", "two", "three")
.build();
// @formatter:on
String[] authorities = (arg != null) ? arg.split(",") : new String[0];
User.UserBuilder builder = User.withUserDetails(parent);
UserDetails user = builder.build();
assertThat(AuthorityUtils.authorityListToSet(user.getAuthorities())).containsOnly("one", "two", "three");
user = builder.authorities(authorities).build();
assertThat(AuthorityUtils.authorityListToSet(user.getAuthorities())).containsOnly(authorities);
user = builder.authorities(AuthorityUtils.createAuthorityList(authorities)).build();
assertThat(AuthorityUtils.authorityListToSet(user.getAuthorities())).containsOnly(authorities);
user = builder.authorities(AuthorityUtils.createAuthorityList(authorities).toArray(GrantedAuthority[]::new))
.build();
assertThat(AuthorityUtils.authorityListToSet(user.getAuthorities())).containsOnly(authorities);
}
@Test
public void testNullValuesRejected() {
assertThatIllegalArgumentException().isThrownBy(() -> new User(null, "koala", true, true, true, true, ROLE_12));
@@ -145,7 +145,7 @@ public class JdbcUserDetailsManagerTests {
AuthorityUtils.createAuthorityList("A", "B"));
this.manager.createUser(user);
UserDetails user2 = this.manager.loadUserByUsername(user.getUsername());
assertThat(user2).usingRecursiveComparison().isEqualTo(user);
assertThat(user2).isEqualToComparingFieldByField(user);
}
@Test
@@ -176,7 +176,7 @@ public class JdbcUserDetailsManagerTests {
AuthorityUtils.createAuthorityList("D", "F", "E"));
this.manager.updateUser(newJoe);
UserDetails joe = this.manager.loadUserByUsername(newJoe.getUsername());
assertThat(joe).usingRecursiveComparison().isEqualTo(newJoe);
assertThat(joe).isEqualToComparingFieldByField(newJoe);
assertThat(this.cache.getUserMap().containsKey(newJoe.getUsername())).isFalse();
}
@@ -189,7 +189,7 @@ public class JdbcUserDetailsManagerTests {
public void userExistsReturnsTrueForExistingUsername() {
insertJoe();
assertThat(this.manager.userExists("joe")).isTrue();
assertThat(this.cache.getUserMap()).containsKey("joe");
assertThat(this.cache.getUserMap().containsKey("joe")).isTrue();
}
@Test
@@ -251,7 +251,7 @@ public class JdbcUserDetailsManagerTests {
UserDetails newJoe = this.manager.loadUserByUsername("joe");
assertThat(newJoe.getPassword()).isEqualTo("password");
assertThat(SecurityContextHolder.getContext().getAuthentication().getCredentials()).isEqualTo("password");
assertThat(this.cache.getUserMap()).containsKey("joe");
assertThat(this.cache.getUserMap().containsKey("joe")).isTrue();
}
@Test
@@ -1,148 +0,0 @@
/*
* Copyright 2020-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.scheduling;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.JRE;
import org.springframework.core.task.VirtualThreadTaskExecutor;
import org.springframework.scheduling.SchedulingTaskExecutor;
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
import org.springframework.security.DelegatingSecurityContextTestUtils;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Steve Riesenberg
*/
public class DelegatingSecurityContextSchedulingTaskExecutorIntegrationTests {
@Test
public void executeWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void executeWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeAndReturn(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext executeAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.runAndReturn(
threadFactory,
this::createExecutor,
SchedulingTaskExecutor::execute
);
// @formatter:on
}
@Test
public void executeCompletableWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeCompletableAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void executeCompletableWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeCompletableAndReturn(
new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext executeCompletableAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.runAndReturn(
threadFactory,
this::createExecutor,
SchedulingTaskExecutor::submitCompletable
);
// @formatter:on
}
@Test
public void submitWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = submitAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void submitWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = submitAndReturn(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext submitAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.callAndReturn(
threadFactory,
this::createExecutor,
SchedulingTaskExecutor::submit
);
// @formatter:on
}
@Test
public void submitCompletableWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = submitCompletableAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void submitCompletableWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = submitCompletableAndReturn(
new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext submitCompletableAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.callAndReturn(
threadFactory,
this::createExecutor,
SchedulingTaskExecutor::submitCompletable
);
// @formatter:on
}
private DelegatingSecurityContextSchedulingTaskExecutor createExecutor(ScheduledExecutorService delegate) {
return new DelegatingSecurityContextSchedulingTaskExecutor(new ConcurrentTaskExecutor(delegate),
securityContext());
}
private static SecurityContext securityContext() {
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(new TestingAuthenticationToken("user", null));
return securityContext;
}
}
@@ -1,125 +0,0 @@
/*
* Copyright 2020-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.scheduling;
import java.time.Duration;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.JRE;
import org.springframework.core.task.VirtualThreadTaskExecutor;
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.security.DelegatingSecurityContextTestUtils;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Steve Riesenberg
*/
public class DelegatingSecurityContextTaskSchedulerIntegrationTests {
@Test
public void scheduleWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = scheduleAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void scheduleWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = scheduleAndReturn(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext scheduleAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.runAndReturn(
threadFactory,
this::createTaskScheduler,
(taskScheduler, task) -> taskScheduler.schedule(task, new PeriodicTrigger(Duration.ofMillis(50)))
);
// @formatter:on
}
@Test
public void scheduleAtFixedRateWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = scheduleAtFixedRateAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void scheduleAtFixedRateWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = scheduleAtFixedRateAndReturn(
new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext scheduleAtFixedRateAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.runAndReturn(
threadFactory,
this::createTaskScheduler,
(taskScheduler, task) -> taskScheduler.scheduleAtFixedRate(task, Duration.ofMillis(50))
);
// @formatter:on
}
@Test
public void scheduleWithFixedDelayWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = scheduleWithFixedDelayAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void scheduleWithFixedDelayWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = scheduleWithFixedDelayAndReturn(
new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext scheduleWithFixedDelayAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.runAndReturn(
threadFactory,
this::createTaskScheduler,
(taskScheduler, task) -> taskScheduler.scheduleWithFixedDelay(task, Duration.ofMillis(50))
);
// @formatter:on
}
private DelegatingSecurityContextTaskScheduler createTaskScheduler(ScheduledExecutorService delegate) {
return new DelegatingSecurityContextTaskScheduler(new ConcurrentTaskScheduler(delegate), securityContext());
}
private static SecurityContext securityContext() {
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(new TestingAuthenticationToken("user", null));
return securityContext;
}
}
@@ -1,143 +0,0 @@
/*
* Copyright 2020-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.task;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.JRE;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.task.VirtualThreadTaskExecutor;
import org.springframework.core.task.support.TaskExecutorAdapter;
import org.springframework.security.DelegatingSecurityContextTestUtils;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Steve Riesenberg
*/
public class DelegatingSecurityContextAsyncTaskExecutorIntegrationTests {
@Test
public void executeWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void executeWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeAndReturn(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext executeAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.runAndReturn(threadFactory,
this::createExecutor,
AsyncTaskExecutor::execute
);
// @formatter:on
}
@Test
public void executeCompletableWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeCompletableAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void executeCompletableWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeCompletableAndReturn(
new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext executeCompletableAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.runAndReturn(threadFactory,
this::createExecutor,
AsyncTaskExecutor::submitCompletable
);
// @formatter:on
}
@Test
public void submitWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = submitAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void submitWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = submitAndReturn(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext submitAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.callAndReturn(threadFactory,
this::createExecutor,
AsyncTaskExecutor::submit
);
// @formatter:on
}
@Test
public void submitCompletableWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = submitCompletableAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void submitCompletableWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = submitCompletableAndReturn(
new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext submitCompletableAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.callAndReturn(threadFactory,
this::createExecutor,
AsyncTaskExecutor::submitCompletable
);
// @formatter:on
}
private DelegatingSecurityContextAsyncTaskExecutor createExecutor(ScheduledExecutorService delegate) {
return new DelegatingSecurityContextAsyncTaskExecutor(new TaskExecutorAdapter(delegate), securityContext());
}
private static SecurityContext securityContext() {
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(new TestingAuthenticationToken("user", null));
return securityContext;
}
}
@@ -1,75 +0,0 @@
/*
* Copyright 2020-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.task;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.JRE;
import org.springframework.core.task.TaskExecutor;
import org.springframework.core.task.VirtualThreadTaskExecutor;
import org.springframework.core.task.support.TaskExecutorAdapter;
import org.springframework.security.DelegatingSecurityContextTestUtils;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Steve Riesenberg
*/
public class DelegatingSecurityContextTaskExecutorIntegrationTests {
@Test
public void executeWhenThreadFactoryIsPlatformThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeAndReturn(Executors.defaultThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
@Test
@DisabledOnJre(JRE.JAVA_17)
public void executeWhenThreadFactoryIsVirtualThenSecurityContextPropagated() throws Exception {
SecurityContext securityContext = executeAndReturn(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
assertThat(securityContext.getAuthentication()).isNotNull();
}
private SecurityContext executeAndReturn(ThreadFactory threadFactory) throws Exception {
// @formatter:off
return DelegatingSecurityContextTestUtils.runAndReturn(threadFactory,
this::createExecutor,
TaskExecutor::execute
);
// @formatter:on
}
private DelegatingSecurityContextTaskExecutor createExecutor(ScheduledExecutorService delegate) {
return new DelegatingSecurityContextTaskExecutor(new TaskExecutorAdapter(delegate), securityContext());
}
private static SecurityContext securityContext() {
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(new TestingAuthenticationToken("user", null));
return securityContext;
}
}