本文介绍了使用 SQL 查询的动态 Spring Security的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,我想通过在spring security中使用sql查询来制作一个拦截url模式并动态访问.

Hello I want to make an intercept url pattern and access dynamically by using sql query in spring security.

通常我们在 XML 中使用这种类型的符号,我想从数据库中获取这些值(/add-role 和 ROLE_ADMIN).

Generally we use this type of notation in XML and I want to take these values (/add-role and ROLE_ADMIN) from database.

<intercept-url pattern="/add-role*" access="ROLE_ADMIN" />

是否可以动态执行此操作?

Is it possible to do this dynamically?

推荐答案

免责声明

作为 Spring Security FAQ 提到,你应该做的第一件事是问我真的应该这样做吗?安全性很复杂,应该对配置进行广泛的测试.允许动态更改配置只会使事情变得更加复杂,从而使应用程序更容易受到攻击.如果您真的想这样做,常见问题解答概述了实现此目的的基本方法.我已经扩展了下面常见问题解答的答案.

Disclaimer

As the Spring Security FAQ mentions, the first thing you should do is ask should I really do this? Security is complicated and the configuration should be tested extensively. Allowing the configuration to change dynamically only further complicates things making the application that much more vulnerable. If you really want to do this, the FAQ outlines a basic method to accomplish this. I have expanded upon the FAQ's answer below.

要动态获取安全 URL 映射,您可以实现自己的 FilterInvocationSecurityMetadataSource.下面给出了一个示例实现.

To obtain the security URL mappings dynamically you can implement your own FilterInvocationSecurityMetadataSource. An example implementation is given below.

注意:请记住,对于 Spring Security 拦截的每个请求都会调用 getAttributes,因此您很可能需要某种缓存.

NOTE: Keep in mind that getAttributes will be invoked for every request that Spring Security intercepts so you will most likely want some sort of caching.

public class JdbcFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        FilterInvocation fi = (FilterInvocation) object;

        String url = fi.getRequestUrl();
        HttpServletRequest request = fi.getHttpRequest();

        // Instead of hard coding the roles lookup the roles from the database using the url and/or HttpServletRequest
        // Do not forget to add caching of the lookup   
        String[] roles = new String[] { "ROLE_ADMIN", "ROLE_USER" };
        return SecurityConfig.createList(roles);
    }

    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    public boolean supports(Class<?> clazz) {
        return FilterInvocation.class.isAssignableFrom(clazz);
    }
}

创建一个 BeanPostProcessor

你不能使用命名空间来连接它,所以使用另一个 FAQ 中的提示 您可以使用 BeanPostProcessor,它可能如下所示:

Create a BeanPostProcessor

You cannot use the namespace to wire it up, so taking another tip from the FAQ you can use a BeanPostProcessor which might look like:

public class FilterInvocationSecurityMetadataSourcePostProcessor implements BeanPostProcessor, InitializingBean {
    private FilterInvocationSecurityMetadataSource securityMetadataSource;

    public Object postProcessAfterInitialization(Object bean, String name) {
        if (bean instanceof FilterSecurityInterceptor) {
            ((FilterSecurityInterceptor)bean).setSecurityMetadataSource(securityMetadataSource);
        }
        return bean;
    }

    public Object postProcessBeforeInitialization(Object bean, String name) {
        return bean;
    }

    public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {
        this.securityMetadataSource = securityMetadataSource;
    }

    public void afterPropertiesSet() throws Exception {
        Assert.notNull(securityMetadataSource,"securityMetadataSource cannot be null");
    }
}

XML 配置

那么,假设上面的两个bean都在包示例中,你会添加以下配置

XML Configuration

Then, assuming both of the above beans are in the package sample, you would add the following configuration

<bean class="sample.FilterInvocationSecurityMetadataSourcePostProcessor">
    <property name="securityMetadataSource">
        <bean class="sample.JdbcFilterInvocationSecurityMetadataSource"/>
    </property>
</bean>

可能的问题

如果您最终收到 ClassCastException,您可能会遇到 SEC-1957 已在 Spring Security 3.1.1+ 中修复 尝试更新到最新版本以解决此问题.

Possible Problems

If you end up getting a ClassCastException, you are likely running into SEC-1957 which was fixed in Spring Security 3.1.1+ Try updating to the latest version to resolve this.

这篇关于使用 SQL 查询的动态 Spring Security的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 07:32