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

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

问题描述

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

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


授权服务器/用户端点返回扩展名为org.springframework.security.core.userdetails.User的内容,例如一封电子邮件:

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


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

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

解决方案

解决方案是自定义UserInfoTokenServices

的实现

默认情况下,仅提取PRINCIPAL_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时,


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).

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?

解决方案

The solution is the implementation of a custom 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

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

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

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";
}

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;
}

Wiring:

@Autowired
private ResourceServerProperties sso;

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

!!UPDATE with Spring Boot 1.4 things are getting easier!!

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天全站免登陆