【问题标题】:How do I restrict access to a URL using Spring security and a property from the spring security object?如何使用 Spring Security 和 Spring Security 对象的属性限制对 URL 的访问?
【发布时间】:2019-02-12 04:27:24
【问题描述】:

我正在使用 Spring 5.1 和 Spring security 4.2。我使用 XML 文件配置了访问规则。我的问题是,如何根据 Spring 安全上下文中的属性编写拦截规则(对 URL 的访问控制)?也就是说,我有一个变量

productList

在 java.util.ArrayList 类型的安全上下文中。如果此列表为空或为空,我想限制对 URL 的访问。我怎么写这个?我有

<http name="defaultSecurity" security-context-repository-ref="myContextRepository"
    auto-config="false" use-expressions="true" authentication-manager-ref="authenticationManager"
    entry-point-ref="loginUrlAuthenticationEntryPoint">
    ...
    <intercept-url pattern="/myurl" access="length(principal.productList) > 0" />
    ...
</http>

当然,在上面

length(principal.productList) > 0   

表达式完全错误。有没有正确的写法?

【问题讨论】:

  • 尝试阅读this如何编写自定义安全表达式
  • 此链接讨论使用 Java 自定义安全性,但我想要一个仅依赖于 XML 配置文件且没有 Java 编码的选项。
  • 这是不可能的,因为您在类中没有长度方法来评估开箱即用的表达式部分,此外 getProductList 未在公共 Principal 类中定义。请参阅:documentationjavadoc WebSecurityExpressionRoot

标签: spring spring-security access-control principal security-context


【解决方案1】:

与安全相关的表达式在 Spring 中的操作集非常有限。您可以通过提供org.springframework.security.access.expression.SecurityExpressionOperations 接口的自定义实现来扩展此集合。这是一个简短的指南:

  1. SecurityExpressionOperations 上创建包装器并实现所需的操作:
class MySecurityExpressionOperations implements SecurityExpressionOperations {
    private SecurityExpressionOperations delegate;

    public MySecurityExpressionOperations(SecurityExpressionOperations delegate) {
        this.delegate = delegate;
    }

    public boolean hasProducts() {
        MyUser user = (MyUser) delegate.getAuthentication().getPrincipal();
        return !user.getProductList().isEmpty();
    }

    // Other methods
}
  1. 扩展org.springframework.security.web.access.expression.WebExpressionVoter 并替换标准表达式处理程序:
class MyWebExpressionVoter extends WebExpressionVoter {
    public MyWebExpressionVoter() {
        setExpressionHandler(new DefaultWebSecurityExpressionHandler() {
            @Override
            protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, FilterInvocation fi) {
                SecurityExpressionOperations delegate = super.createSecurityExpressionRoot(authentication, fi);
                return new MySecurityExpressionOperations(delegate);
            }
        });
    }
 }
  1. 提供自定义访问决策管理器:
<bean id="affirmativeBased" class="org.springframework.security.access.vote.AffirmativeBased">
    <constructor-arg>
        <list>
            <bean class="my.company.MyWebExpressionVoter"/>
        </list>
    </constructor-arg>
</bean>
  1. 应用自定义访问决策管理器:
<http pattern="/**" use-expressions="true" access-decision-manager-ref="affirmativeBased">
    <!-- ... -->
</http>
  1. 使用额外的安全操作保护 URL 之一:
<intercept-url pattern="/products" access="hasProducts()"/>

【讨论】:

    【解决方案2】:

    如果您想检查 productList 中的元素数量,这里有一个解决方法:

     <intercept-url pattern="/myurl" access="principal.productList.size() > 0" />
    

    【讨论】:

    • 试一试,但没有骰子。
    • 不认为(T(your.pkg.Principal)principal).productList.size() &gt; 0 想工作?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-07
    • 2012-12-27
    • 2018-06-05
    • 2023-04-08
    • 2016-02-27
    • 2012-08-16
    • 2013-09-30
    相关资源
    最近更新 更多