如何从 OAuth2 授权服务器/用户端点获取自定义用户信息

2023-12-31

我有一个资源服务器配置为@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":"[email protected] /cdn-cgi/l/email-protection"
}


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

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


解决方案是实施自定义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 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 提供,它将被用来代替默认的实现。

在此 UserInfoTokenServices 内,您可以构建principal就像你想要的那样。

此 UserInfoTokenServices 用于从响应中提取 UserDetails/users您的授权服务器的端点。正如你所看到的

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

仅指定的属性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;
}

Wiring:

@Autowired
private ResourceServerProperties sso;

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

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

使用 Spring Boot 1.4.0主要提取器 http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/api/org/springframework/boot/autoconfigure/security/oauth2/resource/PrincipalExtractor.html被介绍了。应该实现此类来提取自定义主体(请参阅Spring Boot 1.4 发行说明 https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.4-Release-Notes#principalextractor).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从 OAuth2 授权服务器/用户端点获取自定义用户信息 的相关文章

随机推荐

  • 使用php杀死Linux中的用户进程

    我正在尝试编写一个 php 脚本来杀死 redhat 机器中的用户 我知道有可能 而且非常不安全 让apache能够以root身份执行操作 但我需要能够从网页上杀死任何用户 是否有人有任何好的工作脚本或给我指出一个地方找到更多信息吗 我可以
  • 如何绕过字符串在文本文件中执行加法

    我将 csv 文件转换为文本文件 我想在文本文件中添加数字 当我运行我的代码时出现错误 假设错误代码我想编写逻辑来绕过我的字符串并仅添加数值 import csv csv file Annual Budget csv txt file an
  • CWnd::CreateDlgIndirect 离开 m_hWnd==NULL

    我正在处理的对话框未显示 使用 CWnd CreateDlgIndirect LPCDLGTEMPLATE lpDialogTemplate CWnd pParentWnd HINSTANCE hInst 对 CreateDlgIndire
  • Ubuntu - Anaconda 2020.02 - 命名空间 Gtk 不可用

    这是在 Ubuntu 16 04 LTS 上 我遇到了与这个问题相同的问题 ValueError 命名空间 Gtk 不可用 https stackoverflow com questions 56823857 valueerror name
  • 保持帐户登录

    我们有一个内部控制面板 办公室的所有员工都全天登录 包括客户服务 我希望对其进行设置 以便在会话到期之前让您保持登录状态 1 小时 如何在 PHP ini 中更改此设置 在我明白将保持会话打开直到浏览器窗口关闭之前我做了一个更改 但它没有坚
  • 使用 plt.plot 与 plt.hist 的彩色图像直方图差异 [Python]

    我使用下面的代码使用两种方法生成彩色图像的直方图 方法一 使用cv2 calcHist 函数计算频率 使用 plt plot 生成频率的线图 方法 2 使用plt hist 函数计算并生成直方图 我添加了bin 250以便2个直方图一致 观
  • 如何在 Python 中将 Excel 工作表另存为 HTML?

    我正在与这个图书馆合作XlsxWriter https pypi python org pypi XlsxWriter 我打开了一本工作簿并在其中写了一些内容 考虑官方的例子 http xlsxwriter readthedocs org
  • ERR_BAD_SSL_CLIENT_AUTH_CERT

    我们在浏览大多数 https 网站时开始遇到问题 示例包括 https technet microsoft com https technet microsoft com https mail google com https mail g
  • 是否可以使用 addEventListener 调用类方法?

    只是我一直想知道的事情 在第二个参数中 addEventListener方法 您可以调用 自定义 类方法 而不是函数吗 即像下面这样的东西会起作用吗 var object new ClassName document getElementB
  • UIScrollView 滚动时重绘内容?

    我知道有一个属性或方法可以使scrollview uiview 在滚动时调用drawRect 方法 由于性能原因 默认情况下处于禁用状态 但我需要启用它 我不记得该方法的名称 因此我无法寻找它 有人知道我在寻找什么吗 提前致谢 我建议使用s
  • QTreeWidget 内的 QT 可点击小部件(可能是按钮)?

    我有一个基本上是 QTreeWidget 的表 我想在其中放置一个可点击的小部件 可能是一个按钮 每行都是一个 QTreeWidgetItem 但我不知道如何使用 QTreeWidgetItem setData 添加按钮 这是对 Qt 文档
  • 无法从 C# 中的 .Net 套接字正确读取数据

    我有一个使用套接字通信的 C 客户端和服务器类 服务器看起来像这样 public class AsyncTcpServer private Socket server socket private Socket client socket
  • iPhone OpenGL ES 不正确的 alpha 混合

    我在 iPhone 上使用 openGL ES 时遇到了不正确的 alpha 混合结果的问题 这是我创建纹理对象的代码 glGenTextures 1 tex name glBindTexture GL TEXTURE 2D tex nam
  • Windows CDROM 弹出

    有谁知道在 Windows 2000 或更高版本上以编程方式关闭 CD 托盘的方法吗 打开 CD 托盘存在 但我似乎无法关闭它 尤其是在 W2k 下 如果可能的话 我特别寻找一种从批处理文件中执行此操作的方法 但 API 调用也可以 我有点
  • CSS 向右浮动无法正常工作

    我的右侧浮子没有按我预期的方式工作 我希望我的按钮能够很好地对齐到一行上方文本的右侧 div style padding 5px border bottom width 1px border bottom color gray border
  • 在帖子上发帖时遇到“(#100) 查找请求的故事时出错”

    我正在使用 Graph API 来获取用户被标记的帖子 然后通过以下方式对帖子进行点赞POSTing to post id likes 然而 即使该帖子显然存在 因为我能够检索到post id 发出like时 遇到如下错误 100 Erro
  • C# 跟踪截断长消息

    在 C 中 我启用了跟踪和网络跟踪源
  • 是否有一种算法可以将威胁范围与二维网格上的任意移动范围相结合?

    我正在构建一个简单的基于 2D 网格的游戏 并正在寻找一种方法来计算每个角色可以在游戏板上施加的 威胁 区域 当前地点的威胁很容易计算 这是下面的红色菱形 但我希望将这些信息与任意 可以步行到这里 区域 橙色 结合起来 该算法一起会给我我的
  • 如何链接docker容器?

    我尝试链接我的 docker 容器 但似乎在访问时出错 我的结构如下 数据库docker Mysql 容器名称是um mysql 后端 docker Tomcat 镜像名称为cz um app 前端 docker Nginx 镜像名称为cz
  • 如何从 OAuth2 授权服务器/用户端点获取自定义用户信息

    我有一个资源服务器配置为 EnableResourceServer注释 它通过以下方式引用授权服务器user info uri参数如下 security oauth2 resource user info uri http localhos