无法创建 AuthenticationManager bean

问题描述 投票:0回答:4

我们正在尝试使用令牌身份验证来使用@PreAuthorize。

当我们尝试使用@PreAuthorize时,SpringSecurity会在调用API之前弹出登录页面。我们不需要该页面,因为我们有自己的身份验证过程。

为了跳过该页面,我们添加了 @SpringBootApplication(exclusion = { SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class }) 在我们的主类上。

在此之后,登录页面被跳过,但是当我们触发它们时,我们所有的 API 都会给出错误,即身份验证需要在上下文中存在。

为此我们做了以下更改

@Configuration
public class MethodSecurityConfig extends WebSecurityConfigurerAdapter {

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

    @Override
    public void configure(HttpSecurity http) throws Exception {

        http.csrf().disable().addFilter(new AuthFilter(authenticationManagerBean())).authorizeRequests().anyRequest().permitAll();
        
    }
    
}

@Component
public class AuthFilter implements Filter {

    
    private AuthenticationManager authenticationManager;

    
    public AuthFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterchain)
            throws IOException, ServletException {

        final String authorizationHeader = ((HttpServletRequest) request).getHeader("Authorization");
        System.out.println("===========Filter called================");

        final Authentication authentication = authenticationManager
                .authenticate(SecurityContextHolder.getContext().getAuthentication());

        System.out.println("===========Authentication================"+authentication);
        
        if (authentication != null && !(authentication instanceof AnonymousAuthenticationToken)
                && authentication.isAuthenticated()) {

            // set authentication in security context holder
            SecurityContextHolder.getContext().setAuthentication(authentication);

        }
        filterchain.doFilter(request, response);
    }
}

现在,当我收到错误消息说 AuthenticationManager 不存在任何 bean 时。

我尝试了许多其他方法,但豆子仍然没有注入过滤器中

你能对此发表评论吗?

java spring spring-boot spring-mvc spring-security
4个回答
0
投票
@Configuration
public class MethodSecurityConfig extends WebSecurityConfigurerAdapter {

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

@Override
public void configure(HttpSecurity http) throws Exception {

    http.csrf().disable().addFilter(new AuthFilter(authenticationManagerBean())).authorizeRequests().anyRequest().permitAll();
    
    }

}

@Component
public class AuthFilter implements Filter {

@Autowired //--->use this
private AuthenticationManager authenticationManager;


public AuthFilter(AuthenticationManager authenticationManager) {
    this.authenticationManager = authenticationManager;
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterchain)
        throws IOException, ServletException {

    final String authorizationHeader = ((HttpServletRequest) request).getHeader("Authorization");
    System.out.println("===========Filter called================");

    final Authentication authentication = authenticationManager
            .authenticate(SecurityContextHolder.getContext().getAuthentication());

    System.out.println("===========Authentication================"+authentication);
    
    if (authentication != null && !(authentication instanceof AnonymousAuthenticationToken)
            && authentication.isAuthenticated()) {

        // set authentication in security context holder
        SecurityContextHolder.getContext().setAuthentication(authentication);

    }
    filterchain.doFilter(request, response);
}

}


0
投票

尝试这样的事情可能会有所帮助:

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

您还可以参考此 How To Inject AuthenticationManager using Java Configuration in a Custom Filter


0
投票

像这样尝试一次

@Configuration
public class MethodSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
     AuthFilter authFilter;

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

    @Override
    public void configure(HttpSecurity http) throws Exception {

        http.csrf().disable().addFilter(authFilter).authorizeRequests().anyRequest().permitAll();//change is here
        
    }
    
}

@Component
public class AuthFilter implements Filter {

    
    private AuthenticationManager authenticationManager;

    
    public AuthFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterchain)
            throws IOException, ServletException {

        final String authorizationHeader = ((HttpServletRequest) request).getHeader("Authorization");
        System.out.println("===========Filter called================");

        final Authentication authentication = authenticationManager
                .authenticate(SecurityContextHolder.getContext().getAuthentication());

        System.out.println("===========Authentication================"+authentication);
        
        if (authentication != null && !(authentication instanceof AnonymousAuthenticationToken)
                && authentication.isAuthenticated()) {

            // set authentication in security context holder
            SecurityContextHolder.getContext().setAuthentication(authentication);

        }
        filterchain.doFilter(request, response);
    }
}

不要使用 spring bean AuthFilter 创建 auth 过滤器的 Java 对象


0
投票

这个问题发生是因为 Spring Security 新版本做了一些更改

更改此方法:

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

对此:

@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
    return authenticationConfiguration.getAuthenticationManager();
}

并更改此:

    @Override
    public void configure(HttpSecurity http) throws Exception {
http.csrf().disable().addFilter(authFilter).authorizeRequests().anyRequest().permitAll();  
        }

这个风格

 @Bean
 public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authorize -> authorize.requestMatchers("/").authenticated().anyRequest().permitAll())
                .csrf(AbstractHttpConfigurer::disable)
return http.build();
}

HttpSecurity 的 configure() 方法被 filterChain 方法取代,如官方网站上所述:

© www.soinside.com 2019 - 2024. All rights reserved.