Skip to content

Commit

Permalink
Adopt EnableMethodSecurity for custom PermissionEvaluator sample #115 (
Browse files Browse the repository at this point in the history
…#118)

* Adopt EnableMethodSecurity for custom PermissionEvaluator sample #115

* Spotless apply

* Add a section on Configure method security for Permission evaluator

* Expand the link text

* Fix imports
  • Loading branch information
timtebeek authored Jul 19, 2022
1 parent 5f75142 commit f10ebe6
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 5 deletions.
31 changes: 30 additions & 1 deletion permission-evaluator/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,36 @@ We've provided an `CustomPermissionEvaluator` implementation to serve as an exam
It first checks the target domain object type, before calling out to the appropriate permission store to check for access.
The access rules here are modeled quite simply, but you can extend this as much as needed for your domain.

Lastly, the `@PreAuthorize` annotations need to be activated through `@EnableGlobalMethodSecurity(prePostEnabled = true)`, which is done in `PermissionEvaluatorConfiguration`.
=== Configure method security
Lastly, the `@PreAuthorize` annotations need to be activated, which we will do in `PermissionEvaluatorConfiguration`.

At present, we could only annotate `PermissionEvaluatorConfiguration` with `@EnableGlobalMethodSecurity(prePostEnabled = true)` to protect our methods annotated with `@PreAuthorize`.
That works and we would be done, but there's a slight catch related to more https://docs.spring.io/spring-security/reference/5.7.2/servlet/authorization/method-security.html#_enablemethodsecurity[recent developments around `@EnableMethodSecurity`].
The documentation lists some of the benefits of using `EnableMethodSecurity` over `EnableGlobalMethodSecurity`.

We need to add the following configuration to wire up our custom permission evaluator.

.PermissionEvaluatorConfiguration.java
[source,java]
----
@Configuration
@EnableMethodSecurity(prePostEnabled = false)
class PermissionEvaluatorConfiguration {
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
Advisor preAuthorizeAuthorizationMethodInterceptor(CustomPermissionEvaluator customPermissionEvaluator) {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(customPermissionEvaluator);
PreAuthorizeAuthorizationManager authorizationManager = new PreAuthorizeAuthorizationManager();
authorizationManager.setExpressionHandler(expressionHandler);
return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(authorizationManager);
}
}
----

=== Tests
Our `CustomPermissionEvaluatorIT` tests use mock users _Alice_ and _Bob_, with a malicious third user _Eve_, all trying to read and write a single spreadsheet.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
package com.jdriven;

import com.jdriven.permission.CustomPermissionEvaluator;

import org.springframework.aop.Advisor;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.context.annotation.Role;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
import org.springframework.security.authorization.method.PreAuthorizeAuthorizationManager;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class PermissionEvaluatorConfiguration {
// Annotations only
@EnableMethodSecurity(prePostEnabled = false)
class PermissionEvaluatorConfiguration {

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
Advisor preAuthorizeAuthorizationMethodInterceptor(CustomPermissionEvaluator customPermissionEvaluator) {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(customPermissionEvaluator);

PreAuthorizeAuthorizationManager authorizationManager = new PreAuthorizeAuthorizationManager();
authorizationManager.setExpressionHandler(expressionHandler);

return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(authorizationManager);
}

}

0 comments on commit f10ebe6

Please sign in to comment.