编辑:
来自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 DEBUG [080-exec-8] o.s.security.web.FilterChainProxy - 保护GET /auth/api/getBasicInfo
看起来会话ID不一致
我使用Spring Security内置的OAuth2社交登录选项, 我实现了一个OAuth2LoginSuccess类,并在其中实现了onAuthenticationSuccess方法。在该方法中,我获取与从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中进行调试,我可以看到一个有效的认证和所有用户详细信息。
登录后,我会重定向到主页,并向服务器发送身份验证请求以检查是否有已登录的用户。
问题在于,有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先返回未授权的错误信息,所以无法运行控制器。
非常感谢您的帮助。
org.springframework.security
打开调试日志记录,这应该可以让您知道出了什么问题。 - stringy05