Revert unnecessary merges on 6.0.x
This commit removes unnecessary main-branch merges starting from8750608b5band adds the following needed commit(s) that were made afterward: -5dce82c48b
This commit is contained in:
@@ -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;
|
||||
|
||||
+2
-1
@@ -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);
|
||||
|
||||
+26
-8
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -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) {
|
||||
|
||||
+2
-1
@@ -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;
|
||||
|
||||
+26
-8
@@ -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) {
|
||||
|
||||
+8
-7
@@ -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;
|
||||
}
|
||||
|
||||
+2
-1
@@ -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;
|
||||
|
||||
-17
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-14
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-15
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
+6
-2
@@ -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;
|
||||
}
|
||||
|
||||
+1
-8
@@ -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;
|
||||
|
||||
+4
-2
@@ -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);
|
||||
|
||||
+3
-2
@@ -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;
|
||||
}
|
||||
|
||||
+3
@@ -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() {
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-81
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
+29
-5
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
-3
@@ -95,9 +95,6 @@ public final class AuthorizationObservationConvention
|
||||
if (className.contains("Message")) {
|
||||
return "message";
|
||||
}
|
||||
if (className.contains("Exchange")) {
|
||||
return "exchange";
|
||||
}
|
||||
return className;
|
||||
}
|
||||
|
||||
|
||||
+4
-34
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-15
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-29
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+20
-43
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -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;
|
||||
}
|
||||
|
||||
+1
@@ -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) {
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ public interface SecurityContextHolderStrategy {
|
||||
* @since 5.8
|
||||
*/
|
||||
default Supplier<SecurityContext> getDeferredContext() {
|
||||
return this::getContext;
|
||||
return () -> getContext();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-1
@@ -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;
|
||||
}
|
||||
|
||||
+1
@@ -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);
|
||||
|
||||
+6
@@ -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
|
||||
|
||||
+4
-2
@@ -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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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) {
|
||||
|
||||
+2
-1
@@ -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));
|
||||
}
|
||||
|
||||
+2
-1
@@ -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) {
|
||||
|
||||
-102
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+2
-1
@@ -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());
|
||||
}
|
||||
|
||||
+6
-6
@@ -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());
|
||||
}
|
||||
|
||||
+2
-2
@@ -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
-7
@@ -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
-7
@@ -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
-17
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
-2
@@ -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() {
|
||||
|
||||
+2
-1
@@ -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;
|
||||
|
||||
+2
-1
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
-87
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -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
-16
@@ -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
-7
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
|
||||
+2
-54
@@ -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
-27
@@ -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,
|
||||
|
||||
-75
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
-98
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
-121
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-1
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-18
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-9
@@ -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
-57
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+3
-3
@@ -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,
|
||||
|
||||
+2
-2
@@ -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));
|
||||
|
||||
+4
-4
@@ -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
|
||||
|
||||
-148
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
-125
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
-143
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
-75
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user