Skip to content

Commit 8c61068

Browse files
committed
Instrument Authentication and Authorization
Closes gh-11989 Closes gh-11990
1 parent 827384e commit 8c61068

File tree

30 files changed

+1641
-130
lines changed

30 files changed

+1641
-130
lines changed

config/src/main/java/org/springframework/security/config/annotation/method/configuration/Jsr250MethodSecurityConfiguration.java

+22-17
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@
1616

1717
package org.springframework.security.config.annotation.method.configuration;
1818

19+
import io.micrometer.observation.ObservationRegistry;
20+
import org.aopalliance.intercept.MethodInvocation;
21+
1922
import org.springframework.aop.Advisor;
20-
import org.springframework.beans.factory.annotation.Autowired;
23+
import org.springframework.beans.factory.ObjectProvider;
2124
import org.springframework.beans.factory.config.BeanDefinition;
2225
import org.springframework.context.annotation.Bean;
2326
import org.springframework.context.annotation.Configuration;
2427
import org.springframework.context.annotation.Role;
28+
import org.springframework.security.authorization.AuthorizationManager;
29+
import org.springframework.security.authorization.ObservationAuthorizationManager;
2530
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
2631
import org.springframework.security.authorization.method.Jsr250AuthorizationManager;
2732
import org.springframework.security.config.core.GrantedAuthorityDefaults;
@@ -40,28 +45,28 @@
4045
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
4146
final class Jsr250MethodSecurityConfiguration {
4247

43-
private final Jsr250AuthorizationManager jsr250AuthorizationManager = new Jsr250AuthorizationManager();
44-
45-
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
46-
.getContextHolderStrategy();
47-
4848
@Bean
4949
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
50-
Advisor jsr250AuthorizationMethodInterceptor() {
50+
static Advisor jsr250AuthorizationMethodInterceptor(ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
51+
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
52+
ObjectProvider<ObservationRegistry> registryProvider) {
53+
Jsr250AuthorizationManager jsr250 = new Jsr250AuthorizationManager();
54+
defaultsProvider.ifAvailable((d) -> jsr250.setRolePrefix(d.getRolePrefix()));
55+
SecurityContextHolderStrategy strategy = strategyProvider
56+
.getIfAvailable(SecurityContextHolder::getContextHolderStrategy);
57+
ObservationRegistry registry = registryProvider.getIfAvailable(() -> ObservationRegistry.NOOP);
58+
AuthorizationManager<MethodInvocation> manager = manager(jsr250, registry);
5159
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor
52-
.jsr250(this.jsr250AuthorizationManager);
53-
interceptor.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
60+
.jsr250(manager);
61+
interceptor.setSecurityContextHolderStrategy(strategy);
5462
return interceptor;
5563
}
5664

57-
@Autowired(required = false)
58-
void setGrantedAuthorityDefaults(GrantedAuthorityDefaults grantedAuthorityDefaults) {
59-
this.jsr250AuthorizationManager.setRolePrefix(grantedAuthorityDefaults.getRolePrefix());
60-
}
61-
62-
@Autowired(required = false)
63-
void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
64-
this.securityContextHolderStrategy = securityContextHolderStrategy;
65+
static <T> AuthorizationManager<T> manager(AuthorizationManager<T> jsr250, ObservationRegistry registry) {
66+
if (registry.isNoop()) {
67+
return jsr250;
68+
}
69+
return new ObservationAuthorizationManager<>(registry, jsr250);
6570
}
6671

6772
}

config/src/main/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfiguration.java

+61-63
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616

1717
package org.springframework.security.config.annotation.method.configuration;
1818

19+
import io.micrometer.observation.ObservationRegistry;
20+
1921
import org.springframework.aop.Advisor;
20-
import org.springframework.beans.factory.annotation.Autowired;
22+
import org.springframework.beans.factory.ObjectProvider;
2123
import org.springframework.beans.factory.config.BeanDefinition;
2224
import org.springframework.context.ApplicationContext;
2325
import org.springframework.context.annotation.Bean;
@@ -26,7 +28,8 @@
2628
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
2729
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
2830
import org.springframework.security.authorization.AuthorizationEventPublisher;
29-
import org.springframework.security.authorization.SpringAuthorizationEventPublisher;
31+
import org.springframework.security.authorization.AuthorizationManager;
32+
import org.springframework.security.authorization.ObservationAuthorizationManager;
3033
import org.springframework.security.authorization.method.AuthorizationManagerAfterMethodInterceptor;
3134
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
3235
import org.springframework.security.authorization.method.PostAuthorizeAuthorizationManager;
@@ -48,85 +51,80 @@
4851
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
4952
final class PrePostMethodSecurityConfiguration {
5053

51-
private final PreFilterAuthorizationMethodInterceptor preFilterAuthorizationMethodInterceptor = new PreFilterAuthorizationMethodInterceptor();
52-
53-
private final AuthorizationManagerBeforeMethodInterceptor preAuthorizeAuthorizationMethodInterceptor;
54-
55-
private final PreAuthorizeAuthorizationManager preAuthorizeAuthorizationManager = new PreAuthorizeAuthorizationManager();
56-
57-
private final AuthorizationManagerAfterMethodInterceptor postAuthorizeAuthorizaitonMethodInterceptor;
58-
59-
private final PostAuthorizeAuthorizationManager postAuthorizeAuthorizationManager = new PostAuthorizeAuthorizationManager();
60-
61-
private final PostFilterAuthorizationMethodInterceptor postFilterAuthorizationMethodInterceptor = new PostFilterAuthorizationMethodInterceptor();
62-
63-
private final DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
64-
65-
@Autowired
66-
PrePostMethodSecurityConfiguration(ApplicationContext context) {
67-
this.preAuthorizeAuthorizationManager.setExpressionHandler(this.expressionHandler);
68-
this.preAuthorizeAuthorizationMethodInterceptor = AuthorizationManagerBeforeMethodInterceptor
69-
.preAuthorize(this.preAuthorizeAuthorizationManager);
70-
this.postAuthorizeAuthorizationManager.setExpressionHandler(this.expressionHandler);
71-
this.postAuthorizeAuthorizaitonMethodInterceptor = AuthorizationManagerAfterMethodInterceptor
72-
.postAuthorize(this.postAuthorizeAuthorizationManager);
73-
this.preFilterAuthorizationMethodInterceptor.setExpressionHandler(this.expressionHandler);
74-
this.postFilterAuthorizationMethodInterceptor.setExpressionHandler(this.expressionHandler);
75-
this.expressionHandler.setApplicationContext(context);
76-
AuthorizationEventPublisher publisher = new SpringAuthorizationEventPublisher(context);
77-
this.preAuthorizeAuthorizationMethodInterceptor.setAuthorizationEventPublisher(publisher);
78-
this.postAuthorizeAuthorizaitonMethodInterceptor.setAuthorizationEventPublisher(publisher);
79-
}
80-
8154
@Bean
8255
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
83-
Advisor preFilterAuthorizationMethodInterceptor() {
84-
return this.preFilterAuthorizationMethodInterceptor;
56+
static Advisor preFilterAuthorizationMethodInterceptor(ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
57+
ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
58+
ObjectProvider<SecurityContextHolderStrategy> strategyProvider, ApplicationContext context) {
59+
PreFilterAuthorizationMethodInterceptor preFilter = new PreFilterAuthorizationMethodInterceptor();
60+
strategyProvider.ifAvailable(preFilter::setSecurityContextHolderStrategy);
61+
preFilter.setExpressionHandler(
62+
expressionHandlerProvider.getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, context)));
63+
return preFilter;
8564
}
8665

8766
@Bean
8867
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
89-
Advisor preAuthorizeAuthorizationMethodInterceptor() {
90-
return this.preAuthorizeAuthorizationMethodInterceptor;
68+
static Advisor preAuthorizeAuthorizationMethodInterceptor(ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
69+
ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
70+
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
71+
ObjectProvider<AuthorizationEventPublisher> eventPublisherProvider,
72+
ObjectProvider<ObservationRegistry> registryProvider, ApplicationContext context) {
73+
PreAuthorizeAuthorizationManager manager = new PreAuthorizeAuthorizationManager();
74+
manager.setExpressionHandler(
75+
expressionHandlerProvider.getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, context)));
76+
AuthorizationManagerBeforeMethodInterceptor preAuthorize = AuthorizationManagerBeforeMethodInterceptor
77+
.preAuthorize(manager(manager, registryProvider));
78+
strategyProvider.ifAvailable(preAuthorize::setSecurityContextHolderStrategy);
79+
eventPublisherProvider.ifAvailable(preAuthorize::setAuthorizationEventPublisher);
80+
return preAuthorize;
9181
}
9282

9383
@Bean
9484
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
95-
Advisor postAuthorizeAuthorizationMethodInterceptor() {
96-
return this.postAuthorizeAuthorizaitonMethodInterceptor;
85+
static Advisor postAuthorizeAuthorizationMethodInterceptor(
86+
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
87+
ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
88+
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
89+
ObjectProvider<AuthorizationEventPublisher> eventPublisherProvider,
90+
ObjectProvider<ObservationRegistry> registryProvider, ApplicationContext context) {
91+
PostAuthorizeAuthorizationManager manager = new PostAuthorizeAuthorizationManager();
92+
manager.setExpressionHandler(
93+
expressionHandlerProvider.getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, context)));
94+
AuthorizationManagerAfterMethodInterceptor postAuthorize = AuthorizationManagerAfterMethodInterceptor
95+
.postAuthorize(manager(manager, registryProvider));
96+
strategyProvider.ifAvailable(postAuthorize::setSecurityContextHolderStrategy);
97+
eventPublisherProvider.ifAvailable(postAuthorize::setAuthorizationEventPublisher);
98+
return postAuthorize;
9799
}
98100

99101
@Bean
100102
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
101-
Advisor postFilterAuthorizationMethodInterceptor() {
102-
return this.postFilterAuthorizationMethodInterceptor;
103-
}
104-
105-
@Autowired(required = false)
106-
void setMethodSecurityExpressionHandler(MethodSecurityExpressionHandler methodSecurityExpressionHandler) {
107-
this.preFilterAuthorizationMethodInterceptor.setExpressionHandler(methodSecurityExpressionHandler);
108-
this.preAuthorizeAuthorizationManager.setExpressionHandler(methodSecurityExpressionHandler);
109-
this.postAuthorizeAuthorizationManager.setExpressionHandler(methodSecurityExpressionHandler);
110-
this.postFilterAuthorizationMethodInterceptor.setExpressionHandler(methodSecurityExpressionHandler);
111-
}
112-
113-
@Autowired(required = false)
114-
void setSecurityContextHolderStrategy(SecurityContextHolderStrategy strategy) {
115-
this.preFilterAuthorizationMethodInterceptor.setSecurityContextHolderStrategy(strategy);
116-
this.preAuthorizeAuthorizationMethodInterceptor.setSecurityContextHolderStrategy(strategy);
117-
this.postAuthorizeAuthorizaitonMethodInterceptor.setSecurityContextHolderStrategy(strategy);
118-
this.postFilterAuthorizationMethodInterceptor.setSecurityContextHolderStrategy(strategy);
103+
static Advisor postFilterAuthorizationMethodInterceptor(ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
104+
ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
105+
ObjectProvider<SecurityContextHolderStrategy> strategyProvider, ApplicationContext context) {
106+
PostFilterAuthorizationMethodInterceptor postFilter = new PostFilterAuthorizationMethodInterceptor();
107+
strategyProvider.ifAvailable(postFilter::setSecurityContextHolderStrategy);
108+
postFilter.setExpressionHandler(
109+
expressionHandlerProvider.getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, context)));
110+
return postFilter;
119111
}
120112

121-
@Autowired(required = false)
122-
void setGrantedAuthorityDefaults(GrantedAuthorityDefaults grantedAuthorityDefaults) {
123-
this.expressionHandler.setDefaultRolePrefix(grantedAuthorityDefaults.getRolePrefix());
113+
private static MethodSecurityExpressionHandler defaultExpressionHandler(
114+
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider, ApplicationContext context) {
115+
DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
116+
defaultsProvider.ifAvailable((d) -> handler.setDefaultRolePrefix(d.getRolePrefix()));
117+
handler.setApplicationContext(context);
118+
return handler;
124119
}
125120

126-
@Autowired(required = false)
127-
void setAuthorizationEventPublisher(AuthorizationEventPublisher eventPublisher) {
128-
this.preAuthorizeAuthorizationMethodInterceptor.setAuthorizationEventPublisher(eventPublisher);
129-
this.postAuthorizeAuthorizaitonMethodInterceptor.setAuthorizationEventPublisher(eventPublisher);
121+
static <T> AuthorizationManager<T> manager(AuthorizationManager<T> delegate,
122+
ObjectProvider<ObservationRegistry> registryProvider) {
123+
ObservationRegistry registry = registryProvider.getIfAvailable(() -> ObservationRegistry.NOOP);
124+
if (registry.isNoop()) {
125+
return delegate;
126+
}
127+
return new ObservationAuthorizationManager<>(registry, delegate);
130128
}
131129

132130
}

config/src/main/java/org/springframework/security/config/annotation/method/configuration/ReactiveAuthorizationManagerMethodSecurityConfiguration.java

+27-11
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616

1717
package org.springframework.security.config.annotation.method.configuration;
1818

19+
import io.micrometer.observation.ObservationRegistry;
20+
import org.aopalliance.intercept.MethodInvocation;
21+
22+
import org.springframework.beans.factory.ObjectProvider;
1923
import org.springframework.beans.factory.annotation.Autowired;
2024
import org.springframework.beans.factory.config.BeanDefinition;
2125
import org.springframework.context.annotation.Bean;
@@ -24,8 +28,11 @@
2428
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
2529
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
2630
import org.springframework.security.authentication.ReactiveAuthenticationManager;
31+
import org.springframework.security.authorization.ObservationReactiveAuthorizationManager;
32+
import org.springframework.security.authorization.ReactiveAuthorizationManager;
2733
import org.springframework.security.authorization.method.AuthorizationManagerAfterReactiveMethodInterceptor;
2834
import org.springframework.security.authorization.method.AuthorizationManagerBeforeReactiveMethodInterceptor;
35+
import org.springframework.security.authorization.method.MethodInvocationResult;
2936
import org.springframework.security.authorization.method.PostAuthorizeReactiveAuthorizationManager;
3037
import org.springframework.security.authorization.method.PostFilterAuthorizationReactiveMethodInterceptor;
3138
import org.springframework.security.authorization.method.PreAuthorizeReactiveAuthorizationManager;
@@ -43,39 +50,39 @@ final class ReactiveAuthorizationManagerMethodSecurityConfiguration {
4350

4451
@Bean
4552
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
46-
PreFilterAuthorizationReactiveMethodInterceptor preFilterInterceptor(
53+
static PreFilterAuthorizationReactiveMethodInterceptor preFilterInterceptor(
4754
MethodSecurityExpressionHandler expressionHandler) {
4855
return new PreFilterAuthorizationReactiveMethodInterceptor(expressionHandler);
4956
}
5057

5158
@Bean
5259
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
53-
AuthorizationManagerBeforeReactiveMethodInterceptor preAuthorizeInterceptor(
54-
MethodSecurityExpressionHandler expressionHandler) {
55-
PreAuthorizeReactiveAuthorizationManager authorizationManager = new PreAuthorizeReactiveAuthorizationManager(
56-
expressionHandler);
60+
static AuthorizationManagerBeforeReactiveMethodInterceptor preAuthorizeInterceptor(
61+
MethodSecurityExpressionHandler expressionHandler, ObjectProvider<ObservationRegistry> registryProvider) {
62+
ReactiveAuthorizationManager<MethodInvocation> authorizationManager = manager(
63+
new PreAuthorizeReactiveAuthorizationManager(expressionHandler), registryProvider);
5764
return AuthorizationManagerBeforeReactiveMethodInterceptor.preAuthorize(authorizationManager);
5865
}
5966

6067
@Bean
6168
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
62-
PostFilterAuthorizationReactiveMethodInterceptor postFilterInterceptor(
69+
static PostFilterAuthorizationReactiveMethodInterceptor postFilterInterceptor(
6370
MethodSecurityExpressionHandler expressionHandler) {
6471
return new PostFilterAuthorizationReactiveMethodInterceptor(expressionHandler);
6572
}
6673

6774
@Bean
6875
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
69-
AuthorizationManagerAfterReactiveMethodInterceptor postAuthorizeInterceptor(
70-
MethodSecurityExpressionHandler expressionHandler) {
71-
PostAuthorizeReactiveAuthorizationManager authorizationManager = new PostAuthorizeReactiveAuthorizationManager(
72-
expressionHandler);
76+
static AuthorizationManagerAfterReactiveMethodInterceptor postAuthorizeInterceptor(
77+
MethodSecurityExpressionHandler expressionHandler, ObjectProvider<ObservationRegistry> registryProvider) {
78+
ReactiveAuthorizationManager<MethodInvocationResult> authorizationManager = manager(
79+
new PostAuthorizeReactiveAuthorizationManager(expressionHandler), registryProvider);
7380
return AuthorizationManagerAfterReactiveMethodInterceptor.postAuthorize(authorizationManager);
7481
}
7582

7683
@Bean
7784
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
78-
DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler(
85+
static DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler(
7986
@Autowired(required = false) GrantedAuthorityDefaults grantedAuthorityDefaults) {
8087
DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
8188
if (grantedAuthorityDefaults != null) {
@@ -84,4 +91,13 @@ DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler(
8491
return handler;
8592
}
8693

94+
static <T> ReactiveAuthorizationManager<T> manager(ReactiveAuthorizationManager<T> delegate,
95+
ObjectProvider<ObservationRegistry> registryProvider) {
96+
ObservationRegistry registry = registryProvider.getIfAvailable(() -> ObservationRegistry.NOOP);
97+
if (registry.isNoop()) {
98+
return delegate;
99+
}
100+
return new ObservationReactiveAuthorizationManager<>(registry, delegate);
101+
}
102+
87103
}

0 commit comments

Comments
 (0)