Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 必须指定Spring引导安全配置-authenticationManager_Java_Spring_Spring Security_Spring Boot - Fatal编程技术网

Java 必须指定Spring引导安全配置-authenticationManager

Java 必须指定Spring引导安全配置-authenticationManager,java,spring,spring-security,spring-boot,Java,Spring,Spring Security,Spring Boot,这是我的主要应用程序配置 @SpringBootApplication public class Application { public static void main(String[] args) { new SpringApplicationBuilder(Application.class) .banner((environment, aClass, printStream) ->

这是我的主要应用程序配置

@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);
    }
}
@组件
公共类TokenProcessingFilter扩展UsernamePasswordAuthenticationFilter{
@凌驾
public void doFilter(ServletRequest请求、ServletResponse响应、FilterChain链)抛出IOException、ServletException{
HttpServletRequest httpRequest=this.getAsHttpRequest(请求);
String authToken=this.extractAuthTokenFromRequest(httpRequest);
字符串userName=TokenUtils.getUserNameFromToken(authToken);
如果(用户名!=null){/*
UserDetails UserDetails=userDetailsService.loadUserByUsername(用户名)*/
UserDetails UserDetails=fakeUserDetails();
if(TokenUtils.validateToken(authToken,userDetails)){
UsernamePasswordAuthenticationToken身份验证=
新的UsernamePasswordAuthenticationToken(userDetails.getUsername(),userDetails.getPassword(),userDetails.GetAuthories());
authentication.setDetails(新的WebAuthenticationDetailsSource().buildDetails(httpRequest));
SecurityContextHolder.getContext().setAuthentication(身份验证);
对象主体=SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}
}
链式过滤器(请求、响应);
}
私有HttpServletRequest getAsHttpRequest(ServletRequest请求){
if(!(HttpServletRequest的请求实例)){
抛出新的RuntimeException(“需要HTTP请求”);
}
返回(HttpServletRequest)请求;
}
私有字符串extractAuthTokenFromRequest(HttpServletRequest httpRequest){
/*从标头获取令牌*/
字符串authToken=httpRequest.getHeader(“x-auth-token”);
/*如果找不到令牌,请从请求参数获取它*/
if(authToken==null){
authToken=httpRequest.getParameter(“token”);
}
返回authToken;
}
私有UserDetails fakeUserDetails(){
UsernamePasswordAuthenticationToken authenticationToken=新建
UsernamePasswordAuthenticationToken(“用户”、“密码”);
List auth=new ArrayList();
授权添加(新的SimpleGrantedAuthority(“用户”);
返回新用户(“用户”、“密码”、身份验证);
}
}
但是,在运行应用程序时,我遇到此异常消息。我错过了什么

运行时发生异常。null:InvocationTargetException: 无法启动嵌入式容器;嵌套异常是 org.springframework.boot.context.embedded.EmbeddedServletContainerException: 无法启动嵌入式Tomcat:创建名为的bean时出错 文件中定义了“tokenProcessingFilter” [C:\Users\kyel\projects\app\target\classes\org\app\testapp\security\TokenProcessingFilter.class]: 调用init方法失败;嵌套异常是 java.lang.IllegalArgumentException:authenticationManager必须为 指定的


您需要在
TokenProcessingFilter
上设置
AuthenticationManager
。不要在TokenProcessingFilter上使用@Component,只需在SecurityConfig中创建它

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


为了保留组件注释,您必须从AbstractAuthenticationProcessingFilter中重写setAuthenticationManager,并自动关联如下参数:

@Component
public class TokenProcessingFilter extends UsernamePasswordAuthenticationFilter {

    //...

    @Override
    @Autowired
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        super.setAuthenticationManager(authenticationManager);
    }

    //...

}

为什么要创建bean呢?如果这样,是否显式调用该方法?
@Component
public class TokenProcessingFilter extends UsernamePasswordAuthenticationFilter {

    //...

    @Override
    @Autowired
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        super.setAuthenticationManager(authenticationManager);
    }

    //...

}