gpt4 book ai didi

spring - 使用 SQL 查询的动态 Spring Security

转载 作者:行者123 更新时间:2023-12-02 02:31:13 24 4
gpt4 key购买 nike

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

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

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

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

最佳答案

免责声明

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

实现自定义 FilterInitationSecurityMetadataSource

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

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

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

您无法使用命名空间来连接它,因此需要另一个 tip from the FAQ您可以使用 BeanPostProcessor,它可能如下所示:

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 都在包示例中,您将添加以下配置

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

可能的问题

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

关于spring - 使用 SQL 查询的动态 Spring Security,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8381776/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com