|
16 | 16 |
|
17 | 17 | package org.springframework.security.config.annotation.method.configuration;
|
18 | 18 |
|
| 19 | +import java.util.function.Supplier; |
| 20 | + |
19 | 21 | import io.micrometer.observation.ObservationRegistry;
|
20 | 22 | import org.aopalliance.intercept.MethodInterceptor;
|
21 | 23 | import org.aopalliance.intercept.MethodInvocation;
|
22 | 24 |
|
| 25 | +import org.springframework.aop.Pointcut; |
23 | 26 | import org.springframework.aop.framework.AopInfrastructureBean;
|
24 | 27 | import org.springframework.beans.factory.ObjectProvider;
|
| 28 | +import org.springframework.beans.factory.annotation.Autowired; |
25 | 29 | import org.springframework.beans.factory.config.BeanDefinition;
|
26 | 30 | import org.springframework.context.annotation.Bean;
|
27 | 31 | import org.springframework.context.annotation.Configuration;
|
28 | 32 | import org.springframework.context.annotation.ImportAware;
|
29 | 33 | import org.springframework.context.annotation.Role;
|
30 | 34 | import org.springframework.core.type.AnnotationMetadata;
|
31 |
| -import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy; |
32 | 35 | import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
33 | 36 | import org.springframework.security.authorization.AuthoritiesAuthorizationManager;
|
34 | 37 | import org.springframework.security.authorization.AuthorizationEventPublisher;
|
35 | 38 | import org.springframework.security.authorization.AuthorizationManager;
|
| 39 | +import org.springframework.security.authorization.ObservationAuthorizationManager; |
36 | 40 | import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
37 | 41 | import org.springframework.security.authorization.method.Jsr250AuthorizationManager;
|
38 | 42 | import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
39 |
| -import org.springframework.security.core.context.SecurityContextHolder; |
40 | 43 | import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
41 | 44 |
|
42 | 45 | /**
|
|
47 | 50 | * @since 5.6
|
48 | 51 | * @see EnableMethodSecurity
|
49 | 52 | */
|
50 |
| -@Configuration(proxyBeanMethods = false) |
| 53 | +@Configuration(value = "_jsr250MethodSecurityConfiguration", proxyBeanMethods = false) |
51 | 54 | @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
52 | 55 | final class Jsr250MethodSecurityConfiguration implements ImportAware, AopInfrastructureBean {
|
53 | 56 |
|
54 |
| - private int interceptorOrderOffset; |
| 57 | + private static final Pointcut pointcut = AuthorizationManagerBeforeMethodInterceptor.jsr250().getPointcut(); |
| 58 | + |
| 59 | + private final Jsr250AuthorizationManager authorizationManager = new Jsr250AuthorizationManager(); |
| 60 | + |
| 61 | + private AuthorizationManagerBeforeMethodInterceptor methodInterceptor = AuthorizationManagerBeforeMethodInterceptor |
| 62 | + .jsr250(this.authorizationManager); |
55 | 63 |
|
56 | 64 | @Bean
|
57 | 65 | @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
58 | 66 | static MethodInterceptor jsr250AuthorizationMethodInterceptor(
|
59 |
| - ObjectProvider<GrantedAuthorityDefaults> defaultsProvider, |
60 |
| - ObjectProvider<SecurityContextHolderStrategy> strategyProvider, |
61 |
| - ObjectProvider<AuthorizationEventPublisher> eventPublisherProvider, |
62 |
| - ObjectProvider<ObservationRegistry> registryProvider, ObjectProvider<RoleHierarchy> roleHierarchyProvider, |
63 |
| - Jsr250MethodSecurityConfiguration configuration) { |
64 |
| - Jsr250AuthorizationManager jsr250 = new Jsr250AuthorizationManager(); |
65 |
| - AuthoritiesAuthorizationManager authoritiesAuthorizationManager = new AuthoritiesAuthorizationManager(); |
66 |
| - RoleHierarchy roleHierarchy = roleHierarchyProvider.getIfAvailable(NullRoleHierarchy::new); |
67 |
| - authoritiesAuthorizationManager.setRoleHierarchy(roleHierarchy); |
68 |
| - jsr250.setAuthoritiesAuthorizationManager(authoritiesAuthorizationManager); |
69 |
| - defaultsProvider.ifAvailable((d) -> jsr250.setRolePrefix(d.getRolePrefix())); |
70 |
| - SecurityContextHolderStrategy strategy = strategyProvider |
71 |
| - .getIfAvailable(SecurityContextHolder::getContextHolderStrategy); |
72 |
| - AuthorizationManager<MethodInvocation> manager = new DeferringObservationAuthorizationManager<>( |
73 |
| - registryProvider, jsr250); |
74 |
| - AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor |
75 |
| - .jsr250(manager); |
76 |
| - interceptor.setOrder(interceptor.getOrder() + configuration.interceptorOrderOffset); |
77 |
| - interceptor.setSecurityContextHolderStrategy(strategy); |
78 |
| - eventPublisherProvider.ifAvailable(interceptor::setAuthorizationEventPublisher); |
79 |
| - return interceptor; |
| 67 | + ObjectProvider<Jsr250MethodSecurityConfiguration> _jsr250MethodSecurityConfiguration) { |
| 68 | + Supplier<AuthorizationManagerBeforeMethodInterceptor> supplier = () -> { |
| 69 | + Jsr250MethodSecurityConfiguration configuration = _jsr250MethodSecurityConfiguration.getObject(); |
| 70 | + return configuration.methodInterceptor; |
| 71 | + }; |
| 72 | + return new DeferringMethodInterceptor<>(pointcut, supplier); |
80 | 73 | }
|
81 | 74 |
|
82 | 75 | @Override
|
83 | 76 | public void setImportMetadata(AnnotationMetadata importMetadata) {
|
84 | 77 | EnableMethodSecurity annotation = importMetadata.getAnnotations().get(EnableMethodSecurity.class).synthesize();
|
85 |
| - this.interceptorOrderOffset = annotation.offset(); |
| 78 | + this.methodInterceptor.setOrder(this.methodInterceptor.getOrder() + annotation.offset()); |
| 79 | + } |
| 80 | + |
| 81 | + @Autowired(required = false) |
| 82 | + void setGrantedAuthorityDefaults(GrantedAuthorityDefaults defaults) { |
| 83 | + this.authorizationManager.setRolePrefix(defaults.getRolePrefix()); |
| 84 | + } |
| 85 | + |
| 86 | + @Autowired(required = false) |
| 87 | + void setRoleHierarchy(RoleHierarchy roleHierarchy) { |
| 88 | + AuthoritiesAuthorizationManager authoritiesAuthorizationManager = new AuthoritiesAuthorizationManager(); |
| 89 | + authoritiesAuthorizationManager.setRoleHierarchy(roleHierarchy); |
| 90 | + this.authorizationManager.setAuthoritiesAuthorizationManager(authoritiesAuthorizationManager); |
| 91 | + } |
| 92 | + |
| 93 | + @Autowired(required = false) |
| 94 | + void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) { |
| 95 | + this.methodInterceptor.setSecurityContextHolderStrategy(securityContextHolderStrategy); |
| 96 | + } |
| 97 | + |
| 98 | + @Autowired(required = false) |
| 99 | + void setObservationRegistry(ObservationRegistry registry) { |
| 100 | + if (registry.isNoop()) { |
| 101 | + return; |
| 102 | + } |
| 103 | + AuthorizationManager<MethodInvocation> observed = new ObservationAuthorizationManager<>(registry, |
| 104 | + this.authorizationManager); |
| 105 | + this.methodInterceptor = AuthorizationManagerBeforeMethodInterceptor.secured(observed); |
| 106 | + } |
| 107 | + |
| 108 | + @Autowired(required = false) |
| 109 | + void setEventPublisher(AuthorizationEventPublisher eventPublisher) { |
| 110 | + this.methodInterceptor.setAuthorizationEventPublisher(eventPublisher); |
86 | 111 | }
|
87 | 112 |
|
88 | 113 | }
|
0 commit comments