如何实现系统的单点登录?
目录
- 1. 单点登录的流程是什么样的?
- 2. 从代码层面剖析单点登录流程
- 3. 跨域问题怎么解决?
- 4. 如何实现会话超时?
1. 单点登录的流程是什么样的?
总体来说,一次单点登录过程包括了 3 次重定向过程。
第一次重定向,发现 Session 里未携带用户信息,拦截该未登录请求,重定向到 CAS Server;
第二次重定向,是登录成功重定向到初始访问接口(用户被拦截的接口),这步的重定向很关键,解决了单点登录的跨域问题;
第三次重定向,Session 携带用户信息去访问初始接口;
整个流程图如下:
思考以下几个问题以加深理解:
用户信息是哪个角色赋值在 Session 中的?
CAS Server 将用户信息封装在 body 里,服务方读取该 body 数据并填充到 Session 中;
服务方是怎么验证 Ticket 的?
第一次登录后,后面登录就不需要验证了,流程图如下。
访问其他系统也不需要认证了,流程图如下。
2. 从代码层面剖析单点登录流程
准备工作:注册拦截资源
@Component public class AuthConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {AiforceProperties aiforceProperties = SpringContextHolder.getApplicationContext().getBean(AiforceProperties.class);registry.addInterceptor(new AuthHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns(getNoAuthUrls());// 拦截白名单} }
从前端请求后端服务
首先从前端调用后端的
http://app.example.com/auth/user
接口,这时会被拦截器拦截,下面是拦截器的实现。@Component @Slf4j public class AuthHandlerInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (isLogin(request)) {return true;}// 未登录则需要跳转到CAS Server进行登录request.getSession().setAttribute(Constants.RETURN_URL, "http://app.example.com/auth/user");response.sendRedirect("http://cas.example.com/cas/login?service=http://app.example.com/callback");// 【1】return false;}public boolean isLogin(HttpServletRequest request) {// 会话中用户信息为空则未登录if (request.getSession().getAttribute(Constants.USER_SESSION) == null) {return false;}return true;} }
后端转发请求到单点登录服务器
注意:这里的请求转发
response.sendRedirect
跟上面的重定向可以理解为一个意思。在请求单点登录服务器前,需要把注册一个回调地址
http://app.example.com/callback
,比如步骤1中代码【1】处。用户提交表单后,单点登录服务器会跳转至
http://cas.example.com/cas/login?service=http://app.example.com/callback
中service
配置的值即http://app.example.com/callback
,并携带ticket
数据,可以放在http body
里面。/callback
接口怎么实现?@RequestMapping(value = "/callback") public Result<String> callback(HttpServletRequest request, HttpServletResponse response) {// 请求单点登录服务器,校验ticket,返回用户信息UserInfo userInfo = iAuthService.validateTicket(request);// 将用户信息放到session里request.getSession().setAttribute(Constants.USER_SESSION, JSON.toJSONString(userInfo));// 转发请求至步骤1初始请求的地址response.sendRedirect("http://app.example.com/auth/user");return Result.ok(); }
重新请求请求后端服务
这时再请求
http://app.example.com/auth/user
接口,步骤1中的isLogin()
就返回true
了。这样就完成了登录。
3. 跨域问题怎么解决?
比如现在有 2 个请求。
请求1:http://app1.example.com/auth/user
请求2:http://app2.example.com/auth/user
图片来源:https://blog.csdn.net/hezheqiang/article/details/82145125
可以通过在 SSO 域名下保存 Cookie 来解决跨域问题。
4. 如何实现会话超时?
在/callback
接口里添加逻辑,将用户信息缓存到redis
中。
@RequestMapping(value = "/callback")
public Result<String> callback(HttpServletRequest request, HttpServletResponse response) {UserInfo userInfo = iAuthService.validateTicket(request);request.getSession().setAttribute(Constants.USER_SESSION, JSON.toJSONString(userInfo));// 新增的逻辑stringRedisTemplate.opsForValue().set(getTokenKey(), JSON.toJSONString(userInfo), 120, TimeUnit.SECONDS);response.sendRedirect("http://app.example.com/auth/user");return Result.ok();
}
接着在isLogin()
方法里添加判断:redis
中的TokenKey
是否过期。
public boolean isLogin(HttpServletRequest request) {if (request.getSession().getAttribute(Constants.USER_SESSION) == null) {return false;}// 判断redis缓存中key是否失效if (stringRedisTemplate.opsForValue().get(getTokenKey()) == null) {return false;}return true;
}
如何实现系统的单点登录?相关推荐
- 通用权限管理系统组件 中集成多个子系统的单点登录(网站入口方式)附源码
通用权限管理系统组件 (GPM - General Permissions Manager) 中集成多个子系统的单点登录(网站入口方式)附源码 上文中实现了直接连接数据库的方式,通过配置文件,自定义的 ...
- java ssm 多租户_(十一)java B2B2C 源码 多级分销springmvc mybatis多租户电子商城系统- SSO单点登录之OAuth2.0登录流程(2)...
上一篇是站在巨人的肩膀上去研究OAuth2.0,也是为了快速帮助大家认识OAuth2.0,闲话少说,我根据框架中OAuth2.0的使用总结,画了一个简单的流程图(根据用户名+密码实现OAuth2.0的 ...
- 一站式登录授权系统(单点登录+授权管理)
项目地址 https://github.com/minlingchao1/auth-center 项目说明 auth-center是一个轻量级的权限管理系统.其核心目标是实现公司内部各个系统的权限的集 ...
- 业务系统接入单点登录服务
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/11377620.html 一:单点登录业务接入场景 对于大型企业,内部有各种各样的办公OA.业务系统,员工使用 ...
- 泛微OA如何与其他系统实现单点登录
因为每一个系统单点登录的认证方式不通,这里主要介绍OA如果获取相应单点需要的数据 <%@ page language="java" contentType="tex ...
- 通达OA系统对接 单点登录 标准SaaS技术服务说明
1 标准技术服务项目 标准业务类型 服务说明 服务项目 预估工期 (人/天) HR接口对接 (人员组织同步) 支持HR接口信息对接(因钉钉服务限制,做钉钉接口需要单独购买服务器进行部署) • 支持平 ...
- 通达OA系统对接 单点登录平台使用和开发手册
企业开放平台使用说明书 企业开放平台用于整合第三方系统,具有单点登录.统一事务代办的功能, 以下操作说明以第三方系统为OA系统简单介绍. 单点登录平台 Step 1 菜单构成 通达OA2017版安装好 ...
- 分布式多系统SSO单点登录
1.整体系统布局 大的布局有两种方式,这两种方式都需要一个独立的SSO认证服务系统称为SSO服务端,而第一种是在SSO服务端只完成登录接口,返回是否登录成功的标识和数据,每个SSO客户端都需要独立的登 ...
- 整合公司3个网站后台管理子系统的经验总结 - 实现多系统的单点登录(ASP.NET + ASP)...
公司有3个网站的后台管理系统,其中2个是ASP编写的网站后台管理系统,1个是ASP.NET编写的网站后台管理系统,各自的用户权限管理,后台的风格都不一样,虽然用起来很好用,但是还是感觉有些凌乱一些,公 ...
最新文章
- sqoop操作之HIVE导出到ORACLE
- nginx 配置https 并解决重定向后https协议变成了http的问题
- 阿里云数据库备份DBS商业化发布,数据库实时备份到OSS
- Go实战--也许最快的Go语言Web框架kataras/iris初识二(TOML、Cache、Cookie)
- python左移位运算_python 移位运算符只能用于整型吗
- solr 7 mysql导入_solr 7.7.0 windows 导入mysql数据库数据
- css3 如何动态画一条直线_素描基础学习课:素描长直线的画法!把直线画直的关键!...
- 循环单链表 python_循环单链表报错
- java语法和python语法的一些区别
- Java设计模式——模板方法模式(模板方法设计模式)详解
- Python机器学习及实践——特征降维
- 随机课堂、随机提问、随机抽检、随机名单,可去重可重复
- 强化学习之——表格式Agent实现
- Git出现 FETCH_HEAD fatal: refusing to merge unrelated histories解决方法
- Java实现ATM机
- selenium webdriver的testNG框架的介绍及使用
- 【原创】基于WinForm的水晶报表开发
- 2023年PMP超全报考指南,速速收藏!
- magic4升级鸿蒙系统日期,magic4.0什么时候更新
- 徕雨科技HDMI网线延长器