2017-04-08 45 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"); 
     } 

} 
相關問題