Spring security “春季安全预授权”;过滤器=无”;不起作用

Spring security “春季安全预授权”;过滤器=无”;不起作用,spring-security,siteminder,pre-authentication,Spring Security,Siteminder,Pre Authentication,奇怪的是 我正在使用spring security和siteminder,它工作得很好。然而,我想有一个url是不受保护的-我们的loadBalancer需要一个“healthCheck”的应用程序本身的url。siteminder没有截取此url,但spring security似乎无论如何都会对其应用预授权 如果我使用一个简单的基于表单的安全配置在本地运行它,那么以下工作(不包括过滤器): 在这种情况下,我可以浏览到localhost/myApp/resources/html/healt

奇怪的是

我正在使用spring security和siteminder,它工作得很好。然而,我想有一个url是不受保护的-我们的loadBalancer需要一个“healthCheck”的应用程序本身的url。siteminder没有截取此url,但spring security似乎无论如何都会对其应用预授权

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


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

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

<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)
java.lang.IllegalArgumentException:无法将null或空值传递给构造函数
org.springframework.security.core.userdetails.User.(User.java:94)
com.myApp.security.SecuritySBSUserDetailsService.loadUserByUsername(SecuritySBSUserDetailsService.java:119)
org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper.loadUserDetails(UserDetailsByNameServiceWrapper.java:53)
我认为这是由于UserDetailsService在没有任何SM_用户的情况下被实例化造成的。然而,过滤器=没有安装到位。。并且在使用表单身份验证时有效。知道是什么导致了这种情况,或者更好的解决方法吗

顺便说一下,my 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>


i、 e.我已将exceptionIfHeaderMissing设置为false,如果这有帮助的话..

好的,据我所知,这似乎是spring security中的一个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
@覆盖
公共用户详细信息loadUserByUsername(字符串用户名)
抛出UsernameNotFoundException、DataAccessException{
logger.trace(“>>loadUserByUsername()”);
info(“--loadUserByUsername():用户名:{}”,用户名);
列表权限=新建ArrayList();
if(userName==null | | userName.trim().equals(“”){
返回(新用户(“匿名”、“真实”、“真实”、“真实”、“权威”);
}
//其余的身份验证检查

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

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

如果启用调试日志记录,它应该详细解释什么与什么匹配

我还省略了
自动配置
。它会导致更多的混乱。对于通用ant模式匹配,您应该使用
/**
而不是
/*


这里可能还值得一提的是,对于定义空的过滤器链,还允许您使用
语法定义多个过滤器链。

从您问题中的信息来看,您使用的似乎是一条不匹配的路径。没有证据表明存在错误。很多人使用这种结构,因此它是错误的也不太可能有如此明显的东西以前不会被发现。
@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