如何动态决定访问Spring Security中的属性值?
在Spring Security中,我们使用intercept-url标签来定义URL的访问,如下所示:
<intercept-url pattern="/**" access="ROLE_ADMIN" />
<intercept-url pattern="/student" access="ROLE_STUDENT" />
这是硬编码在applicationContext-security.xml
中的。我想从数据库表中读取访问值。我定义了自己的 UserDetailsService
并从数据库中读取登录用户的角色。如何在运行时将这些角色分配给 URL 模式?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
Spring-security 中的 FilterIncationSecurityMetadataSourceParser 类(在带有源代码的 STS 中尝试 Ctrl/Cmd+Shift+T)解析拦截 url 标签并创建 ExpressionBasedFilterInvocalSecurityMetadataSource 的实例,该实例扩展了 DefaultFilterInitationSecurityMetadataSource,后者实现了扩展 SecurityMetadataSource 的 FilterInitationSecurityMetadataSource。
我所做的是创建一个实现 FilterInitationSecurityMetadataSource 的自定义类,OptionsFromDataBaseFilterInitationSecurityMetadataSource。我使用 DefaultFilterIncationSecurityMetadataSource 作为使用 urlMatcher 的基础,以实现 support() 方法和类似的东西。
然后你必须实现这些方法:
Collection getAttributes(Object object),你可以在其中访问数据库,搜索受保护的“对象”(通常是要访问的 URL)以获取允许的 ConfigAttribute(通常是 ROLE)
booleansupports(Class clazz)
Collection getAllConfigAttributes()
后面的要小心,因为它是在启动时调用的,也许是目前配置不佳(我的意思是,数据源或持久性上下文自动连接,具体取决于您使用的内容)。 Web 环境中的解决方案是在 web.xml 中配置 contextConfigLocation,以在 applicationContext-security.xml 之前加载 applicationContext.xml。
最后一步是自定义 applicationContext-security.xml 来加载此 bean。
为此,我在此文件中使用常规 bean,而不是安全命名空间:
您必须定义所有相关的 bean。例如:
我知道这不是一个很好解释的答案,但它并不像看起来那么困难。
只要使用 spring 源作为基础,你就会得到你想要的。
使用数据库中的数据进行调试会对您有很大帮助。
The FilterInvocationSecurityMetadataSourceParser class in Spring-security (try Ctrl/Cmd+Shift+T in STS with the source code) parses the intercept-url tags and creates instances of ExpressionBasedFilterInvocationSecurityMetadataSource, that extends DefaultFilterInvocationSecurityMetadataSource that implements FilterInvocationSecurityMetadataSource that extends SecurityMetadataSource.
What I did is to create a custom class that implements FilterInvocationSecurityMetadataSource, OptionsFromDataBaseFilterInvocationSecurityMetadataSource. I used DefaultFilterInvocationSecurityMetadataSource as base to use urlMatcher, to implement the support() method and something like that.
Then you must to implement these methods:
Collection getAttributes(Object object), where you can access to database, searching for the 'object' being secured (normally the URL to access) to obtain the allowed ConfigAttribute's (normally the ROLE's)
boolean supports(Class clazz)
Collection getAllConfigAttributes()
Be careful with the later, because it's called at startup and maybe is not well configured at this time (I mean, with the datasources or persistence context autowired, depending on what are you using). The solution in a web environment is to configure the contextConfigLocation in the web.xml to load the applicationContext.xml before the applicationContext-security.xml
The final step is to customize the applicationContext-security.xml to load this bean.
For doing that, I used regular beans in this file instead of the security namespace:
You have to define all the related beans. For instance:
I know that is not a well explained answer, but it's not as difficult as it seems.
Just use the spring source as base and you will obtain what you want.
Debugging with the data in your database, will help you a lot.
实际上,Spring Security 3.2 不鼓励根据 http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/faq.html#faq-dynamic-url-metadata
但是,它可以(但不优雅)在命名空间中使用带有自定义 accessDecisionManager 的 http 元素。
配置应该是:
CustomAccessDecisionManager 应该是...
其中 getConfigAttributesFromSecuredUris 检索特定 URL 的数据库角色
Actually, spring security 3.2 do not encourage to do this according to http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/faq.html#faq-dynamic-url-metadata
but, it is possible (but not elegant) using http element in namespace with a custom accessDecisionManager..
The config should be:
The CustomAccessDecisionManager should be...
Where getConfigAttributesFromSecuredUris retrieve form DB de roles for the specific URL
我有类似的问题,基本上我想将拦截url列表与其他springsecurity配置部分分开,第一个属于应用程序配置,后者属于产品(核心、插件)配置。
spring的JIRA中有一个提案,关于这个问题。
我不想放弃使用 springsecurity 命名空间,所以我正在考虑一些可能的解决方案来解决这个问题。
为了动态创建拦截 URL 列表,您必须在 FilterSecurityInterceptor 中注入 securitymetadatasource 对象。
使用 springsecurity 架构,FilterSecurityInterceptor 的实例由 HttpBuilder 类创建,并且无法将 securitymetadatasource 作为架构配置文件中定义的属性传递,就像使用某种解决方法一样,这可能是:
你怎么认为?
I have kind of the same problem, basically I'd like to keep separate the list of intercept-url from the other springsecurity configuration section, the first to belong to the application configuration the latter to the product (core, plugin) configuration.
There is a proposal in the JIRA of spring, concerning this problem.
I don't want to give up to use the springsecurity namespace, so I was thinking to some possible solutions in order to deal with this.
In order to have the list of intercept-url dynamically created you have to inject the securitymetadatasource object in the FilterSecurityInterceptor.
Using springsecurity schema the instance of FilterSecurityInterceptor is created by the HttpBuilder class and there is no way to pass the securitymetadatasource as property defined in the schema configuration file, as less as using kind of workaround, which could be:
What do you think?
这是我应用的解决方案,以便将拦截 URL 条目列表与其他 spring 安全配置分开。
bean securityMetadataSource 可以放在同一个配置文件中,也可以放在另一个配置文件中。
当然,您可以决定通过实现 FilterInitationSecurityMetadataSource 接口来实现您自己的 securityMetadataSource bean。
像这样的事情:
希望这有帮助。
This the solution I've applied in order to split the list of intercept-url entries from the other spring security configuration.
The bean securityMetadataSource can be put either in the same configuration file or in another configuration file.
Of course you can decide to implement your own securityMetadataSource bean by implementing the interface FilterInvocationSecurityMetadataSource.
Something like this:
Hope this helps.
在 Spring Security 3.2 中可以这样做:
This is how it can be done in Spring Security 3.2:
一个适合我的简单解决方案。
一个 bean :
customAuthenticationProvider 是CustomAuthenticationProvider 类创建方法中的
A simple solution that works for me.
customAuthenticationProvider is a bean
in CustomAuthenticationProvider class create method: