6

我正在使用 Spring Security 来保护 webapp。URL 的保护方式如下:

<security:http entry-point-ref="authenticationEntryPoint">
  <security:intercept-url pattern="/" access="ROLE_ANONYMOUS" />
  <security:intercept-url pattern="/assets/**/*" access="ROLE_ANONYMOUS" />
  ...
  <security:intercept-url pattern="/**" access="ROLE_USER" />
  <security:anonymous granted-authority="ROLE_ANONYMOUS" />
</security:http>

我有一个过滤器需要在某些情况下将用户重定向到特殊页面。但是,该页面需要资产目录中的图像和 CSS 文件,不幸的是,这些文件也会被重定向到该特殊页面。我不希望过滤器手动检查每个 URL 模式,因为我的实际 URL 配置要长得多,而且我还希望允许其他页面。

有没有办法从给定页面的过滤器中确定需要哪些角色?如果不需要 ROLE_ANONYMOUS,我可以选择不重定向。

4

2 回答 2

3

假设您使用的是 Spring Security 3,该信息的来源(为特定路径配置的属性/角色)是注入到 FilterSecurityInterceptor 中的 FilterInvocationSecurityMetadataSource。因此,如果您有特定的 URL,则可以通过将 FilterInvocation(从请求和响应创建)传递给 FilterInvocationSecurityMetadataSource 的 getAttributes() 方法来查询配置的属性。

获取对命名空间创建的内部 bean 的引用可能有点棘手。假设您有自己的 bean(或 bean)要从中进行调用,您可以通过将 BeanPostProcessor 添加到应用程序上下文中来将其注入其中,其实现方式如下:

public class FilterSecurityMDSExtractor implements BeanPostProcessor, BeanFactoryAware {
    private ConfigurableListableBeanFactory bf;

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof FilterInvocationSecurityMetadataSource) {
            // Get your own bean from the BeanFactory here and inject the SecurityMetadataSource into it
        }
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }    

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.bf = (ConfigurableListableBeanFactory)beanFactory;
    }   
}

请注意,Spring Security 会在上下文中自动注册一个 WebInvocationPrivilegeEvaluator,它可用于检查用户是否能够在不实际调用特定 URL 的情况下调用它。这很相似,因为它查询 SecurityMetadataSource,但不完全是您在此处所追求的。

于 2010-01-23T16:56:56.627 回答
2

不要忘记,在决定是否允许访问时实际发生的是 URL 和现有身份验证通过一系列AccessDecisionVoter传递,其中一个默认值是RoleVoter。此投票者检查所请求资源的配置,如果需要特定角色,如果现有身份验证没有该角色,则将拒绝该请求。

因此,对于解决方案 - 您可以在角色投票者之前添加其他投票者。每个选民必须返回 GRANT、DENY 或 ABSTAIN,并且只有在返回 ABSTAIN 时才会继续处理后续的选民。因此,您可以编写自己的自定义投票器(如果可行,也可以重用现有的投票器),在角色投票器之前触发它,并无条件地授予对您所指资源的任何请求的访问权限。

我在当前项目中做过类似的事情,其中​​某些特定于应用程序的临时属性可以让某人访问通常他们无法访问的资源,并且它作为一种方法效果很好。

于 2009-01-17T21:07:37.977 回答