spring security authorization server 定制令牌和用户信息

版本

1.2.1

定制方法

默认用户信息Mapper只针对用户ID,电子邮件,电话,个人档案等字段进行处理,如需在用户信息端点返回自定义的字段可通过以下方法定制Mapper

@Bean
public OAuth2TokenCustomizer<JwtEncodingContext> jwtTokenCustomizer() {return (context) -> {if (OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType())) {context.getClaims().claims((claims) -> {// 在令牌中添加了角色声明信息,默认用户信息端点Mapper不会进行处理Set<String> roles = AuthorityUtils.authorityListToSet(context.getPrincipal().getAuthorities()).stream().map(c -> c.replaceFirst("^ROLE_", "")).collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet));claims.put("roles", roles);});}};
}@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http
) {...// 定制MapperFunction<OidcUserInfoAuthenticationContext, OidcUserInfo> userInfoMapper = (context) -> {OidcUserInfoAuthenticationToken authentication = context.getAuthentication();JwtAuthenticationToken principal = (JwtAuthenticationToken) authentication.getPrincipal();// 解析JWT令牌中的所有声明信息return new OidcUserInfo(principal.getToken().getClaims());};http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)// 启用OpenID Connect 1.0.oidc(oidc->{oidc.userInfoEndpoint(userInfo->{userInfo.userInfoMapper(userInfoMapper);});});
}

源码

userInfoMapper 默认配置

  • OpenID Connect 用户信息认证器
    org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcUserInfoAuthenticationProvider
public final class OidcUserInfoAuthenticationProvider implements AuthenticationProvider {...// 用户信息Mapper默认值private Function<OidcUserInfoAuthenticationContext, OidcUserInfo> userInfoMapper = new DefaultOidcUserInfoMapper();...private static final class DefaultOidcUserInfoMapper implements Function<OidcUserInfoAuthenticationContext, OidcUserInfo> {// 电子邮件声明字段private static final List<String> EMAIL_CLAIMS = Arrays.asList(StandardClaimNames.EMAIL,StandardClaimNames.EMAIL_VERIFIED);// 电话声明字段private static final List<String> PHONE_CLAIMS = Arrays.asList(StandardClaimNames.PHONE_NUMBER,StandardClaimNames.PHONE_NUMBER_VERIFIED);// 个人档案声明字段private static final List<String> PROFILE_CLAIMS = Arrays.asList(StandardClaimNames.NAME,StandardClaimNames.FAMILY_NAME,StandardClaimNames.GIVEN_NAME,StandardClaimNames.MIDDLE_NAME,StandardClaimNames.NICKNAME,StandardClaimNames.PREFERRED_USERNAME,StandardClaimNames.PROFILE,StandardClaimNames.PICTURE,StandardClaimNames.WEBSITE,StandardClaimNames.GENDER,StandardClaimNames.BIRTHDATE,StandardClaimNames.ZONEINFO,StandardClaimNames.LOCALE,StandardClaimNames.UPDATED_AT);@Overridepublic OidcUserInfo apply(OidcUserInfoAuthenticationContext authenticationContext) {OAuth2Authorization authorization = authenticationContext.getAuthorization();OidcIdToken idToken = authorization.getToken(OidcIdToken.class).getToken();OAuth2AccessToken accessToken = authenticationContext.getAccessToken();// 获取scope请求的声明信息Map<String, Object> scopeRequestedClaims = getClaimsRequestedByScope(idToken.getClaims(),accessToken.getScopes());// 使用请求的声明信息创建用户信息对象return new OidcUserInfo(scopeRequestedClaims);}private static Map<String, Object> getClaimsRequestedByScope(Map<String, Object> claims, Set<String> requestedScopes) {Set<String> scopeRequestedClaimNames = new HashSet<>(32);// 用户IDscopeRequestedClaimNames.add(StandardClaimNames.SUB);// 根据请求的SCOPE添加字段if (requestedScopes.contains(OidcScopes.ADDRESS)) {scopeRequestedClaimNames.add(StandardClaimNames.ADDRESS);}if (requestedScopes.contains(OidcScopes.EMAIL)) {scopeRequestedClaimNames.addAll(EMAIL_CLAIMS);}if (requestedScopes.contains(OidcScopes.PHONE)) {scopeRequestedClaimNames.addAll(PHONE_CLAIMS);}if (requestedScopes.contains(OidcScopes.PROFILE)) {scopeRequestedClaimNames.addAll(PROFILE_CLAIMS);}// 根据请求的SCOPE字段过滤信息Map<String, Object> requestedClaims = new HashMap<>(claims);requestedClaims.keySet().removeIf(claimName -> !scopeRequestedClaimNames.contains(claimName));return requestedClaims;}}
}
  • OpenID Connect 用户信息端点配置器
    org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OidcUserInfoEndpointConfigurer
public final class OidcUserInfoEndpointConfigurer extends AbstractOAuth2Configurer {...// userInfoMapper配置入口public OidcUserInfoEndpointConfigurer userInfoMapper(Function<OidcUserInfoAuthenticationContext, OidcUserInfo> userInfoMapper) {this.userInfoMapper = userInfoMapper;return this;}... // 初始化安全配置@Overridevoid init(HttpSecurity httpSecurity) {// 应用用户信息端点URI安全配置AuthorizationServerSettings authorizationServerSettings = OAuth2ConfigurerUtils.getAuthorizationServerSettings(httpSecurity);String userInfoEndpointUri = authorizationServerSettings.getOidcUserInfoEndpoint();this.requestMatcher = new OrRequestMatcher(new AntPathRequestMatcher(userInfoEndpointUri, HttpMethod.GET.name()),new AntPathRequestMatcher(userInfoEndpointUri, HttpMethod.POST.name()));// 应用用户认证器List<AuthenticationProvider> authenticationProviders = createDefaultAuthenticationProviders(httpSecurity);if (!this.authenticationProviders.isEmpty()) {authenticationProviders.addAll(0, this.authenticationProviders);}this.authenticationProvidersConsumer.accept(authenticationProviders);authenticationProviders.forEach(authenticationProvider ->httpSecurity.authenticationProvider(postProcess(authenticationProvider)));}// 创建 OpenID Connect 用户信息认证器private List<AuthenticationProvider> createDefaultAuthenticationProviders(HttpSecurity httpSecurity) {List<AuthenticationProvider> authenticationProviders = new ArrayList<>();OidcUserInfoAuthenticationProvider oidcUserInfoAuthenticationProvider =new OidcUserInfoAuthenticationProvider(OAuth2ConfigurerUtils.getAuthorizationService(httpSecurity));// 如果存在定制的userInfoMapper,则替换默认值if (this.userInfoMapper != null) {oidcUserInfoAuthenticationProvider.setUserInfoMapper(this.userInfoMapper);}authenticationProviders.add(oidcUserInfoAuthenticationProvider);return authenticationProviders;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/600603.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker kingbase

docker kingbase run 命令 docker run -tid \ -e ENABLE_CIyes \ -e NEED_STARTyes \ -e DB_MODEoracle \ -e DB_USERkingbase \ -e DB_PASSWORD123456 \ --privileged \ -p 4321:54321 \ -v /home/admin/SoftWare/volume/kingbase/userdata/data:/home/kingbase/userdata/da…

【唐山海德教育】成人高校的毕业证书有何用途?

答&#xff1a;成人高等教育毕业生在干部聘用、职称评审、工资待遇等方面与普通高等教育同层次毕业生同等对待。本科毕业可申请学士学位&#xff0c;与其它国家承认的大学专&#xff08;本&#xff09;毕业证书具有同等效力&#xff0c;含金量一样&#xff0c;在使用上也是相同…

如何在 Xftp 中使用自定义编辑器

1、简介 很多时候我们使用 Xshell 远程登录linux服务器进行文本编辑&#xff0c;通过命令行窗口难以进行快速编辑&#xff0c;因此&#xff0c;借助 Xftp 工具&#xff0c;指定文本编辑器&#xff0c;能够快速帮助我们实现文本编辑。 2、Xftp 使用 在上文中&#xff08;https:…

2024PMP考试新考纲-【人员领域】近期典型真题和超详细解析(4)

今天华研荟继续为您分享PMP新考纲下的【人员People领域】近年真题&#xff0c;帮助大家举一反三&#xff0c;一次性通过2024年的PMP考试。 昨天有个小伙伴问我说2024年3月份的PMP考试共有多少题&#xff0c;其中关于人员的有多少题&#xff1f;根据官方发布的消息&#xff0c;华…

如何在 C# 12 中使用主构造函数

C# 12 中最引人注目的新功能之一是对主构造函数的支持。主构造函数的概念并不新鲜。包括 Scala、Kotlin 和 OCaml 在内的多种编程语言都支持直接在声明类的位置集成构造函数参数。 在本文中&#xff0c;我们将仔细研究主构造函数以及如何在 C# 12 中使用它们。若要运行本文中提…

即插即用篇 | YOLOv8 Gradio 前端展示页面 | 支持 【分类】【检测】【分割】【关键点】 任务

分类任务效果 分割任务效果 检测任务效果 关键点任务效果 使用方法 Gradio 是一个开源库,旨在为机器学习模型提供快速且易于使用的网页界面。它允许开发者和研究人员轻松地为他们的模型创建交互式的演示,使得无论技术背景如何的人都可以方便地试用和理解这些模型。使用Gradi…

【BCC动态跟踪PostgreSQL】

BPF Compiler Collection (BCC)是基于eBPF的Linux内核分析、跟踪、网络监控工具。其源码存放于GitCode - 开发者的代码家园 想要监控PostgreSQL数据库的相关SQL需要在编译PostgreSQL的时候开启dtrace。下文主要介绍几个和PostgreSQL相关的工具,其他工具可根据需求自行了解。 …

【QT 自研上位机 与 ESP32下位机联调>>>串口控制GPIO-基础样例-联合文章】

【QT 自研上位机 与 ESP32下位机联调&#xff1e;&#xff1e;&#xff1e;串口控制GPIO-基础样例-联合文章】 1、概述2、实验环境3、 自我总结4、 实验过程1、验证上位机QT程序1、下载样例代码2、修改qt程序3、运行测试验证 2、验证下位机ESP32程序1、下载样例代码2、更改ESP3…

55.网游逆向分析与插件开发-游戏增加自动化助手接口-自动药水设定功能的逆向分析

内容来源于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;项目需求与需求拆解-CSDN博客 之前在找到过一个虚函数&#xff0c;每个按钮的都有一个实现机制&#xff0c;参考这里游戏结束过程的逆向分析 实际上找起来会不会用上不知道&#xff0c;接下来开始逆…

go语言 json marshal和unmarshal序列化字节切片和反序列化对象

json.Marshal 和 json.Unmarshal 是 Go 语言标准库中用于 JSON 编码和解码的函数。 - json.Marshal 用于将 Go 对象转换为 JSON 格式的字节切片。 go package main import ( "encoding/json" "fmt" ) type Person struct { Name string json:"name&qu…

二维码地址门牌系统技术服务:让您的生活更便捷,一码通行,安全无忧

文章目录 前言一、融合二维码技术与门牌的便捷服务二、手机开门便捷功能三、智能化安全保障四、智能化、便捷化的新型技术 前言 在数字化时代&#xff0c;二维码门牌系统技术应运而生&#xff0c;为了满足人们对安全、便捷生活的需求。这项技术将二维码与门牌结合&#xff0c;…

2019数据结构----队列真题

(1)允许增加空间&#xff0c;空间可以改变所以是通过链表,链式存储实现的&#xff1b;占用的空间可以重复使用&#xff0c;所以是循环队列。 (2)队空&#xff1a;frontrear;队满&#xff1a;frontrear->next

CNAS中兴新支点——什么是安全测试,安全测试报告有什么作用,主要测试哪些内容?

1.安全测试在做什么&#xff1f; 扫描&#xff1f;在很多人眼中&#xff0c;做安全的就是整天那个工具在哪里扫描操作&#xff0c;使用各种不同的工具做扫描。 是的&#xff0c;扫描是安全测试很重要的一部分&#xff0c;扫描可快速有效发现问题。扫描工具的易用性&#xff0…

霍尔传感器测速测距实验——STM32驱动(课程设计)

———————实验效果——————— &#x1f384;图片演示测距 &#x1f384;视频演示测速 基于STM32单片机 霍尔传感器测速度&#xff0c;测圈数 &#x1f384;模块介绍 测距使用HC-SR04模块 测距使用测速使用霍尔传感器 ———————代码获取查看下方———————…

商务智能|描述性统计分析与数据可视化

一、商务智能的三大方面 三个主要方面是描述性的统计分析、预测性的分析和指导性的数据分析。 A. 商务智能的知识体系下,数据分析包含了哪三个工作?商务智能体系架构里边关于数据分析的术语是什么? 商务智能的知识体系下,数据分析包含了三个工作,即描述性分析,预测性分析…

Mac Parallels19.1.0 Install CentOS7.9

0、资源准备 # centos7.9镜像一份 链接: https://pan.baidu.com/s/1acIjUnsTGhk_2cYCZLSoGg?pwd6666 提取码: 6666 --来自百度网盘超级会员v7的分享1、打开PD 2、选择镜像进行安装 指定镜像名称 创建 进行密码设置 安装目的地点开后直接点击完成 网络和主机名称 开…

编程语言的生命力

一、目前主流的编程语言 目前流行的编程语言有很多种&#xff0c;可谓是百花齐放、百家争鸣。根据不同的应用场景和领域&#xff0c;有不同的编程语言被广泛使用。一些目前主流的编程语言HTML5、Python、JavaScript 、Java 、C 、PHP 、Swift 等等。 还有许多其他的编程语言&am…

xcode-开发相关

分发方式 下面是指应用程序分发方法&#xff0c;决定了你可以将app安装到哪些设备以及应用可以使用哪些功能 每个分发模式对应的provision profile不同 debug release ad hoc(临时分发) 允许100台指定的移动设备&#xff0c;这种分发不会将应用发布到App Store&#xff0c…

使用国内镜像源来安装 Golang 包:

使用国内镜像源来安装 Golang 包&#xff1a; 阿里云&#xff1a;https://mirrors.aliyun.com/goproxy/ 要使用这些镜像源&#xff0c;请将 GOPROXY 环境变量设置为所选镜像源的 URL。例如&#xff0c;要使用阿里云镜像源&#xff0c;请在命令行中运行以下命令&#xff1a; …

Java SE面试

1.什么是 Java&#xff1f; Java 是一门面向对象的编程语言&#xff0c;不仅吸收了 C语言的各种优点&#xff0c;还摒弃了 C里难以理解的多继承、指针等概念&#xff0c;因此 Java 语言具有功能强大和简单易用两个特征。Java 语言作为静态面向对象编程语言的优秀代表&#xff…