单点登录(SSO)是目前比较流行的企业业务整合的解决方案之一,它的机制是在企业网络用户访问企业网站时作一次身份认证,随后就可以对所有被授权的网络资源进行无缝的访问,而不需要多次输入自己的认证信息.Web服务具有松散耦合、语言中立、平台无关性、开放性的特性,通过对集中单点登录模型的分析和比较,提出了基于Web服务和token-id的单点登录管理框架.介绍了该系统的体系机构及关键部分的工作原理.

本项目主要是采用spring boot +mysql 实现。重点描述如何重代码结构上实现 Web服务统一身份认证协议设计与实现功能。

主要功能如下

  1. token生成与管理
  2. 系统接入token 实现sso 单点登录
  3. 统一身份token 认证与校验
  4. 分布式系统接入sso模式

项目整体结构

一:sso 管理

原理,利用http 头部信息保存token 匹配服务器的session信息,进行校验。当用户首次登录系统,注册sso 信息

(1):注册sso token

    public ResultPo register(String sessionId, String token, long uid) {String session = getSession(uid, token);if (session != null && session.equals(sessionId)) {ResultPo result = ResultPo.create(200, "sso token exist");SSoPo po = redisService.getPo(SSoPo.class, new MongoPrimaryKey("session_id", session));if (po != null) {po.setMtime(TimeUtils.Now());redisService.updatePo(po);result.appendData("sso", po);return result;}} else if (session != null) {this.removeSession(session, token);}SSoPo sso = new SSoPo();sso.setUid(uid);sso.setSessionId(sessionId);sso.setToken(token);sso.setMtime(TimeUtils.Now());SSoPo po = redisService.getPo(SSoPo.class, sso.getPrimaryKeys());if (po != null) {po.setMtime(TimeUtils.Now());redisService.updatePo(po);ResultPo result = ResultPo.create(200, "sso token exist");result.appendData("sso", sso);return result;}redisService.savePo(sso);ResultPo result = ResultPo.create(200, "sso register successful");result.appendData("sso", sso);redisService.hsetString(getSessionPool(token), uid + "", sessionId, sso.getClass().getAnnotation(Cache.class).timestamp());return result;}/*** token 生成器** @return*/public String generateTokeCode() {String value = System.currentTimeMillis() + new Random().nextInt() + "";System.out.println(value);long currentTime = System.currentTimeMillis();SimpleDateFormat formatter = new SimpleDateFormat("yyyy年-MM月dd日-HH时mm分ss秒");Date date = new Date(currentTime);System.out.println(formatter.format(date));//获取数据指纹,指纹是唯一的try {MessageDigest md = MessageDigest.getInstance("md5");byte[] b = md.digest(value.getBytes());//产生数据的指纹//Base64编码BASE64Encoder be = new BASE64Encoder();be.encode(b);System.out.println(be.encode(b));return be.encode(b);//制定一个编码} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return null;}

把信息保存到中心服务中,把用户uid sessionid token 三者关系建立起来。

(2):校验sso

 public ResultPo validateSession(String sessionId, String token) {SSoPo sso = redisService.getPo(SSoPo.class, new MongoPrimaryKey("session_id", sessionId));if (sso == null) {return ResultPo.create(ErrorCode.SESSION_ERROR, "session not found");}//过期boolean expr = TimeUtils.Now() > (sso.getMtime() + sso.getClass().getAnnotation(Cache.class).timestamp());if (expr) {removeSession(sso.getSessionId(), token);return ResultPo.create(ErrorCode.SESSION_ERROR, "session long old");}ResultPo po = ResultPo.create(200, "session validate successful");po.appendData("sso", sso);return po;}

用户在分布式系统中请求都携带此token 中,不用在此进行登录或者用户信息的校验,只需要通过token 和application所颁发的token 进行校验。

/*** 验证web 应用是否合法** @param serverId* @param token* @return*/public ResultPo validateApp(long serverId, String token) {HashMap<String, Object> params = new HashMap<>();params.put("serverId", serverId);params.put("token", token);String json = HttpUtil.getInstance(token).post("", this.url + "/sso/appValidate", params);return BaseUtils.getResultPo(json);}

(3):token 销毁

 @Overridepublic ResultPo removeSession(String sessionId, String token) {SSoPo sso = redisService.getPo(SSoPo.class, new MongoPrimaryKey("session_id", sessionId));if (sso == null) {return ResultPo.create(200, "");}redisService.deletePo(SSoPo.class, new MongoPrimaryKey("session_id", sessionId));redisService.deleteHField(getSessionPool(token), sso.getUid() + "");return ResultPo.create(200, "successful");}

二:服务器节点接入

服务节点的介入,任何系统授信信息都需要通过中心服务器颁发的token 与appid 进行注册校验,提供application的注册信息。颁发给每个系统。

(1):系统节点接入

应用节点定义:

@Document(collection = "server_node")
@Cache(cache = true)
public class ServerNode implements IMongoPo {@Field("server_id")@PrimaryKey(name = "server_id")@Indexed(name = "server_id", unique = true)  //索引  name为索引名称,unique=true,唯一索引private int serverId;@Field("type")private String type;@Field("name")private String name;@Field("url")private String url;@Field("token")private String token;@Field("port")private int port;@Field("weight")private int weight;@Field("status")private int status;

应用接入:

 @Overridepublic ResultPo register(ServerNode serverNode) {boolean successful = serverDao.add(serverNode);if (successful) {return ResultPo.create();}return ResultPo.create(500, "create app error");}

分系统接入
定义一个服务的主要信息

"sso": [{"id": 1,"url": "http://127.0.0.1","port": 8524,"weight": 1,"token": "123456"}],

应用校验

应用系统进行网络通讯的时候,首先会进行application校验。

  @RequestMapping("appValidate")public ResultPo appValidate(HttpServletRequest request, long serverId, String token) {ResultPo resultpo = serverService.get(serverId);Object obj = resultpo.get("data");if (obj == null) {resultpo.setCode(500);resultpo.setMessage("application validate error!");return resultpo;}ServerNode node = (ServerNode) obj;if (!node.getToken().equals(token)) {resultpo.setCode(500);resultpo.setMessage("application validate error! token not march");return resultpo;}resultpo.setCode(200);resultpo.setMessage("application validate successful");return resultpo;}
package com.graduation.online.proxy;import com.graduation.online.base.BaseUtils;
import com.graduation.online.base.enums.ServerType;
import com.graduation.online.base.model.ResultPo;
import com.graduation.online.base.service.ServerNodeService;
import com.graduation.online.base.utils.HttpUtil;import java.util.HashMap;public class SSoAgentServer extends BaseAgent {public SSoAgentServer() {super(ServerNodeService.getInstance().getServerNode(ServerType.SSO));}public ResultPo register(String sessionId, long uid) {HashMap<String, Object> params = new HashMap<>();params.put("sessionId", sessionId);params.put("token", token);params.put("uid", uid);String json = HttpUtil.getInstance(token).post(sessionId, this.url + "/sso/register", params);return BaseUtils.getResultPo(json);}/*** 验证系统用户session 同一身份** @param sessionId* @return*/public ResultPo validateSession(String sessionId) {HashMap<String, Object> params = new HashMap<>();params.put("sessionId", sessionId);params.put("token", token);String json = HttpUtil.getInstance(token).post(sessionId, this.url + "/sso/validate", params);return BaseUtils.getResultPo(json);}/*** 验证web 应用是否合法** @param serverId* @param token* @return*/public ResultPo validateApp(long serverId, String token) {HashMap<String, Object> params = new HashMap<>();params.put("serverId", serverId);params.put("token", token);String json = HttpUtil.getInstance(token).post("", this.url + "/sso/appValidate", params);return BaseUtils.getResultPo(json);}public long getSSoUId(String sessionId) {HashMap<String, Object> params = new HashMap<>();params.put("sessionId", sessionId);params.put("token", token);String json = HttpUtil.getInstance(token).post(sessionId, this.url + "/sso/uid", params);ResultPo result = BaseUtils.getResultPo(json);if (result.get("uid") == null) {return -1;}return Long.parseLong(result.get("uid").toString());}public String getSession(long uid) {HashMap<String, Object> params = new HashMap<>();params.put("uid", uid);params.put("token", token);String json = HttpUtil.getInstance(token).post(null, this.url + "/sso/getSession", params);ResultPo result = BaseUtils.getResultPo(json);if (result.get("sessionId") == null) {return "";}return result.get("sessionId").toString();}public ResultPo removeSession(String sessionId) {HashMap<String, Object> params = new HashMap<>();params.put("sessionId", sessionId);params.put("token", token);String json = HttpUtil.getInstance(token).post(sessionId, this.url + "/sso/remove", params);return BaseUtils.getResultPo(json);}
}

分系统用户进行登录时候,只需要在登录授权一次,既可以在任何系统进行数据读取,

三:简单演示

当用户登录系统后

后台sso 系统接收到用户认证信息

用户授权后,进入到系统

系统为应用授权

总结:本系统采用web 的sso 统一身份认知,利用一个简单的,实现web 认证管理,加密认证,分布式系统应用授权认证。

代码地址:git@github.com:twjitm/graduation-online-server-code.git

Web服务统一身份认证协议设计与实现相关推荐

  1. 统一身份认证和授权--微服务架构

    一.预备知识 本文讨论基于微服务架构下的身份认证和用户授权的技术方案,在阅读之前,最好先熟悉并理解以下几个知识点: 微服务架构相关概念:服务注册.服务发现.API 网关 身份认证和用户授权:SSO.C ...

  2. 统一身份认证子系统界面设计与实现

    目  录 一 引言 -------------------------1 二 需求分析-----------------------..2 三 总体设计-----------------------. ...

  3. 服务架构:统一身份认证和授权技术解决方案

    本文讨论的是基于微服务架构下的身份认证和用户授权的技术方案,从背景到微服务架构整套流程分解. 一.预备知识 本文讨论基于微服务架构下的身份认证和用户授权的技术方案,在阅读之前,最好先熟悉并理解以下几个 ...

  4. 构建基于分布式SOA架构的统一身份认证体系

    摘要:本文充分利用SOA架构松耦合的特点,通过规范统一网络接口实现业务系统整合,既提升系统安全性,又简化资源访问操作,具有重要的理论和现实意义. 统一身份认证旨在将分散在各个信息系统中的用户和权限资源 ...

  5. 企业级项目|用Python进行web开发企业统一用户认证和权限控制平台

    目前大家对Python的了解更多来源是数据分析.Ai.运维工具开发,在行业中使用Python进行web开发,同样也是非常受欢迎的,例如:FaceBook,豆瓣,知乎,饿了么等等,本文主要是介绍是利用P ...

  6. 统一身份认证系统的简单看法

    [事件背景]洋葱服务为什么没被成功接盘?_搜狐科技_搜狐网 https://www.sohu.com/a/124452755_354899 今天无意中看到这则新闻,发现人家洋葱认证服务已经停运1年多啦 ...

  7. springmvc--sso单点登录cas统一身份认证器

    开发环境 maven idea Windows 10 JDK 1.8+ 域名解析的配置 这里通过SwitchHosts来实现:以管理员身份打开 前两个:两个客户端应用的域名 后一个:是服务端的域名. ...

  8. 网络信息安全课程:对于匿名身份认证协议的学习

    有关匿名协议的基本概念整理 匿名身份认证的基本概念 匿名性 广泛存在于通信.认证等领域的安全需求,指系统中的某些信息对除了相关实体之外是不确定的或无关联性的. 过程 匿名性 发送方 发送者的匿名性 通 ...

  9. 【统一身份认证】详细讲解

    一.什么是统一身份认证? 二.统一身份认证的构成? 1.角色模型:    用户-〉角色-〉权限 2.实现 前言 身份认证是一款软件(系统),主要作用是用于甄别用户身份,认证成功之后会把身份信息(姓名, ...

最新文章

  1. Spring@Autowired注解与自动装配
  2. mysql查询索引like_通过索引查询慢速搜索LIKE%MYSQL
  3. Silverlight简介
  4. tpm php,TPM系列
  5. 关于angularjs指令
  6. springboot08 自动配置原理
  7. apache VSF 操作类
  8. 详解数据库锁机制和原理
  9. 屏幕中间html滚动字幕,Gom引擎屏幕中间滚动大字及屏幕其他信息滚动条脚本实例...
  10. 电池SOC仿真系列-基于粒子群算法电池参数辨识
  11. “当当收店庆费一事”之我见
  12. Acala与全球知名跨链资产流动平台Ren达成合作
  13. 数据结构课程设计报告(附代码)
  14. NFT Insider由WHALE社区、BeepCrypto联合出品,浓缩每周NFT新闻,为大家带来关于NFT最全面、最新鲜、最有价值的讯息。
  15. python查答案_大学慕课Python编程基础答案查题公众号
  16. Java基础之if练习打印星期天
  17. ampak正基RF定频手动测试命令
  18. iphone怎么投屏到mac上 iphone投屏到mac方法
  19. Java Security https://www.bilibili.com/video/BV1PE411i7CV?p=33spm_id_from=pageDriver
  20. 游戏设计参考:魔兽世界WOW角色的基本属性及其作用

热门文章

  1. 手机端如何阻止苹果浏览器输入框默认放大事件
  2. 关于nbsp的一点笔记
  3. 从中国AI的“直道超车”时刻,看百度何以奔赴星辰大海
  4. 艾宾浩斯记忆法和遗忘曲线
  5. linux安装、更新、卸载anaconda
  6. 如何下载win10原装镜像
  7. 【photoshop】笔记(四)之修补工具
  8. 巨头倾轧却能强劲生长,青云做对了什么?
  9. 在Windows服务器上搭建Nuget私人服务器(超~详细)
  10. python 离线翻译软件_Python使用tkinter制作在线翻译软件