我正在运行一个带有@SpringBootApplication@EnableAutoConfiguration注释的根类的SpringBoot应用程序。

我创建了一个UserRepositoryInterface接口,该接口使用我的User JPA对象扩展了CrudRepository接口。该接口没有实现,也没有实现。此应用程序中都没有任何配置文件。除了JPA DB连接之外,都可以。

public interface UsersRepositoryInterface extends CrudRepository<User, Long> {

    // Query to search for users via email
    List<User> findByEmail(@Param("email") String email);
}


而且我已经成功将其自动连接到一些REST端点中。当我尝试将其自动连接到我的安全级别时,会出现问题。我正在尝试使用JWT进行身份验证,并且可以正常工作。现在,我想在登录过程中调用数据库,但遇到了问题。这些是类:

首先是WebSecurityConfiguererAdapter类,在这里我将路径添加到过滤器。请注意带有“ new JWTLoginFilter”的行,这是我尝试自动连线的类:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService userDetailsServ;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().authorizeRequests()

                //Allow options pre-flight request
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
            // Allow POST request to /login
                .antMatchers(HttpMethod.POST, "/login").permitAll()
            // Others must be authenticated
                .anyRequest().authenticated()
                .and()
            // We filter the api/login requests
                .addFilterBefore(new JWTLoginFilter("/login", authenticationManager()),
                    UsernamePasswordAuthenticationFilter.class)
            // And filter other requests to check the presence of JWT in header
                .addFilterBefore(new JWTAuthenticationFilter(),
                    UsernamePasswordAuthenticationFilter.class);
    }

   @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    // Change logging in from username+password to email+password
        auth.userDetailsService(userDetailsServ);
    }
}


还有JWTLoginFilter类。我省略了一些不相关的代码:

public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {

    @Autowired
    private UsersRepositoryInterface userRepo;

    public JWTLoginFilter(String url, AuthenticationManager authManager) {
        super(new AntPathRequestMatcher(url));
        setAuthenticationManager(authManager);
    }

    @Override
    public Authentication attemptAuthentication(
        HttpServletRequest req, HttpServletResponse response)
        throws AuthenticationException, IOException, ServletException {

        //Check if userRepo is injected
        if(userRepo == null) {
            System.out.println("Null");
        }

        AccountCredentials creds = new ObjectMapper()
            .readValue(req.getInputStream(), AccountCredentials.class);
        return getAuthenticationManager().authenticate(
            new UsernamePasswordAuthenticationToken(
                    creds.getEmail(),
                    creds.getPassword(),
                    Collections.emptyList()
            )
        );
    }
}


调用时,println中的JWTLoginFilter将始终返回Null。

我想念什么吗?

解决了它:

现在可以使用。

注释了JWTLoginFilter

@Component("someName")


并将其注入到WebSecurityConfig中

@Resource(name="someName")
private JWTLoginFilter myFilter;


在JWTLoginFilter构造函数中对URL进行了硬编码,但是我仍然必须将AuthenticationManager从WebSecurityConfig自动装配到JWTLoginFilter中。

首先必须使AuthenticationManager为Bean。在这里使用答案:How To Inject AuthenticationManager using Java Configuration in a Custom Filter

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


然后在此处注入答案:Spring Security authenticationmanager must be specified - for custom filter

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


同时删除

setAuthenticationManager(authManager);


在JWTLoginFilter的构造函数中

最佳答案

好吧,您期望什么?您正在通过JWTLoginFilter关键字创建new。 Spring根本不做任何接线。您应该将此过滤器设置为@Bean@Component或其他任何名称,以使其成为spring bean,然后以某种方式将其注入WebSecurityConfig

09-04 18:22