我正在运行一个带有@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
。