【发布时间】:2019-06-26 20:33:26
【问题描述】:
我有一个位于控制器前面的请求过滤器。此过滤器检索用户配置文件并在具有请求范围的 userProfile 组件上设置属性,然后传递到下一个过滤器。
当尝试从过滤器内部访问userProfile 时,该属性尚未成功自动装配。
我在尝试从过滤器内部自动连接 userProfile 时看到以下异常:
org.springframework.beans.factory.BeanCreationException:创建名为“scopedTarget.userProfile”的bean时出错:当前线程的范围“请求”不活动;如果您打算从单例中引用它,请考虑为该 bean 定义一个作用域代理;嵌套异常是 java.lang.IllegalStateException:未找到线程绑定请求:您是指实际 Web 请求之外的请求属性,还是在原始接收线程之外处理请求?如果您实际上是在 Web 请求中操作并且仍然收到此消息,则您的代码可能在 DispatcherServlet 之外运行:在这种情况下,请使用 RequestContextListener 或 RequestContextFilter 来公开当前请求。
但是,当尝试从控制器内部访问 userProfile 时,该属性已成功自动装配。
如何在过滤器中成功自动装配userProfile 组件?
请求过滤器:
@Component
public class JwtAuthenticationFilter extends GenericFilterBean implements Filter {
@Autowired
public UserProfile userProfile;
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain next) throws IOException, ServletException {
....
userProfile
.username(authorizedUser.username())
.email(authorizedUser.email())
.firstName(authorizedUser.firstName())
.lastName(authorizedUser.lastName());
}
}
控制器:
@CrossOrigin
@RestController
@RequestMapping("/users")
public class UsersController {
@Autowired
public UserProfile userProfile;
@GetMapping(
path = "/current",
produces = MediaType.APPLICATION_JSON_VALUE
)
@ResponseStatus(HttpStatus.OK)
public String currentUser() throws ResponseFormatterException {
System.out.println(userProfile.email());
}
}
用户个人资料:
@Component
@RequestScope
public class UserProfile {
@Getter @Setter
@Accessors(fluent = true)
@JsonProperty("username")
private String username;
@Getter @Setter
@Accessors(fluent = true)
@JsonProperty("email")
private String email;
@Getter @Setter
@Accessors(fluent = true)
@JsonProperty("firstName")
private String firstName;
@Getter @Setter
@Accessors(fluent = true)
@JsonProperty("lastName")
private String lastName;
}
安全配置:
@Configuration
@EnableWebSecurity
public class SecurityConfigurator extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticatingFilter jwtAuthenticatingFilter;
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(getAuthenticator());
}
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/actuator/**")
.antMatchers("/favicon.ico");
}
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/actuator/**").permitAll()
.antMatchers("/favicon.ico").permitAll()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.addFilterBefore(getFilter(), SessionManagementFilter.class)
.authenticationProvider(getAuthenticator())
.exceptionHandling()
.authenticationEntryPoint(new HttpAuthenticationEntryPoint());
}
protected AbstractAuthenticator getAuthenticator() {
return new JwtAuthenticator();
}
protected AuthenticatingFilter getFilter() {
return jwtAuthenticatingFilter;
}
}
【问题讨论】:
-
为我工作(spring boot 2.1.6.RELEASE),你确定你没有其他可能导致错误的重要部分吗?可能在某处手动启动一个新线程?或者也许是 hystrix 命令?
-
@Shadov 我在
2.1.4.RELEASE。我没有搞乱线程,也没有hystrix命令。我正在环顾四周,看看是否有什么东西可能会影响 DI,但没有任何反应。 -
@Shadov 我找到了一个安全配置,我会将它添加到我的问题中。
-
很多事情都可能出错,如果没有看到一切就很难说。注释掉SecurityConfig上的两个注解,看看你的过滤器是否有效,这个类是否有问题就清楚了。并在您的项目中搜索
new JwtAuthenticationFilter()和@Async,确保没有人这样做。 -
@Shadov 我知道 :( 但绝对没有
new JwtAuthenticationFilter()任何地方。当我删除这些注释时,我的身份验证过滤器根本不会受到影响。不知道这是否有帮助?
标签: java spring spring-boot dependency-injection autowired