2017-04-08 61 views
0

我正在运行一个SpringBoot应用程序,其根类注有@SpringBootApplication,@EnableAutoConfigurationSpring Boot:Autowired CRUDRepository null,在某些类中

我创建了一个UserRepositoryInterface接口,延伸CrudRepository接口与我的用户JPA对象。这个接口没有实现,而且还没有需要。本应用程序中没有任何配置文件。除了JPA数据库连接,但它的作品。

public interface UsersRepositoryInterface extends CrudRepository<User, Long> { 

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

而且我成功地将它自动装配到一些REST端点。问题出现时,我尝试将Autowire安装到我的安全类中。我正在尝试使用JWT进行身份验证,并且它可以工作。现在我想在登录过程中调用数据库,并且遇到问题。这里是类:

首先WebSecurityConfiguererAdapter类,其中我添加到过滤器的路径。注意与“new JWTLoginFilter”行了,这是我努力的Autowire类:

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

printlnJWTLoginFilter总是返回,当呼吁。

我错过了什么吗?

解决它:

现在的作品。

注释的JWTLoginFilter与

@Component("someName") 

而且随着

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

硬编码在JWTLoginFilter构造函数中的URL注入其在WebSecurityConfig,但我还是不得不从WebSecurityConfig自动装配的的AuthenticationManager进入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

+0

能否请您添加的项目结构? – tmarwen

回答

2

那么,你期望吗?您正在通过new关键字创建JWTLoginFilter。春天根本不做任何布线。你应该使这个过滤器@Bean@Component或其他任何使其成为spring bean并将其注入WebSecurityConfig以某种方式。

+0

我对Spring很新,所以我不知道。有趣。 我被愚弄了一下,但我似乎无法注入JWTLoginFilter类到WebSecurityConfig。有什么建议么? – kozeljko

+0

感谢您的建议,使其工作。 – kozeljko

1

我希望你的问题已经解决了。但我正在为面临同样问题的人添加一个示例代码片段供参考。

当我们的过滤器包含自动装配的依赖项,并且在使用new()的spring配置中实例化我们的过滤器时,不会自动装载它的依赖项,因为它不会是一个字符串管理bean。因此,我们需要在Spring应用程序配置类中自动调用我们的过滤器,而这又会自动调用其内部依赖关系。

PFB示例代码以供参考。

@SpringBootApplication 
public class MyApplication extends SpringBootServletInitializer { 

    @Autowired 
    private MyFilter myFilter; 

    public static void main(String[] args) { 
     SpringApplication.run(MyApplication.class, args); 
    } 

    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { 
     return builder.sources(MyApplication.class); 
    } 

    @Bean 
    public FilterRegistrationBean myFilterRegistration() { 
     FilterRegistrationBean registration = new FilterRegistrationBean(); 
     registration.setFilter(myFilter); 
     registration.addUrlPatterns("*"); 
     return registration; 
    } 
} 

筛选:

@Component 
public class MyFilter extends BaseFilter { 

    @Autowired 
    private EmployeeRepository employeeRepository; 

    //your code goes here 
     if(employeeRepository != null) { 
      System.out.println("employeeRepository is not null"); 
     } 

} 
相关问题