|
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