Spring安全自定义身份验证提供程序无效

时间:2015-08-01 11:41:51

标签: spring authentication spring-security

我正在将我的应用程序的安全性迁移到Spring Security 4.0。我的要求是身份验证应该是JAAS身份验证,并且将从数据库中获取Autorization数据。所以我有自定义身份验证提供程序。但我的问题是Spring没有将身份验证请求委托给我的自定义身份验证提供程序。

代码如下:

自定义身份验证提供程序

public class CustomAutenticationProvider extends DaoAuthenticationProvider implements AuthenticationProvider {
private AuthenticationProvider delegate;

public CustomAutenticationProvider(AuthenticationProvider delegate) {
    this.delegate = delegate;
}

@Override
public Authentication authenticate(Authentication authentication) {
    Authentication a = delegate.authenticate(authentication);

    if(a.isAuthenticated()){
        a = super.authenticate(a);
    }else{
        throw new BadCredentialsException(messages.getMessage(
                "AbstractUserDetailsAuthenticationProvider.badCredentials",
                "Bad credentials"));
    }

    return a;
}

private List<GrantedAuthority> loadRolesFromDatabaseHere(String name) {
    GrantedAuthority grantedAuthority =new JaasGrantedAuthority(name, new UserPrincipal(name));
    return Arrays.asList(grantedAuthority);
}

@Override
public boolean supports(Class<?> authentication) {
    return delegate.supports(authentication);
}

/* (non-Javadoc)
 * @see org.springframework.security.authentication.dao.DaoAuthenticationProvider#additionalAuthenticationChecks(org.springframework.security.core.userdetails.UserDetails, org.springframework.security.authentication.UsernamePasswordAuthenticationToken)
 */
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails,
        UsernamePasswordAuthenticationToken authentication)
                throws AuthenticationException {


    if(!authentication.isAuthenticated())
        throw new BadCredentialsException(messages.getMessage(
                "AbstractUserDetailsAuthenticationProvider.badCredentials",
                "Bad credentials"));


}

}

加载授权数据

public class CustomUserDetailsService implements UserDetailsService {

private UserDataSource _dataSource = UserDataSource.newInstance();

/* (non-Javadoc)
 * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
 */
@Override
public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException {
    System.out.println("loadUserByUsername with param: "+username+" called");
    int _userID;
    UserData _userData = null;
    try {
        _userID = _dataSource.findUserID( username );
        _userData = _dataSource.findByID( _userID );
    } catch (SystemException | SecurityException e) {
        throw new BackEndSystemException("Could not retrieve userId or UserData for userName :"+username);
    }

    return _userData;
}

}

Spring XML条目

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:security="http://www.springframework.org/schema/security"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd">


<security:authentication-manager id="customAuthManager">
        <security:authentication-provider ref="customauthProvider" />
    </security:authentication-manager>
    <bean id="customauthProvider" class="com.enterprise.security.CustomAutenticationProvider">
        <constructor-arg name="delegate" ref="jaasAuthProvider" />
        <property name="userDetailsService" ref="userDetailsService" />
    </bean>

    <security:http pattern="*/js/**" security="none" />
    <security:http pattern="*/css/**" security="none" />
    <security:http pattern="*/image*" security="none" />
    <security:http pattern="/en/Login*" security="none" />
    <security:http auto-config="true" use-expressions="true">
        <security:csrf disabled="true" />
        <security:intercept-url pattern="/**" access="permitAll" />
        <security:form-login login-page="/en/Login.jsp" default-target-url="/en/account/AccountWelcome.jsp" />
        <security:logout invalidate-session="true" delete-cookies="JSESSIONID" logout-success-url="/en/account/AccountWelcome.jsp" logout-url="/j_spring_security_logout" />
        <!-- 
            <security:session-management session-fixation-protection="newSession"> 
                <security:concurrency-control max-sessions="1" expired-url="/loginfailed"  error-if-maximum-exceeded="false"/> </security:session-management>
        -->
    </security:http>

    <bean id="userDetailsService" class="com.enterprise.security.service.CustomUserDetailsService"></bean>

    <bean id="jaasAuthProvider"
    class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider">
        <property name="loginConfig" value="classpath:ldap.jaas.config" />
        <property name="authorityGranters">
            <list>
                <bean class="com.enterprise.security.DummyJAASRoleGrantor" />
            </list>
        </property>
        <property name="loginContextName" value="LDAPLogin" />
        <property name="callbackHandlers">
            <list>
                <bean
                    class="org.springframework.security.authentication.jaas.JaasNameCallbackHandler" />
                <bean
                    class="org.springframework.security.authentication.jaas.JaasPasswordCallbackHandler" />
            </list>
        </property>
    </bean>
</beans>

web.xml条目

    <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xmlns="http://java.sun.com/xml/ns/javaee"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
             id="WebApp_ID" version="3.0">

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/springApplicationContext.xml
        </param-value>
    </context-param>
      
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>
            org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

调用堆栈

Daemon Thread [http-bio-8080-exec-9] (Suspended (breakpoint at line 29 in CustomUserDetailsService))    
owns: SocketWrapper<E>  (id=407)    
CustomUserDetailsService.loadUserByUsername(String) line: 29    
DaoAuthenticationProvider.retrieveUser(String, UsernamePasswordAuthenticationToken) line: 114   
DaoAuthenticationProvider(AbstractUserDetailsAuthenticationProvider).authenticate(Authentication) line: 143 
ProviderManager.authenticate(Authentication) line: 167  
ProviderManager.authenticate(Authentication) line: 192  
UsernamePasswordAuthenticationFilter.attemptAuthentication(HttpServletRequest, HttpServletResponse) line: 93    
UsernamePasswordAuthenticationFilter(AbstractAuthenticationProcessingFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 217   
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 330 
LogoutFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 120   
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 330 
HeaderWriterFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 64  
HeaderWriterFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107   
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 330 
WebAsyncManagerIntegrationFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 53    
WebAsyncManagerIntegrationFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107 
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 330 
SecurityContextPersistenceFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 91    
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 330 
FilterChainProxy.doFilterInternal(ServletRequest, ServletResponse, FilterChain) line: 213   
FilterChainProxy.doFilter(ServletRequest, ServletResponse, FilterChain) line: 176   
DelegatingFilterProxy.invokeDelegate(Filter, ServletRequest, ServletResponse, FilterChain) line: 344    
DelegatingFilterProxy.doFilter(ServletRequest, ServletResponse, FilterChain) line: 261  
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 241  
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 208  
StandardWrapperValve.invoke(Request, Response) line: 220    
StandardContextValve.invoke(Request, Response) line: 122    
NonLoginAuthenticator(AuthenticatorBase).invoke(Request, Response) line: 505    
StandardHostValve.invoke(Request, Response) line: 170   
ErrorReportValve.invoke(Request, Response) line: 103    
AccessLogValve.invoke(Request, Response) line: 957  
StandardEngineValve.invoke(Request, Response) line: 116 
CoyoteAdapter.service(Request, Response) line: 423  
Http11Processor(AbstractHttp11Processor<S>).process(SocketWrapper<S>) line: 1079    
Http11Protocol$Http11ConnectionHandler(AbstractProtocol$AbstractConnectionHandler<S,P>).process(SocketWrapper<S>, SocketStatus) line: 620   
JIoEndpoint$SocketProcessor.run() line: 318 
ThreadPoolExecutor(ThreadPoolExecutor).runWorker(ThreadPoolExecutor$Worker) line: 1145  
ThreadPoolExecutor$Worker.run() line: 615   
TaskThread$WrappingRunnable.run() line: 61  
TaskThread(Thread).run() line: 724  

1 个答案:

答案 0 :(得分:0)

我在身份验证管理器中遗漏了别名属性。但为什么这个别名是必要的?

<security:authentication-manager alias="authenticationManager">
        <security:authentication-provider ref="customauthProvider" />
</security:authentication-manager>