如何以编程方式解析spring安全表达式(例如在某些控制器中)

如何以编程方式解析
spring(web)安全表达式,如hasRole(‘admin’)(不使用标签,注释或……)? (
reference doc)

我找到了Spring: What parser to use to parse security expressions – 但我不知道如何查找或构建EvaluationContext,例如在弹簧控制器内.

没有提供EvaluationContext给出

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

最佳答案 你需要添加几个东西才能让这个东西运转起来.你必须插入Spring的安全API.这是我如何做到的,它在Spring 3.2中运行良好.

首先,如前所述,您必须在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>

这定义了一个新的expressionHandler来覆盖WebExpressionVoter的默认值.然后我们将这个新决策选民添加到决策经理. CustomWebSecurityExpressionHandler用于控制SecurityExpressionRoot的创建.到现在为止还挺好.问题是为什么你需要一个CustomWebSecurityExpressionRoot,答案很简单 – 你在那里定义自定义安全方法.考虑到这一点,我们可以编写以下类:

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);
    }

}

如果要获取ExpressionParser的引用,可以使用以下方法AbstractSecurityExpressionHandler.getExpressionParser().它可以通过CustomWebSecurityExpressionHandler访问.如果你想做一些更具体的事情,你也可以看看它的API.
我希望这能回答你的问题.

点赞