2015-07-12 61 views
6

這是我的主要應用程序配置春季啓動安全配置 - 的AuthenticationManager必須指定

@SpringBootApplication 
public class Application { 

    public static void main(String[] args) { 
     new SpringApplicationBuilder(Application.class) 
       .banner((environment, aClass, printStream) -> 
         System.out.println(stringBanner())) 
       .run(); 
    } 
} 

這是我的春天的安全應用程序配置。

@Configuration 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
@EnableWebMvcSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private WebServiceAuthenticationEntryPoint unauthorizedHandler; 

    @Autowired 
    private TokenProcessingFilter authTokenProcessingFilter; 

    @Bean 
    @Override 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
       .csrf() 
       .disable() 
       .sessionManagement() 
       .sessionCreationPolicy(SessionCreationPolicy.STATELESS) // Restful hence stateless 
       .and() 
       .exceptionHandling() 
       .authenticationEntryPoint(unauthorizedHandler) // Notice the entry point 
       .and() 
       .addFilter(authTokenProcessingFilter) // Notice the filter 
       .authorizeRequests() 
       .antMatchers("/resources/**", "/api/auth") 
       .permitAll() 
       .antMatchers("/greeting") 
       .hasRole("USER"); 
    } 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
     auth 
       .inMemoryAuthentication() 
       .withUser("user") 
       .password("password") 
       .roles("USER"); 
    } 
} 

這裏是我的TokenProcessingFilter,運行應用程序時伸出UsernamePasswordAuthenticationFilter爲我定製認證過濾器

@Component 
public class TokenProcessingFilter extends UsernamePasswordAuthenticationFilter { 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     HttpServletRequest httpRequest = this.getAsHttpRequest(request); 
     String authToken = this.extractAuthTokenFromRequest(httpRequest); 
     String userName = TokenUtils.getUserNameFromToken(authToken); 
     if (userName != null) {/* 
      UserDetails userDetails = userDetailsService.loadUserByUsername(userName);*/ 
      UserDetails userDetails = fakeUserDetails(); 
      if (TokenUtils.validateToken(authToken, userDetails)) { 
       UsernamePasswordAuthenticationToken authentication = 
         new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities()); 
       authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest)); 
       SecurityContextHolder.getContext().setAuthentication(authentication); 
       Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 
      } 
     } 
     chain.doFilter(request, response); 
    } 

    private HttpServletRequest getAsHttpRequest(ServletRequest request){ 
     if (!(request instanceof HttpServletRequest)) { 
      throw new RuntimeException("Expecting an HTTP request"); 
     } 
     return (HttpServletRequest) request; 
    } 


    private String extractAuthTokenFromRequest(HttpServletRequest httpRequest) { 
     /* Get token from header */ 
     String authToken = httpRequest.getHeader("x-auth-token"); 
     /* If token not found get it from request parameter */ 
     if (authToken == null) { 
      authToken = httpRequest.getParameter("token"); 
     } 
     return authToken; 
    } 

    private UserDetails fakeUserDetails(){ 
     UsernamePasswordAuthenticationToken authenticationToken = new 
       UsernamePasswordAuthenticationToken("user","password"); 

     List<SimpleGrantedAuthority> auth= new ArrayList<>(); 
     auth.add(new SimpleGrantedAuthority("USER")); 
     return new User("user","password",auth); 
    } 
} 

不過,我遇到這個異常信息。我錯過了什麼?

運行時發生異常。 null:InvocationTargetException: 無法啓動嵌入容器;嵌套的異常是 org.springframework.boot.context.embedded.EmbeddedServletContainerException: 無法啓動嵌入的Tomcat:與名稱 「tokenProcessingFilter」在文件 定義[C錯誤創建豆:\用戶\ kyel \項目\應用\目標\ class \ org \ app \ testapp \ security \ TokenProcessingFilter.class]: 調用init方法失敗;嵌套的例外是 java.lang.IllegalArgumentException異常:好的AuthenticationManager必須 指定

回答

10

您需要設置AuthenticationManagerTokenProcessingFilter。而不是在TokenProcessingFilter上使用@Component,只需在SecurityConfig中創建它。

@Bean 
TokenProcessingFilter tokenProcessingFilter() { 
    TokenProcessingFilter tokenProcessingFilter = new TokenProcessingFilter(); 
    tokenProcessingFilter.setAuthenticationManager(authenticationManager()); 
    return tokenProcessingFilter; 
} 

protected void configure(HttpSecurity http) throws Exception { 
    ... 
    .addFilter(tokenProcessingFilter())