一、问题背景
在使用oauth2获取用户登录信息的时候,如果用户未登录,就会出现
org.springframework.security.web.authentication.WebAuthenticationDetails cannot be cast to org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails
;
问题如下:
二、原因
问题出现在以下两句代码:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails();
通过打印 authentication
对象的 authentication.getAuthorities()
和authentication.getName()
属性我们可以发现:当用户未登录的时候,这两个属性的值分别为:[ROLE_ANONYMOUS]
、anonymousUser
,因此OAuth2AuthenticationDetails
在将 authentication.getDetails()
转型时出现无法转型的错误,知道为题所在以后我们就可以对症下药了。
三、解决办法
在调用 SysUser user = AuthUtil.getUserInfo();
方法获取用户登录信息之前,我们想要判断用户是否登录,判断方法如下:
public class UserLoginCheck {
public static boolean userIsLogin() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String userName = authentication.getName();
String role = authentication.getAuthorities().toString();
if ("anonymousUser".toUpperCase(Locale.ROOT).equals(userName.toUpperCase(Locale.ROOT))) {
return false;
}
return !"[ROLE_ANONYMOUS]".equals(role);
}
}
如果该方法返回false,则说明用户未登录,所以不要调用 SysUser user = AuthUtil.getUserInfo();
方法,直接给出提示即可;通过以上方法可以有效避免本文所遇见的问题。
PS:完整的AuthUtil.java
如下:
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import java.util.Map;
/**
* 自定义内容转化器获取用户额外信息
*
* @Author WXZ
* @Time 11:07
* @Date 2021.04.04
*/
public class AuthUtil {
/**
* 获取用户信息
*
* @return SYSUser
*/
public static SysUser getUserInfo() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails();
Map<String, Object> map = (Map<String, Object>) details.getDecodedDetails();
Map<String, String> userInfo = (Map<String, String>) map.get("userInfo");
SysUser user = new SysUser();
user.setId(userInfo.get("uid"));
user.setUsername(userInfo.get("username"));
user.setEmail(userInfo.get("email"));
user.setNickName(userInfo.get("nickName"));
user.setImageUrl(userInfo.get("imageUrl"));
user.setMobile(userInfo.get("mobile"));
return user;
}
}