【发布时间】:2021-03-15 03:52:53
【问题描述】:
我正在尝试在我的服务组件中访问 HttpServletRequest 或 HttpSession。
服务组件是处理 github OAuth2 登录的地方。
以下是我的服务代码。
@RequiredArgsConstructor
@Service
public class GithubOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
private final UserRepository userRepository;
private final JwtTokenUtil jwtTokenUtil;
private final HttpServletRequest request;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
String userNameAttributeName = userRequest.getClientRegistration()
.getProviderDetails().getUserInfoEndpoint()
.getUserNameAttributeName();
OAuthAttributes attributes = OAuthAttributes.ofGithub(userNameAttributeName, oAuth2User.getAttributes());
User user = saveOrFindUser(attributes);
request.setAttribute("token", jwtTokenUtil.generateAccessToken(user.getId(), user.getRole()));
return new DefaultOAuth2User(
Collections.singleton(new SimpleGrantedAuthority(user.getRole().name())),
attributes.getAttributes(),
attributes.getNameAttributeKey()
);
}
private User saveOrFindUser(OAuthAttributes attributes) {
Optional<User> optionalUser = userRepository.findByEmail(attributes.getEmail());
if(optionalUser.isPresent()) {
return optionalUser.get();
} else {
return userRepository.save(attributes.toEntity());
}
}
}
下面是我的 Spring Security 配置类。
@RequiredArgsConstructor
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final GithubOAuth2UserService githubOAuth2UserService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.headers().frameOptions().disable()
.and().csrf().disable()
.cors().configurationSource(corsConfigurationSource())
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/v1/health-check")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/")
.and()
.oauth2Login()
.successHandler(authenticationSuccessHandler())
.failureHandler(authenticationFailureHandler())
.userInfoEndpoint()
.userService(githubOAuth2UserService);
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOriginPattern("*");
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
return new GithubOAuthExceptionHandler();
}
@Bean
public AuthenticationSuccessHandler authenticationSuccessHandler() {
return new GithubOAuthOnSuccessHandler();
}
}
我尝试使用 Lombok 的 @RequiredArgsConstructor 自动连接 HttpSession 和 HttpServletRequest,并尝试了以下方式。
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
我收到以下错误。
java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
我正在尝试访问 @Service 组件中的 HttpServletRequest 或 HttpSession,但我不明白为什么会发生此错误。
是否有任何额外的配置可以访问组件中的这些类?
我正在使用 Spring Boot 2.4.3。
【问题讨论】:
-
试试这个answer在类似问题中讨论过。
-
是的,但正如我上面提到的,类似问题的两个答案都对我不起作用。
-
如果答案对您不起作用,我想知道
RequestContextFilter是否在您的过滤器链中。过滤器在每个请求上填充RequestContextHolder。
标签: spring-boot servlets spring-security oauth-2.0