当前位置: 首页 > news >正文

基于 OAuth2.0 思路实现两种单点登录:授权服务端与客户端的落地实践

手撸OAuth2.0,web版,移动端同样适用—基于 OAuth2.0 思路实现两种单点登录:授权服务端与客户端的落地实践

摘要

在多系统集成场景中,单点登录的目标并不只是“少输一次密码”,更重要的是把“统一认证”和“各系统本地会话”拆分开来。本文介绍一套基于 OAuth2.0 授权码模式思路实现的单点登录方案,其中授权服务端负责统一认证,客户端负责完成本地登录落地。

本文实现了两种登录入口:

  1. 客户端主动发起登录
  2. 用户已经登录授权服务端后,从应用中心直接进入客户端

两种方式前半段不同,但后半段统一收敛为:

授权服务端签发 code -> 客户端用 code 换 access_token -> 客户端再用 access_token 获取用户信息 -> 客户端根据用户信息执行本地免密登录 -> 客户端生成自己的业务 token -> 前端完成系统登录

需要说明的是,本文重点放在“统一认证 + 本地登录落地”这条主链路上。
对于“客户端基于 access_token 访问受保护资源时的 scope / audience / 资源权限校验”,本文暂未实现,仅在末尾给出后续扩展方向。


一、整体设计目标

这套实现的核心思想可以概括为两句话:

  1. 授权服务端负责认证“你是谁”
  2. 客户端负责决定“你在我系统里如何登录”

也就是说,授权服务端并不直接替客户端生成业务登录态,而是通过code -> access_token -> userinfo的方式,把统一身份传递给客户端。客户端收到身份后,再在自己的用户体系、权限体系和会话体系内完成一次本地登录。

这样做有三个直接好处:

  • 统一认证与业务系统解耦
  • 各客户端仍然保有自己的权限控制能力
  • 后续可以平滑演进为更完整的 OAuth2.0 / OpenID Connect 模式

二、核心数据模型

授权服务端维护一张sso_app应用表,用来保存每个客户端系统的注册信息。核心字段如下:

@TableName("mom_sso_app")publicclassSsoAppEntityimplementsSerializable{@TableId("f_id")privateStringid;@TableField("f_system_id")privateStringsystemId;@TableField("f_en_code")privateStringenCode;@TableField("f_app_name")privateStringappName;@TableField("f_client_id")privateStringclientId;@TableField("f_client_secret")privateStringclientSecret;@TableField("f_callback_uri")privateStringcallbackUri;@TableField("f_status")privateStringstatus;}

字段职责如下:

  • systemId:关联授权服务端自己的应用表
  • enCode:应用编码,用于标识是哪个应用发起了登录
  • clientId / clientSecret:客户端凭证
  • callbackUri:客户端回调地址

在应用创建时,clientIdclientSecret由服务端自动生成:

@OverridepublicSsoAppEntitycreate(SsoAppFormform){checkForm(form);checkSystemIdUnique(form.getSystemId(),null);Datenow=newDate();SsoAppEntityentity=newSsoAppEntity();entity.setId(RandomUtil.uuId());entity.setSystemId(form.getSystemId());entity.setAppName(form.getAppName());entity.setEnCode(form.getEnCode());entity.setClientId(generateClientId());entity.setClientSecret(generateClientSecret());entity.setCallbackUri(form.getCallbackUri());entity.setStatus(StringUtil.isEmpty(form.getStatus())?"0":form.getStatus());entity.setRemark(form.getRemark());entity.setCreatorTime(now);entity.setLastModifyTime(now);this.save(entity);returnentity;}

客户端侧则维护自己的 SSO 配置:

client:sso:oauth:server-url:http://127.0.0.1:30000client-id:sso_client_xxxclient-secret:xxxxxxxxxredirect-uri:http://127.0.0.1:8089/auth/sso/callbackfront-redirect-uri:http://localhost:5666/sso/callbacksys-client-id:e5cd7e4891bf95d1d19206ce24a7b32estate-expire-seconds:300ticket-expire-seconds:60

三、登录页中的enCode作用

这套实现里,enCode不是一个普通业务字段,而是授权服务端登录页识别“登录来源”的关键标记。

授权服务端在构造登录页跳转地址时,会把enCode作为路径片段拼接进去:

privateSsoAuthorizeVObuildLoginRedirect(SsoAppEntityapp,Stringstate,StringresponseType){SystemEntitysystem=loadSystemById(app.getSystemId());UriComponentsBuilderbuilder=UriComponentsBuilder.fromUriString(momLoginPageUrl).pathSegment(system.getEnCode());if(StringUtil.isNotEmpty(state)){builder.queryParam("state",state);}SsoAuthorizeVOvo=newSsoAuthorizeVO();vo.setRedirectUrl(builder.build().encode().toUriString());vo.setSystemId(system.getId());vo.setEnCode(system.getEnCode());vo.setClientId(app.getClientId());vo.setRedirectUri(app.getCallbackUri());vo.setState(state);returnvo;}

这段逻辑背后的真实含义是:

  • 如果登录页 URL 中带有enCode,说明这次登录是某个客户端系统发起的
  • 登录页在登录成功后,应继续走单点登录链路,并最终跳回对应客户端
  • 如果登录页 URL 中没有enCode,说明用户只是直接打开了授权服务端自己的登录页
  • 此时登录成功后,不需要回跳到外部应用,而是正常进入授权服务端本身的首页或工作台

因此,enCode的作用可以总结为:

它不是权限参数,而是登录来源标记,用于区分“普通登录”与“来自客户端的登录请求”。

这也是一个授权中心支持多应用登录时非常重要的前端分流逻辑。


四、方式一:客户端主动发起登录

这种方式适用于:用户先访问客户端,此时还没有登录授权服务端。

1. 调用流程图

授权服务端客户端浏览器授权服务端客户端浏览器
http://www.jsqmd.com/news/1155388/

相关文章:

  • 7月武汉金条投资金回收,纪念金币高价回收,本地多家黄金回收门店实测对比 - 名奢变现站
  • JMeter后置处理器实战:JSON提取器与正则表达式数据关联详解
  • 教育教学论文AI哪个最好用?教师必备工具
  • 创世战车JBRider快乐索命流:4套10K战力实战配装详解
  • 百达翡丽官方售后在哪维修保养服务点权威公示(2026年7月最新) - 百达翡丽官方售后中心
  • aaa 级信用企业评价是什么?aaa 级信用企业申报门槛高吗? - 信息快递
  • IDE黄昏不是终结,而是AI驱动开发会话的黎明
  • 3分钟快速上手:Vosk离线语音识别完整实践指南
  • 冷媒分装机厂家排名前三有哪些?2026年最新实力榜单揭晓 - 商业新知
  • 东营老牌古蓝装饰,150+员工,400+自有工人,靠谱之选! - 速递信息
  • Redis Cluster 部署与运维:向量搜索场景下的分片、故障转移和容量规划
  • L9958与PIC18F46K42在电机控制中的优势与实践
  • 光谱椭偏仪应用|超低折射率纳米空气柱阵列-SiO₂复合超材料
  • wxhelper深度解析:安全使用微信逆向工具的完整实践指南
  • ME8115 反激式开关电源实战:从炸膛到量产 2500 套的 3 个关键改进点
  • 冰城各区均可上门收表,门店多资金足无隐形收费,专攻理查德米勒热门款隐私好 - 奢侈品交易观察员
  • 常建再生资源:解锁常熟工地废料回收新范式,开启绿色循环新征程 - 企业权威推荐大使
  • Qwen 3.6生产级压测:Spark分布式推理与Halo单机优化实战
  • 2026年企业级AI大模型中转平台选型:如何在保障长期稳定性的同时,实现大模型成本大幅骤降
  • 2026全国铝合金防火窗厂家推荐:资质齐全可承接各类工程项目 - 商业新知
  • 二本信息管理与信息系统好就业吗?普通本科怎么找工作
  • 网盘直链下载助手完整指南:九大网盘下载速度提升终极方案
  • 2026年临沂奥迪发动机精修十大口碑榜,免拆治理烧机油技术实力企业汇总 - 资讯报道
  • IP子网划分实战:从/24到/30的5种掩码规划与VLSM应用场景
  • 亨得利中国官方售后服务中心官方网站权威认证(2026年7月最新) - 亨得利客户服务中心
  • 计算机网络期末复习:基于吉大20/21级真题的5大高频考点与3类易错题解析
  • VSCode 中 Markdown 转 PDF
  • 广州焊工教育机构参考榜:焊接实训、报考流程与服务怎么选 - 思溯深度专栏
  • 2026昭通黄金变现防骗指南|本地实测靠谱回收渠道与交易干货 - 天天开心12
  • 端到端成趋势,决策范式革新