Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow the customization of the Reactive Method Security MethodSecurityExpressionHandler #7459

Closed
Tracked by #14595
codependent opened this issue Sep 19, 2019 · 7 comments
Assignees
Labels
in: core An issue in spring-security-core status: duplicate A duplicate of another issue type: enhancement A general enhancement
Milestone

Comments

@codependent
Copy link

codependent commented Sep 19, 2019

Summary

I need to customize the behavior of the reactive method security expression handler. In the non reactive version this could be done extending GlobalMethodSecurityConfiguration as stated in the documentation:

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        // ... create and return custom MethodSecurityExpressionHandler ...
        return expressionHandler;
    }
}

However, the reactive equivalent ReactiveMethodSecurityConfiguration is a package-private class and can't be extended to modify the framework.

Actual Behavior

We can't modify the expression handler.

Expected Behavior

Allow the definition of a custom MethodSecurityExpressionHandler

Configuration

...

Version

5.2.0.RC1

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 19, 2019
@jnfeinstein
Copy link

The reactive version is bean-based. Is this as simple as adding a conditional?

@sunildabburi
Copy link

I had a similar problem. I tried this approach and it worked.

Create the following configuration class that initializes the required security beans along with my custom expression handler bean.

class AuthorizationConfig {

    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    DelegatingMethodSecurityMetadataSource methodMetadataSource(
            MethodSecurityExpressionHandler methodSecurityExpressionHandler) {
        var attributeFactory = new ExpressionBasedAnnotationAttributeFactory(methodSecurityExpressionHandler);
        var prePostSource = new PrePostAnnotationSecurityMetadataSource(attributeFactory);
        return new DelegatingMethodSecurityMetadataSource(List.of(prePostSource));
    }

    @Bean
    PrePostAdviceReactiveMethodInterceptor securityMethodInterceptor(AbstractMethodSecurityMetadataSource source,
            MethodSecurityExpressionHandler handler) {
        var postAdvice = new ExpressionBasedPostInvocationAdvice(handler);
        var preAdvice = new ExpressionBasedPreInvocationAdvice();
        preAdvice.setExpressionHandler(handler);
        return new PrePostAdviceReactiveMethodInterceptor(source, preAdvice, postAdvice);
    }

    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    MethodSecurityMetadataSourceAdvisor methodSecurityInterceptor(AbstractMethodSecurityMetadataSource source) {
        return new MethodSecurityMetadataSourceAdvisor("securityMethodInterceptor", source,
                "methodMetadataSource");
    }

    @Bean
    MethodSecurityExpressionHandler methodSecurityExpressionHandler() {
        return new CustomMethodSecurityExpressionHandler(); // my custom expression handler
    }
}

DO NOT use @EnableReactiveMethodSecurity as the above code does what it does but not completely as the above implementation does not take into consideration the import order and default role prefixes which were not required in my case. If you want to use them too, you can clone the code from ReactiveMethodSecurityConfiguration

Hope this helps

@ssozonoff
Copy link

@bean
@primary
public DefaultMethodSecurityExpressionHandler getCustomMethodSecurityExpressionHandler() {
return new CustomMethodSecurityExpressionHandler();
}

Seems to work as well

@wickedev
Copy link

wickedev commented Jan 8, 2022

How about avoiding this problem by calling setRoleHierarchy inside ReactiveMethodSecurityConfiguration.methodSecurityExpressionHandler method or adding @ConditionalOnMissingBean annotation?

@jzheaux jzheaux added in: core An issue in spring-security-core type: enhancement A general enhancement status: blocked An issue that's blocked on an external project change and removed status: waiting-for-triage An issue we've not yet triaged labels Mar 31, 2022
@jzheaux
Copy link
Contributor

jzheaux commented Mar 31, 2022

Let's take a look at this after #9401 is merged.

@LajosPolya
Copy link

@bean @primary public DefaultMethodSecurityExpressionHandler getCustomMethodSecurityExpressionHandler() { return new CustomMethodSecurityExpressionHandler(); }

Seems to work as well

This worked for me but my CustomMethodSecurityExpressionHandler class has to be annotated with @Component and @Primary

@jzheaux jzheaux removed the status: blocked An issue that's blocked on an external project change label Mar 13, 2024
@jzheaux
Copy link
Contributor

jzheaux commented Sep 10, 2024

Closed in 60cd8fd

@jzheaux jzheaux closed this as completed Sep 10, 2024
@jzheaux jzheaux self-assigned this Sep 10, 2024
@jzheaux jzheaux added the status: duplicate A duplicate of another issue label Sep 10, 2024
@jzheaux jzheaux added this to the 6.4.0-M4 milestone Sep 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core An issue in spring-security-core status: duplicate A duplicate of another issue type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

8 participants