2014-11-21 247 views
2

为了使Spring和Rest能够使用完全安全和无状态令牌,我遵循以下教程。ActiveDirectoryLdapAuthenticationProvider:获取用户详细信息

http://captechconsulting.com/blog/jens-alm/versioned-validated-and-secured-rest-services-spring-40-4

我现在想的认证机制,使用Active Directory(ActiveDirectoryLdapAuthenticationProvider)转换。我的问题是,我无法弄清楚如何到达UserDetails,因此可以使用loadUserByUsername(userName)方法。

下面是导致我的问题的方法,注释行提供用户详细信息服务的过滤器,但我不知道如何使用Active Directory身份验证获取此信息。

private Filter authenticationFilter() { 
     HeaderAuthenticationFilter headerAuthenticationFilter = new HeaderAuthenticationFilter(); 

     //headerAuthenticationFilter.userDetailsService(userDetailsService()); 
     headerAuthenticationFilter.headerUtil(headerUtil); 
     return headerAuthenticationFilter; 
    } 

下面是我的Spring Security Configuration和使用的类。

SecurityConfig

@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; 
     } 
    } 

} 

HeaderAuthenticationFilter

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 && 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; 
    } 
} 

回答

0

春LDAP有一种叫LdapUserDetailsService,我要出去的肢体,并说,这可能是一个你必须要这样做。通常情况下,Spring具有合理的默认设置,我们只需要连接正确的事物。

+0

所以UserDetailsS​​ervice不是通过oringally自动装配的。这是我加入试图解决我的问题。我也尝试过使用LdapUserDetailsS​​ervice,但我不确定如何正确获取它的一个实例。当安全配置被创建并且使用由@EnableWebMvcSecurity标签证明的方法时,当前的UserDetailsS​​ervice对象被定义。 – 2014-11-21 18:41:52

相关问题