spring - 如何使用 Spring 安全性和 Spring 安全性对象中的属性限制对 URL 的访问?

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

我正在使用 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   

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

最佳答案

Spring 中与安全相关的表达式的操作集非常有限。您可以通过提供 org.springframework.security.access.expression.SecurityExpressionOperations 的自定义实现来扩展此集。界面。以下是如何操作的简要指南:

  • 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
    }
    
  • 扩展 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);
                }
            });
        }
     }
    
  • 提供自定义访问决策管理器:

  • <bean id="affirmativeBased" class="org.springframework.security.access.vote.AffirmativeBased">
        <constructor-arg>
            <list>
                <bean class="my.company.MyWebExpressionVoter"/>
            </list>
        </constructor-arg>
    </bean>
    
  • 应用自定义访问决策管理器:

  • <http pattern="/**" use-expressions="true" access-decision-manager-ref="affirmativeBased">
        <!-- ... -->
    </http>
    
  • 使用附加安全操作保护 URL 之一:

  • <intercept-url pattern="/products" access="hasProducts()"/>
    

    关于spring - 如何使用 Spring 安全性和 Spring 安全性对象中的属性限制对 URL 的访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52212007/

    相关文章:

    java - Spring 3 依赖注入(inject)

    java - Spring-security - 无法访问 ServletException

    java - Spring abac 数据过滤与 Spring @PostFilter

    apache - 如何使用 Require 指令来限制 apache 2.4 中的文件访问

    c++ - 可以通过强制转换为布局兼容类型来访问私有(private)成员函数吗?

    java - @Validated 注解无效

    java - 如何将数据模型模拟注入(inject)到Spring Controller 中?

    java - 为什么 Spring Boot hibernate OneToMany 映射子项返回 null 值?

    java - Spring Security - 记住我自定义服务 onLoginSuccess 未使用 oauth2 调用

    iphone - 限制 iPhone 应用程序访问服务器