mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-10 12:23:30 +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.Role;
|
||||
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.Jsr250AuthorizationManager;
|
||||
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
||||
@ -54,19 +53,12 @@ final class Jsr250MethodSecurityConfiguration {
|
||||
defaultsProvider.ifAvailable((d) -> jsr250.setRolePrefix(d.getRolePrefix()));
|
||||
SecurityContextHolderStrategy strategy = strategyProvider
|
||||
.getIfAvailable(SecurityContextHolder::getContextHolderStrategy);
|
||||
ObservationRegistry registry = registryProvider.getIfAvailable(() -> ObservationRegistry.NOOP);
|
||||
AuthorizationManager<MethodInvocation> manager = manager(jsr250, registry);
|
||||
AuthorizationManager<MethodInvocation> manager = new DeferringObservationAuthorizationManager<>(
|
||||
registryProvider, jsr250);
|
||||
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor
|
||||
.jsr250(manager);
|
||||
interceptor.setSecurityContextHolderStrategy(strategy);
|
||||
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.authorization.AuthorizationEventPublisher;
|
||||
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.AuthorizationManagerBeforeMethodInterceptor;
|
||||
import org.springframework.security.authorization.method.PostAuthorizeAuthorizationManager;
|
||||
@ -120,11 +119,7 @@ final class PrePostMethodSecurityConfiguration {
|
||||
|
||||
static <T> AuthorizationManager<T> manager(AuthorizationManager<T> delegate,
|
||||
ObjectProvider<ObservationRegistry> registryProvider) {
|
||||
ObservationRegistry registry = registryProvider.getIfAvailable(() -> ObservationRegistry.NOOP);
|
||||
if (registry.isNoop()) {
|
||||
return delegate;
|
||||
}
|
||||
return new ObservationAuthorizationManager<>(registry, delegate);
|
||||
return new DeferringObservationAuthorizationManager<>(registryProvider, delegate);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Role;
|
||||
import org.springframework.security.access.annotation.Secured;
|
||||
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.SecuredAuthorizationManager;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
@ -52,19 +51,12 @@ final class SecuredMethodSecurityConfiguration {
|
||||
SecuredAuthorizationManager secured = new SecuredAuthorizationManager();
|
||||
SecurityContextHolderStrategy strategy = strategyProvider
|
||||
.getIfAvailable(SecurityContextHolder::getContextHolderStrategy);
|
||||
ObservationRegistry registry = registryProvider.getIfAvailable(() -> ObservationRegistry.NOOP);
|
||||
AuthorizationManager<MethodInvocation> manager = manager(secured, registry);
|
||||
AuthorizationManager<MethodInvocation> manager = new DeferringObservationAuthorizationManager<>(
|
||||
registryProvider, secured);
|
||||
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor
|
||||
.secured(manager);
|
||||
interceptor.setSecurityContextHolderStrategy(strategy);
|
||||
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