dimanche 15 mars 2015

Spring Security SecurityContextHolder authentication is always anonymousUser

So this is kind of two different questions but solving one will resolve the other or should (if that makes sense). I'm trying out annotation to configure spring security instead of xml. I'm running into an issue where although I successfully authenticate my user and set the authentication via SecurityContextHolder.getContext().setAuthentication(result). I still end up with an anonymousUser.


Here's my security config



@Configuration
@EnableWebSecurity

public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
UserService userService;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.parentAuthenticationManager(authenticationManager());
}

@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(userService);
daoAuthenticationProvider.setHideUserNotFoundExceptions(false);
daoAuthenticationProvider.setPasswordEncoder(bCryptEncoder());
return daoAuthenticationProvider;
}

@Bean
public ProviderManager authenticationManager() {
List<AuthenticationProvider> providers = new ArrayList<AuthenticationProvider>();
providers.add(daoAuthenticationProvider());
return new ProviderManager(providers);
}

@Bean
public BCryptPasswordEncoder bCryptEncoder() {
return new BCryptPasswordEncoder();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/js/**", "/css/**", "/theme/**", "main/javax.faces.resource/**", "/main/userLogin", "/main/welcome", "/main/help")
.permitAll()
.and()
.exceptionHandling()
.accessDeniedPage("/main/error/unauthorized")
.and()
.sessionManagement()
.invalidSessionUrl("/main/userLogin")
.and()
.formLogin()
.loginPage("/main/userLogin")
.defaultSuccessUrl("/main/welcome")
.failureUrl("/main/userLogin")
.and()
.logout()
.deleteCookies("JSESSIONID")
.logoutUrl("/main/logout")
.logoutSuccessUrl("/main/loggedOut");
}

@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/js/**", "/css/**", "/theme/**", "main/javax.faces.resource/**")
.antMatchers(HttpMethod.POST, "/main/userLogin");
}


And here's the service class that performs the authentication



@Service("userAuthenticationProviderService")
public class UserAuthenticationProviderServiceImpl implements UserAuthenticationProviderService {

private static Log log = LogFactory.getLog(UserAuthenticationProviderServiceImpl.class);

@Autowired
private AuthenticationManager authenticationManager;

@Override
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, readOnly = true)
public boolean isUserAuthenticated(User user) {
try {log.info("try begin");
Authentication request = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
Authentication result = authenticationManager.authenticate(request);
SecurityContextHolder.getContext().setAuthentication(result);
SecurityContextHolder.setContext(context);

log.info("try end changed. User: " + SecurityContextHolder.getContext().getAuthentication().getName());
return true;
}
catch (Exception e) {
log.error(e.getMessage());
return false;
}
}

@Override
public boolean isUserLoggedIn() {
boolean userLoggedIn = !(SecurityContextHolder.getContext().getAuthentication() instanceof AnonymousAuthenticationToken);
log.info("userLoggedIn: " + userLoggedIn);
log.info("User: " + SecurityContextHolder.getContext().getAuthentication().getName());
return userLoggedIn;
}

}


You might notice that I'm ignoring the login page when I configure the web security. I get that this is part of the problem but it's kind of my workaround to the other issue I'm having. I use spring webflow and everything (buttons/links) are sent as POST and because my login page is configured in the formLogin(), any button/link on that page is assumed to be the login action (or at least that's what it seems like when I comment out that portion and run it).


I'm able to authenticate, just that the authentication doesn't seem to persist in the SecurityContext.


Here's the stack trace I get when I DON'T ignore the login page when configuring WebSecurity



2015-03-15 15:11:23 DEBUG ViewState:189 - Entering state 'userLogin' of flow 'userLogin'
2015-03-15 15:11:23 DEBUG SessionBindingConversationManager:86 - Putting conversation attribute 'name' with value userLogin

2015-03-15 15:11:23 DEBUG SessionBindingConversationManager:86 - Putting conversation attribute 'caption' with value null
2015-03-15 15:11:23 DEBUG SessionBindingConversationManager:86 - Putting conversation attribute 'description' with value nu
ll
2015-03-15 15:11:23 DEBUG SessionBindingConversationManager:86 - Putting conversation attribute 'flowExecutionSnapshotGroup
' with value org.springframework.webflow.execution.repository.impl.SimpleFlowExecutionSnapshotGroup@9380d07
2015-03-15 15:11:23 DEBUG FlowExecutionImpl:421 - Assigned key e5s1
2015-03-15 15:11:23 DEBUG Transition:231 - Completed transition execution. As a result, the new state is 'userLogin' in fl
ow 'userLogin'
2015-03-15 15:11:23 DEBUG Transition:231 - Completed transition execution. As a result, the new state is 'userLogin' in fl
ow 'userLogin'
2015-03-15 15:11:23 DEBUG SessionBindingConversationManager:75 - Locking conversation 5
2015-03-15 15:11:23 DEBUG DefaultFlowExecutionRepository:121 - Putting flow execution '[FlowExecutionImpl@53ee2fb6 flow = '
userLogin', flowSessions = list[[FlowSessionImpl@a1717c0 flow = 'userLogin', state = 'userLogin', scope = map['viewScope' ->
map[[empty]], 'loginOrRegisterAction' -> com.ilandcoder.common.ui.LoginOrRegisterAction@4d39c7a9]]]]' into repository
2015-03-15 15:11:23 DEBUG DefaultFlowExecutionRepository:128 - Adding snapshot to group with id 1
2015-03-15 15:11:23 DEBUG SessionBindingConversationManager:86 - Putting conversation attribute 'scope' with value map['fla
shScope' -> map['messagesMemento' -> map[[null] -> list[[empty]]]]]
2015-03-15 15:11:23 DEBUG SessionBindingConversationManager:107 - Unlocking conversation 5
2015-03-15 15:11:23 DEBUG FlowHandlerAdapter:413 - Sending flow execution redirect to '/webapp/main/userLogin?execution=e5s
1'
2015-03-15 15:11:23 DEBUG ResponseStatusExceptionResolver:134 - Resolving exception from handler [[FlowHandlerMapping.Defau
ltFlowHandler@a94233f]]: java.lang.NullPointerException
2015-03-15 15:11:23 DEBUG DefaultHandlerExceptionResolver:134 - Resolving exception from handler [[FlowHandlerMapping.Defau
ltFlowHandler@a94233f]]: java.lang.NullPointerException
2015-03-15 15:11:23 DEBUG DispatcherServlet:989 - Could not complete request
java.lang.NullPointerException
at javax.faces.context.PartialResponseWriter.startDocument(PartialResponseWriter.java:119)
at org.springframework.faces.webflow.JsfAjaxHandler.sendAjaxRedirectInternal(JsfAjaxHandler.java:75)
at org.springframework.js.ajax.AbstractAjaxHandler.sendAjaxRedirect(AbstractAjaxHandler.java:31)
at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.sendFlowExecutionRedirect(FlowHandlerAdapter.java:416)
at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handleFlowExecutionResult(FlowHandlerAdapter.java:385)
at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:239)
at org.springframework.faces.webflow.JsfFlowHandlerAdapter.handle(JsfFlowHandlerAdapter.java:57)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:
118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.jav
a:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilt
er.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolder
AwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthentica
tionProcessingFilter.java:199)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilte
r.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncM
anagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1081)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1566)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1523)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
2015-03-15 15:11:24 DEBUG HttpSessionSecurityContextRepository:304 - SecurityContext is empty or contents are anonymous - con
text will not be stored in HttpSession.
2015-03-15 15:11:24 DEBUG SecurityContextPersistenceFilter:97 - SecurityContextHolder now cleared, as request processing co
mpleted

Aucun commentaire:

Enregistrer un commentaire