title: ActiveDirectoryLdapAuthenticationProvider: Getting UserDetails
body: <p>I followed the following tutorial in order to get Spring and Rest working with full security and stateless tokens. </p>
  
  <p><a href="http://captechconsulting.com/blog/jens-alm/versioned-validated-and-secured-rest-services-spring-40-4" rel="nofollow">http://captechconsulting.com/blog/jens-alm/versioned-validated-and-secured-rest-services-spring-40-4</a></p>
  
  <p>I am now trying to convert the authentications mechanism to use Active Directory (ActiveDirectoryLdapAuthenticationProvider). My issue is that I can not figure out how to get to the UserDetails so the  loadUserByUsername(userName) method can be utilized. </p>
  
  <p>Below is method that is causing me problems, the commented line provides the user detail service to the filter but I can not figure out how to get this information using Active Directory authentication. </p>
  
  <pre><code> private Filter authenticationFilter() {
          HeaderAuthenticationFilter headerAuthenticationFilter = new HeaderAuthenticationFilter();
  
          //headerAuthenticationFilter.userDetailsService(userDetailsService());
          headerAuthenticationFilter.headerUtil(headerUtil);
          return headerAuthenticationFilter;
      }
  </code></pre>
  
  <p>Below is my Spring Security Configuration and utilized class.</p>
  
  <p>SecurityConfig</p>
  
  <pre><code>@Configuration
  @EnableWebMvcSecurity
  public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
      private static final String ACCESS_DENIED_JSON = "{\"message\":\"You are not privileged to request this resource.\", \"access-denied\":true,\"cause\":\"AUTHORIZATION_FAILURE\"}";
      private static final String UNAUTHORIZED_JSON = "{\"message\":\"Full authentication is required to access this resource.\", \"access-denied\":true,\"cause\":\"NOT AUTHENTICATED\"}";
  
      @Autowired
      private HeaderUtil headerUtil;
  
  //    @Autowired
  //    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
  //        auth.inMemoryAuthentication().
  //
  //                withUser("user").password("password").roles("USER").
  //
  //                and().
  //
  //                withUser("admin").password("password").roles("USER", "ADMIN");
  //    }
  //    
      @Bean
      public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
          ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("domain.com", "ldap://ad.domain.com:389");
          provider.setConvertSubErrorCodesToExceptions(true);
          provider.setUseAuthenticationRequestCredentials(true);
  
          //provider.setAuthoritiesMapper( new NullAuthoritiesMapper()); // see http://comdynamics.net/blog/544/spring-security-3-integration-with-active-directory-ldap/
  
  
          return provider;
      }
  
  
      @Autowired
      protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
          auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
      }
  
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
  
          CustomAuthenticationSuccessHandler successHandler = new CustomAuthenticationSuccessHandler();
          successHandler.headerUtil(headerUtil);
  
          http.
                  addFilterBefore(corsFilter(), LogoutFilter.class).
                  addFilterBefore(authenticationFilter(), LogoutFilter.class).
  
                  csrf().disable().
  
                  formLogin().successHandler(successHandler).
                  loginProcessingUrl("/login").
  
                  and().
  
                  logout().
                  logoutSuccessUrl("/logout").
  
                  and().
  
                  sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).
  
                  and().
  
                  exceptionHandling().
                  accessDeniedHandler(new CustomAccessDeniedHandler()).
                  authenticationEntryPoint(new CustomAuthenticationEntryPoint()).
  
                  and().
  
                  authorizeRequests().
                  antMatchers(HttpMethod.POST, "/login").permitAll().
                  antMatchers(HttpMethod.POST, "/logout").authenticated().
  //                antMatchers(HttpMethod.GET, "/**").hasRole("USER").
  //                antMatchers(HttpMethod.POST, "/**").hasRole("ADMIN").
  //                antMatchers(HttpMethod.DELETE, "/**").hasRole("ADMIN").
                  antMatchers(HttpMethod.GET, "/**").authenticated().
                  antMatchers(HttpMethod.POST, "/**").authenticated().
                  antMatchers(HttpMethod.DELETE, "/**").authenticated().
                  anyRequest().authenticated();
  
      }
  
      private Filter authenticationFilter() {
          HeaderAuthenticationFilter headerAuthenticationFilter = new HeaderAuthenticationFilter();
  
          //headerAuthenticationFilter.userDetailsService(userDetailsService());
          headerAuthenticationFilter.headerUtil(headerUtil);
          return headerAuthenticationFilter;
      }
  
  
      private Filter corsFilter() {
          return new SimpleCORSFilter();
      }
  
      private static class CustomAccessDeniedHandler implements AccessDeniedHandler {
          @Override
          public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
  
              response.setContentType(Versions.V1_0);
              response.setStatus(HttpServletResponse.SC_FORBIDDEN);
              PrintWriter out = response.getWriter();
              out.print(ACCESS_DENIED_JSON);
              out.flush();
              out.close();
  
          }
      }
  
      private static class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
          @Override
          public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
  
              response.setContentType(Versions.V1_0);
              response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
              PrintWriter out = response.getWriter();
              out.print(UNAUTHORIZED_JSON);
              out.flush();
              out.close();
          }
      }
  
      private static class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
  
          private HeaderUtil headerUtil;
  
          @Override
          public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                              Authentication authentication) throws ServletException, IOException {
              try {
                  String token = headerUtil.createAuthToken(((LdapUserDetailsImpl) authentication.getPrincipal()).getUsername());
                  ObjectMapper mapper = new ObjectMapper();
                  ObjectNode node = mapper.createObjectNode().put("x-auth-token", token);
                  PrintWriter out = response.getWriter();
                  out.print(node.toString());
                  out.flush();
                  out.close();
              } catch (GeneralSecurityException e) {
                  throw new ServletException("Unable to create the auth token", e);
              }
              clearAuthenticationAttributes(request);
  
          }
  
          private void headerUtil(HeaderUtil headerUtil) {
              this.headerUtil = headerUtil;
          }
      }
  
  }
  </code></pre>
  
  <p>HeaderAuthenticationFilter</p>
  
  <pre><code>public class HeaderAuthenticationFilter extends GenericFilterBean {
  
  
      private UserDetailsService userDetailsService;
  
      private HeaderUtil headerUtil;
  
      @Override
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
  
          UserDetails userDetails = loadUserDetails((HttpServletRequest) request);
          SecurityContext contextBeforeChainExecution = createSecurityContext(userDetails);
  
          try {
              SecurityContextHolder.setContext(contextBeforeChainExecution);
              if (contextBeforeChainExecution.getAuthentication() != null &amp;&amp; contextBeforeChainExecution.getAuthentication().isAuthenticated()) {
                  String userName = (String) contextBeforeChainExecution.getAuthentication().getPrincipal();
                  headerUtil.addHeader((HttpServletResponse) response, userName);
              }
              filterChain.doFilter(request, response);
          }
          finally {
              // Clear the context and free the thread local
              SecurityContextHolder.clearContext();
          }
      }
  
      private SecurityContext createSecurityContext(UserDetails userDetails) {
          if (userDetails != null) {
              SecurityContextImpl securityContext = new SecurityContextImpl();
              Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities());
              securityContext.setAuthentication(authentication);
              return securityContext;
          }
          return SecurityContextHolder.createEmptyContext();
      }
  
      private UserDetails loadUserDetails(HttpServletRequest request) {
          String userName = headerUtil.getUserName(request);
  
          return userName != null
                  ? userDetailsService.loadUserByUsername(userName)
                  : null;
      }
  
      public void userDetailsService(UserDetailsService userDetailsService2) {
          this.userDetailsService = userDetailsService2;
      }
  
      public void headerUtil(HeaderUtil headerUtil) {
          this.headerUtil = headerUtil;
      }
  }
  </code></pre>