如何从 OAuth2 授权服务器/用户端点获取自定义用户信息 [英] How to get custom user info from OAuth2 authorization server /user endpoint

查看:114
本文介绍了如何从 OAuth2 授权服务器/用户端点获取自定义用户信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个配置了 @EnableResourceServer 注释的资源服务器,它通过 user-info-uri 参数引用授权服务器,如下所示:

I have a resource server configured with @EnableResourceServer annotation and it refers to authorization server via user-info-uri parameter as follows:

security:
  oauth2:
    resource:
      user-info-uri: http://localhost:9001/user


授权服务器/user 端点返回 org.springframework.security.core.userdetails.User 的扩展名,例如电子邮件:


Authorization server /user endpoint returns an extension of org.springframework.security.core.userdetails.User which has e.g. an email:

{  
   "password":null,
   "username":"myuser",
    ...
   "email":"me@company.com"
}


每当访问某个资源服务器端点时,Spring 都会通过调用授权服务器的 /user 端点来验证幕后的访问令牌,并且它实际上取回了丰富的用户信息(其中包含例如电子邮件信息,我已经验证Wireshark).


Whenever some resource server endpoint is accessed Spring verifies the access token behind the scenes by calling the authorization server's /user endpoint and it actually gets back the enriched user info (which contains e.g. email info, I've verified that with Wireshark).

所以问题是如何在没有明确第二次调用授权服务器的 /user 端点的情况下获取此自定义用户信息.Spring 是否在授权后将其存储在资源服务器本地的某个位置,或者如果没有现成可用的东西,那么实现这种用户信息存储的最佳方法是什么?

So the question is how do I get this custom user info without an explicit second call to the authorization server's /user endpoint. Does Spring store it somewhere locally on the resource server after authorization or what is the best way to implement this kind of user info storing if there's nothing available out of the box?

推荐答案

解决方案是实现自定义UserInfoTokenServices

https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/UserInfoTokenServices.java

只需将您的自定义实现作为 Bean 提供,它将被用来代替默认实现.

Just Provide your custom implementation as a Bean and it will be used instead of the default one.

在这个 UserInfoTokenServices 中,您可以按照自己的意愿构建 principal.

Inside this UserInfoTokenServices you can build the principal like you want to.

此 UserInfoTokenServices 用于从授权服务器的 /users 端点的响应中提取 UserDetails.正如你在

This UserInfoTokenServices is used to extract the UserDetails out of the response of the /usersendpoint of your authorization server. As you can see in

private Object getPrincipal(Map<String, Object> map) {
    for (String key : PRINCIPAL_KEYS) {
        if (map.containsKey(key)) {
            return map.get(key);
        }
    }
    return "unknown";
}

默认仅提取PRINCIPAL_KEYS 中指定的属性.这正是你的问题.您必须提取的不仅仅是用户名或您的财产名称.所以寻找更多的钥匙.

Only the properties specified in PRINCIPAL_KEYS are extracted by default. And thats exactly your problem. You have to extract more than just the username or whatever your property is named. So look for more keys.

private Object getPrincipal(Map<String, Object> map) {
    MyUserDetails myUserDetails = new myUserDetails();
    for (String key : PRINCIPAL_KEYS) {
        if (map.containsKey(key)) {
            myUserDetails.setUserName(map.get(key));
        }
    }
    if( map.containsKey("email") {
        myUserDetails.setEmail(map.get("email"));
    }
    //and so on..
    return myUserDetails;
}

接线:

@Autowired
private ResourceServerProperties sso;

@Bean
public ResourceServerTokenServices myUserInfoTokenServices() {
    return new MyUserInfoTokenServices(sso.getUserInfoUri(), sso.getClientId());
}

!!更新 Spring Boot 1.4 事情变得更容易了!!

使用 Spring Boot 1.4.0 a PrincipalExtractor 被引入.应实现此类以提取自定义主体(请参阅 Spring Boot 1.4 发行说明).

With Spring Boot 1.4.0 a PrincipalExtractor was introduced. This class should be implemented to extract a custom principal (see Spring Boot 1.4 Release Notes).

这篇关于如何从 OAuth2 授权服务器/用户端点获取自定义用户信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆