Skip to content

Commit 8363261

Browse files
committed
Support custom MethodSecurityExpressionHandler
Closes gh-15715
1 parent add5c56 commit 8363261

File tree

4 files changed

+50
-0
lines changed

4 files changed

+50
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.springframework.context.ApplicationContext;
3535
import org.springframework.context.annotation.Bean;
3636
import org.springframework.context.annotation.Configuration;
37+
import org.springframework.context.annotation.Fallback;
3738
import org.springframework.context.annotation.Role;
3839
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
3940
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
@@ -114,6 +115,7 @@ static MethodInterceptor postAuthorizeAuthorizationMethodInterceptor(
114115

115116
@Bean
116117
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
118+
@Fallback
117119
static DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler(
118120
@Autowired(required = false) GrantedAuthorityDefaults grantedAuthorityDefaults) {
119121
DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();

config/src/test/java/org/springframework/security/config/annotation/method/configuration/PrePostReactiveMethodSecurityConfigurationTests.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,21 @@
1616

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

19+
import java.io.Serializable;
20+
1921
import org.junit.jupiter.api.Test;
2022
import org.junit.jupiter.api.extension.ExtendWith;
2123
import reactor.test.StepVerifier;
2224

25+
import org.springframework.beans.factory.config.BeanDefinition;
2326
import org.springframework.context.annotation.Bean;
2427
import org.springframework.context.annotation.Configuration;
28+
import org.springframework.context.annotation.Role;
29+
import org.springframework.security.access.PermissionEvaluator;
30+
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
2531
import org.springframework.security.config.test.SpringTestContext;
2632
import org.springframework.security.config.test.SpringTestContextExtension;
33+
import org.springframework.security.core.Authentication;
2734
import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners;
2835
import org.springframework.security.test.context.support.WithMockUser;
2936
import org.springframework.test.context.junit.jupiter.SpringExtension;
@@ -201,6 +208,14 @@ void preAuthorizeWhenAllowedAndHandlerWithCustomAnnotationUsingBeanThenInvokeMet
201208
StepVerifier.create(service.preAuthorizeWithMaskAnnotationUsingBean()).expectNext("ok").verifyComplete();
202209
}
203210

211+
@Test
212+
@WithMockUser(roles = "ADMIN")
213+
public void customMethodSecurityExpressionHandler() {
214+
this.spring.register(MethodSecurityServiceEnabledConfig.class, PermissionEvaluatorConfig.class).autowire();
215+
ReactiveMethodSecurityService service = this.spring.getContext().getBean(ReactiveMethodSecurityService.class);
216+
StepVerifier.create(service.preAuthorizeHasPermission("Hello")).expectNext("ok").verifyComplete();
217+
}
218+
204219
@Configuration
205220
@EnableReactiveMethodSecurity
206221
static class MethodSecurityServiceEnabledConfig {
@@ -212,4 +227,29 @@ ReactiveMethodSecurityService methodSecurityService() {
212227

213228
}
214229

230+
@Configuration
231+
static class PermissionEvaluatorConfig {
232+
233+
@Bean
234+
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
235+
static DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler() {
236+
DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
237+
handler.setPermissionEvaluator(new PermissionEvaluator() {
238+
@Override
239+
public boolean hasPermission(Authentication authentication, Object targetDomainObject,
240+
Object permission) {
241+
return true;
242+
}
243+
244+
@Override
245+
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
246+
Object permission) {
247+
return true;
248+
}
249+
});
250+
return handler;
251+
}
252+
253+
}
254+
215255
}

config/src/test/java/org/springframework/security/config/annotation/method/configuration/ReactiveMethodSecurityService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ public interface ReactiveMethodSecurityService {
101101
@HandleAuthorizationDenied(handlerClass = MethodAuthorizationDeniedHandler.class)
102102
Mono<String> checkCustomResult(boolean result);
103103

104+
@PreAuthorize("hasPermission('#kgName', 'read')")
105+
Mono<String> preAuthorizeHasPermission(String kgName);
106+
104107
class StarMaskingHandler implements MethodAuthorizationDeniedHandler {
105108

106109
@Override

config/src/test/java/org/springframework/security/config/annotation/method/configuration/ReactiveMethodSecurityServiceImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,9 @@ public Mono<String> checkCustomResult(boolean result) {
8888
return Mono.just("ok");
8989
}
9090

91+
@Override
92+
public Mono<String> preAuthorizeHasPermission(String kgName) {
93+
return Mono.just("ok");
94+
}
95+
9196
}

0 commit comments

Comments
 (0)