如何以编程方式检查某个URL是否需要使用Spring Security进行身份验证?

dav*_*ooh 7 java authentication spring spring-mvc spring-security

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

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

<security:intercept-url pattern="/**" access="isAuthenticated()" />
Run Code Online (Sandbox Code Playgroud)

在我的配置中.

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

boolean isAuthenticationRequired(String ulr);
Run Code Online (Sandbox Code Playgroud)

可能有用.

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

更新搜索它似乎关键可能是SecurityMetadataSource......

cod*_*ent 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

使用它,您可以轻松地编写实用程序服务来检查 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"/>
    ...
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!