Spring Security Preauth“filters = none”无效

时间:2012-05-16 17:40:57

标签: spring-security siteminder pre-authentication

奇怪的是,

我正在使用带有siteminder的spring security,它运行正常。但是我希望有一个不受保护的网址 - 我们的loadBalancer在应用程序本身中需要一个“healthCheck”网址。这个网址没有被siteminder拦截,但春天的安全性似乎无论如何都应用了preauth ..

如果我使用简单的基于表单的安全配置在本地运行它,则以下工作(不包括过滤器):

<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/html/healthCheck.html" filters="none" />   
    <intercept-url pattern="/css/**" filters="none" />
    <intercept-url pattern="/images/**" filters="none" />
    <intercept-url pattern="/js/**" filters="none" />
    <intercept-url pattern="/login" filters="none" />
    <intercept-url pattern="/favicon.ico" filters="none" />
    <intercept-url pattern="/*" access="hasAnyRole('ROLE_USER')" />
    <form-login login-page="/login" default-target-url="/" authentication-failure-url="/loginfailed" />
    <logout logout-success-url="/logout" />
</http>

在这种情况下,我可以浏览localhost / myApp / resources / html / healthCheck.html而不会遇到授权问题,但任何其他网址都会显示登录表单。到目前为止一切都很好看!

但是当我部署到服务器时,我使用以下配置:

<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/html/healthCheck.html" filters="none" />   
    <intercept-url pattern="/css/**" filters="none" />
    <intercept-url pattern="/images/**" filters="none" />
    <intercept-url pattern="/js/**" filters="none" />
    <intercept-url pattern="/login" filters="none" />
    <intercept-url pattern="/favicon.ico" filters="none" />
    <intercept-url pattern="/*" access="hasAnyRole('ROLE_USER')" />
    <custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
</http>

当我浏览到:server / myapp / resources / html / healthCheck.html时出现以下错误:

java.lang.IllegalArgumentException: Cannot pass null or empty values to constructor
    org.springframework.security.core.userdetails.User.<init>(User.java:94)
    com.myApp.security.SecuritySBSUserDetailsService.loadUserByUsername(SecuritySBSUserDetailsService.java:119)
    org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper.loadUserDetails(UserDetailsByNameServiceWrapper.java:53)

我认为这是由UserDetailsS​​ervice实例化而没有任何SM_USER引起的。然而,filters = none已经到位..并且在使用表单身份验证时有效。任何想法可能导致这种或更好的解决方法?

顺便说一句,我的userdetails服务配置如下:

<beans:bean id="siteminderFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
    <beans:property name="principalRequestHeader" value="SM_USER" />
    <beans:property name="exceptionIfHeaderMissing" value="false" />
    <beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>

即。我将exceptionIfHeaderMissing设置为false,如果这有帮助..

2 个答案:

答案 0 :(得分:2)

我能看到的最明显的事情是/resources/html/healthCheck.html不会与/html/healthCheck.html匹配。如果你在某处重写URL,你应该解释一下。

如果启用调试日志记录,则应详细说明与什么匹配的内容。

我也遗漏了auto-config。它会导致更多的混乱而不是它的价值。您应该使用/**而不是/*来进行通用的蚂蚁模式匹配。

这里可能还值得一提的是Spring Security 3.1 has a better approach用于定义空过滤器链,并且还允许您使用<http>语法定义多个过滤器链。

答案 1 :(得分:0)

好吧,据我所知,这似乎是春季安全漏洞。我通过在UserDetailsS​​ervice中的loadUserByName方法的开头添加一个虚拟返回来解决它。

@Override
public UserDetails loadUserByUsername(String userName)
        throws UsernameNotFoundException, DataAccessException {
    logger.trace(">> loadUserByUsername()");
    logger.info("-- loadUserByUsername(): username : {}", userName);

    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();             
    if(userName==null || userName.trim().equals("")) {
        return(new User("ANONYMOUS", "", true, true, true, true, authorities));
        }
// rest of auth checks

看起来我的配置,UserDetails检查根本不应该被触发(就像表单一样..)。如果有人有基于配置的解决方法,我会给你一个加号: - )