Spring Security: Access the current authenticated User inside a servlet Filter

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication != null) {
  if (authentication.getPrincipal() instanceof UserDetails) {
    UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
    return springSecurityUser.getUsername();
  } else if (authentication.getPrincipal() instanceof String) {
    return (String) authentication.getPrincipal();
  }
}
return null;

You can see here, that in order to access the SecurityContext, the security filter must come first.

If you are asking how to do it, it depends on the way you configured your web application. In my case, I'm using Spring-Boot , based on Servlet-3 configuration style, and Spring context configuration in Java (no XML) So, my configuration looks like this:

@Configuration
@EnableWebMvc
@EnableWebMvcSecurity
public class WebCtxConfig extends WebMvcConfigurerAdapter {

    @Autowired
    ApplicationContext ctx;


    @Bean
    FilterRegistrationBean springSecurityFilter() {
        FilterChainProxy o = (FilterChainProxy) ctx
                .getBean(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME);
        FilterRegistrationBean trVal = new FilterRegistrationBean();
        trVal.setFilter(o);
        trVal.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE + 1);
        return trVal;
    }

    @Bean
    public FilterRegistrationBean applicationContextIdFilter(final IThreadLifecycleManager threadLifecycleManager) {
        FilterRegistrationBean retVal = new FilterRegistrationBean();
        YourFilter filter = new YourFilter();
        retVal.setFilter(filter);
        retVal.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE + 2);
        return retVal;
    }
}

Note that by setting the order, you are able to controll the filters order.


The following snippet works and provides a Principal instance:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;

    Principal principal = req.getUserPrincipal();

    if (principal != null) {
        // do something with the Principal
    }

    chain.doFilter(request,  response);
}

inside doFilter:

HttpServletRequest request = (HttpServletRequest) request;
HttpSession session = request.getSession(false);

SecurityContextImpl sci = (SecurityContextImpl) session.getAttribute("SPRING_SECURITY_CONTEXT");

if (sci != null) {
        UserDetails cud = (UserDetails) sci.getAuthentication().getPrincipal();
        // do whatever you need here with the UserDetails
}

Hope this helps