2015-07-12 66 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())