奇怪的一个,
我在siteminder中使用Spring Security,它工作得很好。然而,我想有一个不受保护的网址-我们的loadBalancer在应用程序本身中需要一个“健康检查”网址。这个网址不会被siteminder截获,但是Spring Security似乎无论如何都会对它应用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>
当我浏览到:服务器/myapp/资源/html/健康检查. 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)
我认为这是由UserDetailsService在没有任何SM_USER的情况下被实例化引起的。然而过滤器=无已到位…并且在使用表单身份验证时有效…知道是什么导致了这种情况,或者更好的解决方法吗?
顺便说一下,我的用户详情服务配置如下:
<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>
即,我已经将异常IfHeaderMissing设置为false,如果这有帮助的话…
我能看到的最明显的事情是/资源/html/健康检查. html
不会与/html/健康检查.html
匹配。如果您正在某处重写URL,您可能应该解释一下。
如果您启用调试日志记录,它应该详细解释匹配的内容。
我还会省略auto-config
。它造成的混乱比它的价值更多。您应该使用/**
而不是/*
来进行通用蚂蚁模式匹配。
这里可能还值得一提的是,Spring Security 3.1有一种更好的方法来定义空过滤器链,并且还允许您使用定义多个过滤器链
好吧,据我所知,这似乎是Spring安全性的bug。我通过在UserDetailsService中的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
似乎使用我拥有的配置,根本不应该触发用户详细信息检查(就像表单一样…)。如果有人有基于配置的解决方法,我会给你一个加号:-)