I am migrating my application's security to Spring Security 4.0 . My requirement is authentication should be JAAS authentication and Autorization data would be fetched from database. SO I have written and custom authentication provider. But my problem is Spring is not delegating authentication requests to my custom authentication provider.
Codes are given below
Custom Authentication Provider
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"));
}
}
Load Authorization Data
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 entry
<?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 entry
<?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>
Call Stack
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