2015-07-12 4 views
6

Ecco il mio principale applicazione di configurazionePrimavera avvio Security Config - AuthenticationManager deve essere specificato

@SpringBootApplication 
public class Application { 

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

Ed ecco la mia domanda di sicurezza primavera config.

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

Ecco la mia TokenProcessingFilter che si estende UsernamePasswordAuthenticationFilter per il mio filtro di autenticazione personalizzato

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

tuttavia quando si esegue l'applicazione, ho incontrato questo messaggio di eccezione. Cosa mi manca?

Si è verificata un'eccezione durante l'esecuzione. null: InvocationTargetException: Impossibile avviare il contenitore incorporato; l'eccezione annidata è org.springframework.boot.context.embedded.EmbeddedServletContainerException: Impossibile avviare incorporato Tomcat: Errore durante la creazione di fagioli con nome definito nel file di [C 'tokenProcessingFilter': \ Users \ Kyel \ progetti \ app \ obiettivo \ classes \ org \ app \ testapp \ security \ TokenProcessingFilter.class]: Invocazione del metodo init fallita; l'eccezione annidata è java.lang.IllegalArgumentException: AuthenticationManager deve essere specificata

risposta

10

È necessario impostare la AuthenticationManager su TokenProcessingFilter. Invece di utilizzare @Component su TokenProcessingFilter, è sufficiente crearlo in SecurityConfig.

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

e

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