我使用JWT (Json Web Token)
来保护我的Spring启动应用程序。
有一个不接受任何bean的课程。
首先,我想也许我想要注入的bean没有定义。所以我决定使用spring ApplicationContext
打印bean名称列表。但我发现即使ApplicationContext
也不能注入这个类:
知道为什么会这样吗?
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
@Autowired
private TokenAuthenticationService tokenAuthenticationService;
@Autowired
private ApplicationContext applicationContext;
public JWTLoginFilter(String url, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authManager);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest req,
HttpServletResponse res) throws AuthenticationException,
IOException, ServletException {
CustomUserDetails creds = new ObjectMapper().readValue(
req.getInputStream(), CustomUserDetails.class);
return getAuthenticationManager().authenticate(
new UsernamePasswordAuthenticationToken(creds.getUsername(),
creds.getPassword()));
}
@Override
protected void successfulAuthentication(HttpServletRequest req,
HttpServletResponse res, FilterChain chain, Authentication auth) {
java.util.List s = Arrays.asList(applicationContext.getBeanDefinitionNames());
System.out.println(s);
tokenAuthenticationService.addAuthentication(res, auth.getName());
}
}
答案 0 :(得分:3)
JWTLoginFilter
也必须是一个bean,以允许Spring注入其他bean。目前,Spring对此没有任何控制权。使用@Component
/ @Service
/ @Repository
注释标记班级(取决于您的过滤器扮演的角色,我认为@Component
是一个不错的选择)将解决问题。
编辑1:
JWTLoginFilter需要找不到类型
java.lang.String
的bean。组件可以有构造函数吗?
问题:Spring试图使用双参数构造函数来创建一个bean,并且期望这两个参数是它的bean。但事实并非如此,因为没有String
类的bean。
解决方案:您应该定义一个非参数构造函数,以允许Spring在没有问题的情况下创建一个未调整的实例。然后创建setter以提供Spring将用于注入所需依赖项的方法。
编辑2:
解决方法是定义一个String
bean(在@Configuration
类中),它将被注入JWTLoginFilter
构造函数,但我不确定你的过滤器是否需要一些外部依赖。
@Bean
public String getStringPatternBean() {
return "pattern";
}
答案 1 :(得分:0)
好吧,我终于决定改变这些类的设计方式。我在TokenAuthenticationService
静态内部创建了方法。