Java Spring Security与;OAuth2
曾经有一个由SpringSecurity配置的单片java应用程序。每当我想要获得经过身份验证的用户时,Java Spring Security与;OAuth2,java,spring-boot,spring-security,oauth-2.0,spring-security-oauth2,Java,Spring Boot,Spring Security,Oauth 2.0,Spring Security Oauth2,曾经有一个由SpringSecurity配置的单片java应用程序。每当我想要获得经过身份验证的用户时,org.springframework.serurity.authentication.UsernamePasswordAuthenticationToken对象都会给出如下结果: User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal(); OAuth2Authenticat
org.springframework.serurity.authentication.UsernamePasswordAuthenticationToken
对象都会给出如下结果:
User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication();
LinkedHashMap linkedHashMap = (LinkedHashMap) oAuth2Authentication.getUserAuthentication().getDetails();
return linkedHashMap.get("principal");
这段代码一直正常工作,直到我将配置从Spring Security更改为Oauth2为了验证OAuth2,
org.springframework.serurity.OAuth2.provider.OAuth2Authentication
对象向我提供经过身份验证的用户,如下所示:
User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication();
LinkedHashMap linkedHashMap = (LinkedHashMap) oAuth2Authentication.getUserAuthentication().getDetails();
return linkedHashMap.get("principal");
因此,SecurityContextHolder.getContext().getAuthentication().getPrincipal()
的结果在OAuth2和Spring Security之间是不同的问题是什么:
我的问题是
1-我必须用重写每个where contains
SecurityContextHolder.getContext().getAuthentication().getPrincipal()
Object obj = SecurityContextHolder.getContext().getAuthentication();
if (obj instanceof OAuth2Authentication) {
OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication();
LinkedHashMap linkedHashMap = (LinkedHashMap) oAuth2Authentication.getUserAuthentication().getDetails();
linkedHashMap.get("principal");
LinkedHashMap result = linkedHashMap.get("principal");
User user = new User();
user.setId((Integer)result.get("id"));
user.setName((String)result.get("name"));
//As same way to set other its attributes@@@@@@@@@@
return user;
} else
return (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
2-正如上面用@@@@@@@@@标记的代码所示,用户对象的字段数接近20,因此我必须重复User.setField(result.get(“field”)
20次,这太单调了。解决方案是,我必须重写与上述代码相同的代码或其他我不知道的东西?是的,实际上,Spring Security和Spring Oauth2之间的这两种身份验证都是不同的。您可以创建某种@Service或@Component类来处理返回所需的内容。然后,可以在需要时将其注入/自动连接。因此,基本上,这个新类成为检索主体的唯一真理来源。如果您碰巧再次更改了安全实现,您的代码不应该受到影响,因为安全处理服务被一个新接口抽象掉了 见下面的示例:
@Service
public class Oauth2PrincipalService implements PrincipalService {
public User retreivePrincipalUser(){
//retreive user stuff here as you need using the oauth2 code you provided..
}
}
是否有可能使Oauth2的用户对象与SpringSecurity中的用户对象相同?我不需要修改我的代码吗?不,我去年用过这个,我了解到用户详细信息存储在地图中,正如你也发现的那样。在我的用例中,这是完美的,因为我能够从SpringAuthService微服务将自定义键/值对注入到userDetails映射中。我相信这样做是因为Oauth2不是特定于Spring的,而且这些用户详细信息字段可能因身份验证服务而异(即Facebook vs Google vs DIY)。在我的例子中,我使用Jackson将地图转换为我的POJO,因此在水合我的用户对象时不必设置所有这些字段。正如您在上面的评论中所说,您使用Jackson进行转换。你能给我jackson convertor的样品吗?@reza ramezani matin在这里看到了这个答案: