How to parse spring security expressions programmatically (e.g. in some controller)

烂漫一生 提交于 2019-12-07 09:16:25

问题


How do you parse spring (web) security expressions like hasRole('admin') programmatically (without using tags, annotations or ...)? (reference doc)

I've found Spring: What parser to use to parse security expressions - but I don't know how to find or build the EvaluationContext e.g. inside a spring controller.

Without providing an EvaluationContext gives

org.springframework.expression.spel.SpelEvaluationException: EL1011E:(pos 0): Method call: Attempted to call method hasRole(java.lang.String) on null context object

回答1:


you need to add several things in order to get this thing working. You have to plug into the Spring's security API. Here's how I did it and it is working fine with Spring 3.2. First as it was stated before you must have similar configuration in your spring-context.xml:

<security:http access-decision-manager-ref="customAccessDecisionManagerBean"> 

<security:http/>

<bean id="customWebSecurityExpressionHandler" 
    class="com.boyan.security.CustomWebSecurityExpressionHandler"/>

<bean id="customAccessDecisionManagerBean" 
    class="org.springframework.security.access.vote.AffirmativeBased">
        <property name="decisionVoters">
            <list>
                <bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
                    <property name="expressionHandler" ref="customWebSecurityExpressionHandler" />
                </bean>
            </list>
        </property> 
</bean>

This defines a new expressionHandler to override the default one for the WebExpressionVoter. Then we add this new decision voter to the decision manager. CustomWebSecurityExpressionHandler's purpose it to control the creation of SecurityExpressionRoot. So far so good. The question is why do you need a CustomWebSecurityExpressionRoot and the answer is simple as that - you define your custom security methods there. Having this in mind we can write the following classes:

public class CustomWebSecurityExpressionHandler extends DefaultWebSecurityExpressionHandler {

    @Override
    protected SecurityExpressionOperations createSecurityExpressionRoot(
                Authentication authentication, FilterInvocation fi) {
          CustomWebSecurityExpressionRoot expressionRoot = 
              new CustomWebSecurityExpressionRoot(authentication, delegationEvaluator);

        return expressionRoot;
       }

    }
}

public class CustomWebSecurityExpressionRoot extends WebSecurityExpressionRoot {

    public CustomWebSecurityExpressionRoot(Authentication auth, FilterInvocation fi) {
            super(auth, fi);
    }

    // in here you must define all of the methods you are going to invoke in @PreAuthorize
    // for example if you have an expression with @PreAuthorize('isBoyan(John)')
    // then you must have the following method defined here:
    public  boolean isBoyan(String value) {
        //your logic goes in here
        return "Boyan".equalsIgnoreCase(value);
    }

}

If you want to get a reference to the ExpressionParser you can use the following method AbstractSecurityExpressionHandler.getExpressionParser(). It is accessible through CustomWebSecurityExpressionHandler. Also you can take a look at its API if you want to do something more specific. I hope this answers you question.



来源:https://stackoverflow.com/questions/21467823/how-to-parse-spring-security-expressions-programmatically-e-g-in-some-controll

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!