这是我的主要应用程序配置
@SpringBootApplication public class Application { public static void main(String[] args) { new SpringApplicationBuilder(Application.class) .banner((environment, aClass, printStream) -> System.out.println(stringBanner())) .run(); } }
这是我的Spring安全应用程序配置。
@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:创建文件[C:\ Users \ kyel \ projects \ app \ target \ classes \ org \中定义的名称为’tokenProcessingFilter’的bean时出错app \ testapp \ security \ TokenProcessingFilter.class]:调用init方法失败;嵌套异常为java.lang.IllegalArgumentException:必须指定authenticationManager
您需要设置AuthenticationManageron TokenProcessingFilter。与其在TokenProcessingFilter上使用@Component,不如在SecurityConfig中创建它。
AuthenticationManager
TokenProcessingFilter
@Bean TokenProcessingFilter tokenProcessingFilter() { TokenProcessingFilter tokenProcessingFilter = new TokenProcessingFilter(); tokenProcessingFilter.setAuthenticationManager(authenticationManager()); return tokenProcessingFilter; }
和
protected void configure(HttpSecurity http) throws Exception { ... .addFilter(tokenProcessingFilter())