mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-12 05:13:33 +00:00
Defer ObservationRegistry Resolution
- If Method Security asks for too early, it is no longer eligible for post-processing. As such, this commit defers loading it until the first authorization request. Issue gh-11990
This commit is contained in:
parent
7b28df8ebe
commit
c45cd6ec9f
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* 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.config.annotation.method.configuration;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import io.micrometer.observation.ObservationRegistry;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
|
import org.springframework.security.authorization.AuthorizationDecision;
|
||||||
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
|
import org.springframework.security.authorization.ObservationAuthorizationManager;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.util.function.SingletonSupplier;
|
||||||
|
|
||||||
|
final class DeferringObservationAuthorizationManager<T> implements AuthorizationManager<T> {
|
||||||
|
|
||||||
|
private final Supplier<AuthorizationManager<T>> delegate;
|
||||||
|
|
||||||
|
DeferringObservationAuthorizationManager(ObjectProvider<ObservationRegistry> provider,
|
||||||
|
AuthorizationManager<T> delegate) {
|
||||||
|
this.delegate = SingletonSupplier.of(() -> {
|
||||||
|
ObservationRegistry registry = provider.getIfAvailable(() -> ObservationRegistry.NOOP);
|
||||||
|
if (registry.isNoop()) {
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
return new ObservationAuthorizationManager<>(registry, delegate);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthorizationDecision check(Supplier<Authentication> authentication, T object) {
|
||||||
|
return this.delegate.get().check(authentication, object);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -26,7 +26,6 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Role;
|
import org.springframework.context.annotation.Role;
|
||||||
import org.springframework.security.authorization.AuthorizationManager;
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
import org.springframework.security.authorization.ObservationAuthorizationManager;
|
|
||||||
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
||||||
import org.springframework.security.authorization.method.Jsr250AuthorizationManager;
|
import org.springframework.security.authorization.method.Jsr250AuthorizationManager;
|
||||||
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
||||||
@ -54,19 +53,12 @@ final class Jsr250MethodSecurityConfiguration {
|
|||||||
defaultsProvider.ifAvailable((d) -> jsr250.setRolePrefix(d.getRolePrefix()));
|
defaultsProvider.ifAvailable((d) -> jsr250.setRolePrefix(d.getRolePrefix()));
|
||||||
SecurityContextHolderStrategy strategy = strategyProvider
|
SecurityContextHolderStrategy strategy = strategyProvider
|
||||||
.getIfAvailable(SecurityContextHolder::getContextHolderStrategy);
|
.getIfAvailable(SecurityContextHolder::getContextHolderStrategy);
|
||||||
ObservationRegistry registry = registryProvider.getIfAvailable(() -> ObservationRegistry.NOOP);
|
AuthorizationManager<MethodInvocation> manager = new DeferringObservationAuthorizationManager<>(
|
||||||
AuthorizationManager<MethodInvocation> manager = manager(jsr250, registry);
|
registryProvider, jsr250);
|
||||||
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor
|
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor
|
||||||
.jsr250(manager);
|
.jsr250(manager);
|
||||||
interceptor.setSecurityContextHolderStrategy(strategy);
|
interceptor.setSecurityContextHolderStrategy(strategy);
|
||||||
return interceptor;
|
return interceptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static <T> AuthorizationManager<T> manager(AuthorizationManager<T> jsr250, ObservationRegistry registry) {
|
|
||||||
if (registry.isNoop()) {
|
|
||||||
return jsr250;
|
|
||||||
}
|
|
||||||
return new ObservationAuthorizationManager<>(registry, jsr250);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ import org.springframework.security.access.expression.method.DefaultMethodSecuri
|
|||||||
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
||||||
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
||||||
import org.springframework.security.authorization.AuthorizationManager;
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
import org.springframework.security.authorization.ObservationAuthorizationManager;
|
|
||||||
import org.springframework.security.authorization.method.AuthorizationManagerAfterMethodInterceptor;
|
import org.springframework.security.authorization.method.AuthorizationManagerAfterMethodInterceptor;
|
||||||
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
||||||
import org.springframework.security.authorization.method.PostAuthorizeAuthorizationManager;
|
import org.springframework.security.authorization.method.PostAuthorizeAuthorizationManager;
|
||||||
@ -120,11 +119,7 @@ final class PrePostMethodSecurityConfiguration {
|
|||||||
|
|
||||||
static <T> AuthorizationManager<T> manager(AuthorizationManager<T> delegate,
|
static <T> AuthorizationManager<T> manager(AuthorizationManager<T> delegate,
|
||||||
ObjectProvider<ObservationRegistry> registryProvider) {
|
ObjectProvider<ObservationRegistry> registryProvider) {
|
||||||
ObservationRegistry registry = registryProvider.getIfAvailable(() -> ObservationRegistry.NOOP);
|
return new DeferringObservationAuthorizationManager<>(registryProvider, delegate);
|
||||||
if (registry.isNoop()) {
|
|
||||||
return delegate;
|
|
||||||
}
|
|
||||||
return new ObservationAuthorizationManager<>(registry, delegate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.context.annotation.Role;
|
import org.springframework.context.annotation.Role;
|
||||||
import org.springframework.security.access.annotation.Secured;
|
import org.springframework.security.access.annotation.Secured;
|
||||||
import org.springframework.security.authorization.AuthorizationManager;
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
import org.springframework.security.authorization.ObservationAuthorizationManager;
|
|
||||||
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
||||||
import org.springframework.security.authorization.method.SecuredAuthorizationManager;
|
import org.springframework.security.authorization.method.SecuredAuthorizationManager;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
@ -52,19 +51,12 @@ final class SecuredMethodSecurityConfiguration {
|
|||||||
SecuredAuthorizationManager secured = new SecuredAuthorizationManager();
|
SecuredAuthorizationManager secured = new SecuredAuthorizationManager();
|
||||||
SecurityContextHolderStrategy strategy = strategyProvider
|
SecurityContextHolderStrategy strategy = strategyProvider
|
||||||
.getIfAvailable(SecurityContextHolder::getContextHolderStrategy);
|
.getIfAvailable(SecurityContextHolder::getContextHolderStrategy);
|
||||||
ObservationRegistry registry = registryProvider.getIfAvailable(() -> ObservationRegistry.NOOP);
|
AuthorizationManager<MethodInvocation> manager = new DeferringObservationAuthorizationManager<>(
|
||||||
AuthorizationManager<MethodInvocation> manager = manager(secured, registry);
|
registryProvider, secured);
|
||||||
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor
|
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor
|
||||||
.secured(manager);
|
.secured(manager);
|
||||||
interceptor.setSecurityContextHolderStrategy(strategy);
|
interceptor.setSecurityContextHolderStrategy(strategy);
|
||||||
return interceptor;
|
return interceptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static <T> AuthorizationManager<T> manager(AuthorizationManager<T> jsr250, ObservationRegistry registry) {
|
|
||||||
if (registry.isNoop()) {
|
|
||||||
return jsr250;
|
|
||||||
}
|
|
||||||
return new ObservationAuthorizationManager<>(registry, jsr250);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user