【发布时间】:2022-01-02 10:30:01
【问题描述】:
编辑:
来自 org.springframework.security 的日志:
2022-01-17 12:31:03.495 IST
2022-01-17 10:31:03.495 DEBUG [080-exec-5] o.s.s.w.s.SessionManagementFilter - Request requested invalid session id D5F8BA31A3D7466AK3K3C8EA26A4F037
Default
2022-01-17 12:31:03.495 IST
2022-01-17 10:31:03.495 DEBUG [080-exec-5] o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
Debug
2022-01-17 12:31:03.495 IST
"Request requested invalid session id D5F8BA31A3D7466AK3K3C8EA26A4F037"
Debug
2022-01-17 12:31:03.495 IST
"Set SecurityContextHolder to anonymous SecurityContext"
Default
2022-01-17 12:31:03.494 IST
2022-01-17 10:31:03.494 DEBUG [080-exec-5] o.s.s.w.c.SecurityContextPersistenceFilter - Set SecurityContextHolder to empty SecurityContext
Debug
2022-01-17 12:31:03.494 IST
"Set SecurityContextHolder to empty SecurityContext"
Default
2022-01-17 12:31:03.493 IST
2022-01-17 10:31:03.493 DEBUG [080-exec-5] o.s.security.web.FilterChainProxy - Securing GET /logo192.png
Debug
2022-01-17 12:31:03.493 IST
"Securing GET /logo192.png"
***但是如果我在日志中查看一些请求后我可以获得有效的身份验证:
调试 2022-01-17 12:31:03.945 IST “将 SecurityContextHolder 设置为 SecurityContextImpl [Authentication=OAuth2AuthenticationToken [Principal=com..security.oauth.CustomOAuth2User@, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [ RemoteIpAddress=***, SessionId=9438C880A19C93AADJI206B9B8B3386], Granted Authorities=[ROLE_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid ]]]" 调试
2022-01-17 12:31:03.945 IST “检索到 SecurityContextImpl [Authentication=OAuth2AuthenticationToken [Principal=com..security.oauth.CustomOAuth2User@, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress= ***, SessionId=9438C880A19C93AADJI206B9B8B3386], Granted Authorities=[ROLE_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]] ]" 调试
2022-01-17 12:31:03.945 IST “检索到 SecurityContextImpl [Authentication=OAuth2AuthenticationToken [Principal=com..security.oauth.CustomOAuth2User@, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress= ***, SessionId=9438C880A19C93AADJI206B9B8B3386], Granted Authorities=[ROLE_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]] ]" 默认
2022-01-17 12:31:03.944 IST 2022-01-17 10:31:03.944 调试 [080-exec-8] o.s.security.web.FilterChainProxy - 保护 GET /auth/api/getBasicInfo
看起来会话 id 不一致
我使用 spring security 内置的 oauth2 社交登录选项, 我使用 onAuthenticationSuccess 方法实现了一个 OAuth2LoginSuccess 类,并在其中获取与我从 oauth 获得的社交 ID 对应的用户:
CustomOAuth2User oAuth2User = (CustomOAuth2User) authentication.getPrincipal();
int sociald = oAuth2User.getAttribute("id");
User user = usersUtils.getUserBySocailId(socialId);
enter code here
// add the user details to the Auth
SecurityContextHolder.clearContext();
((OAuth2AuthenticationToken) authentication).setDetails(user);
SecurityContextHolder.getContext().setAuthentication(authentication);
如果我在 onAuthenticationSuccess 中进行调试,我可以看到包含所有用户详细信息的有效身份验证。
登录后我重定向到主页并向服务器发送 auth get 请求以检查是否有用户登录。
问题是 50% 的请求成功完成并且用户可以发出经过身份验证的请求。
但是另外 50% 我被自动重定向到登录页面,当我检查日志时看到 Spring boot 说用户未经身份验证并且身份验证丢失。
但在 onAuthenticationSuccess 中我总能看到正确的身份验证。
我的 ApplicationSecurityConfig 如下所示:
http.csrf().disable().authorizeRequests()
.antMatchers("/login*", "/signin/**", "/signup/**", "/oauth2/**").permitAll()
.antMatchers(Constants.ADMIN_PREFIX + "/**").hasRole("ADMIN")
.antMatchers(Constants.AUTH_PREFIX + "/**").hasAnyRole("ADMIN", "USER")
.antMatchers(Constants.PUBLIC_PREFIX + "/**").permitAll()
.anyRequest().permitAll()
.and()
.exceptionHandling().authenticationEntryPoint(new UnauthenticatedRequestHandler())
.and()
.formLogin()
.passwordParameter("password")
.usernameParameter("email")
.loginPage("/Login")
.loginProcessingUrl("/loginSecure").permitAll().successHandler(new LoginSuccess()).failureHandler(new FailureSuccess())
.and()
.oauth2Login()
.loginPage("/Login")
.userInfoEndpoint()
.userService(oAuth2UserService)
.and()
.successHandler(new OAuth2LoginSuccess())
.and()
.rememberMe()
.rememberMeParameter("remember-me")
.tokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(21))
.userDetailsService(this.applicationUserService)
.and()
.logout()
.clearAuthentication(true).invalidateHttpSession(true).logoutSuccessUrl("/login")
.addLogoutHandler(new CustomLogOutHandler());
这是我检查用户是否登录的功能:
@GetMapping(Constants.AUTH_PREFIX + "/checkUserLogged")
public Integer checkUserLogged(Authentication authentication,HttpServletRequest request) {
try{
if (authentication != null) {
User (User) authentication.getDetails();
if (user == null) {
return -1;
}
return user.getId();
}
}
catch (Exception e){
logger.warning(e.getLocalizedMessage());
}
return -1;
}
但是当问题发生时,它无法运行控制器,因为 spring security 之前返回未经授权的错误。
提前感谢您的帮助
【问题讨论】:
-
可以添加日志吗?
-
我不确定你在做什么,但我很想看到答案。
-
日志只是说没有经过身份验证的用户
-
Spring Security 在用户会话中持有 auth 上下文,所以也许有什么问题?无论哪种方式都打开 org.springframework.security 的调试日志记录,这应该可以让您知道哪里出错了
-
@stringy05 我将 org.springframework.security 更改为调试并得到以下身份验证丢失:2022-01-17 12:31:03.495 IST “请求请求的无效会话 id D5F8BAJKL23JKL32LLEA26A4F037”调试2022-01-17 12:31:03.495 IST “将 SecurityContextHolder 设置为匿名 SecurityContext” 默认 2022-01-17 12:31:03.494 IST 2022-01-17 10:31:03.494 调试 [080-exec-5] o.s.s.w.c.SecurityContextPersistenceFilter - 将 SecurityContextHolder 设置为空 SecurityContext 调试 2022-01-17 12:31:03.494 IST “将 SecurityContextHolder 设置为空 SecurityContext”
标签: java spring spring-boot spring-security spring-security-oauth2