【问题标题】:How to programmatically check if a certain URL needs authentication with Spring Security?如何以编程方式检查某个 URL 是否需要使用 Spring Security 进行身份验证?
【发布时间】:2014-08-13 16:03:23
【问题描述】:

有没有办法使用 Spring Security (v 3.1.x) 以编程方式获取某个 URL 的授权规则

我的意思是...假设我设置:

<security:intercept-url pattern="/**" access="isAuthenticated()" />

在我的配置中。

在处理/internal/** 路径的控制器中,我想知道我是否需要身份验证才能访问某个路径。像这样的方法:

boolean isAuthenticationRequired(String ulr);

可能有用。

我可以通过SecurityContextHolder获得这些信息吗?

UPDATE四处搜索,似乎关键可能是SecurityMetadataSource...

【问题讨论】:

  • 这不是您问题的答案,而是可能对您有所帮助的提示。尝试在身份验证期间引发异常。分析堆栈跟踪并找到执行身份验证的代码。环顾四周,您将看到所需的 API。祝你好运。
  • @AlexR 感谢您的建议。
  • 没问题。祝你好运。找到解决方案后,请发布“正确”的自我答案。
  • @AlexR 我希望能找到它... :D

标签: java spring spring-mvc authentication spring-security


【解决方案1】:

如果您使用基于模式的配置,我认为这是获取 SecurityMetadataSource 和规则的唯一(也是丑陋的)方法:

@Autowired
private ApplicationContext applicationContext;

public void someMethod(){
    FilterSecurityInterceptor fsi = applicationContext.getBean(org.springframework.security.web.access.intercept.FilterSecurityInterceptor.class);
    FilterInvocationSecurityMetadataSource sms = fsi.getSecurityMetadataSource();

    try {
        Field field = sms.getClass().getDeclaredField("requestMap");
        field.setAccessible(true);
        Map<RequestMatcher, Collection<ConfigAttribute>> requestMap = (Map<RequestMatcher, Collection<ConfigAttribute>>)field.get(sms);
        Set<Entry<RequestMatcher, Collection<ConfigAttribute>>> entrySet = requestMap.entrySet();
        for (Entry<RequestMatcher, Collection<ConfigAttribute>> entry : entrySet) {
            AntPathRequestMatcher path = (AntPathRequestMatcher)entry.getKey();                     
            System.out.println(path.getPattern());
                            //prints sthg like /action/index
            Collection<ConfigAttribute> roles = entry.getValue();
            System.out.println(roles);
                            //[ROLE_USER,ROLE_ADMIN]
        }
    } catch (Exception e) {
        //TODO
        e.printStackTrace();
    }
}

使用它,您可以轻松地编写实用程序服务来检查 URL。

替代方案更简洁,但最终更冗长:如果您不使用基于模式的配置,则可以更轻松地访问包含映射的 bean (interceptedUrls):

<bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
    <property name="authenticationManager" ref="authenticationManager"/>
    <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
    <property name="securityMetadataSource" ref="interceptedUrls"/>
</bean>


<sec:filter-invocation-definition-source id="interceptedUrls">       
    <sec:intercept-url pattern="/action/login" access="ROLE_ANONYMOUS"/>
    <sec:intercept-url pattern="/action/passwordReset" access="ROLE_ANONYMOUS"/>        

    <sec:intercept-url pattern="/action/index" access="ROLE_ADMIN"/>
    ...

希望这会有所帮助!

【讨论】:

  • +1 我会避免反思,但我认为这可能是一个好的(丑陋的)建议。谢谢。
猜你喜欢
  • 2016-05-11
  • 2013-08-03
  • 2017-05-15
  • 2011-07-02
  • 1970-01-01
  • 1970-01-01
  • 2012-03-06
  • 2013-02-23
  • 2012-11-27
相关资源
最近更新 更多