目录

  • 1. 单点登录的流程是什么样的?
  • 2. 从代码层面剖析单点登录流程
  • 3. 跨域问题怎么解决?
  • 4. 如何实现会话超时?

1. 单点登录的流程是什么样的?

总体来说,一次单点登录过程包括了 3 次重定向过程。

第一次重定向,发现 Session 里未携带用户信息,拦截该未登录请求,重定向到 CAS Server;
第二次重定向,是登录成功重定向到初始访问接口(用户被拦截的接口),这步的重定向很关键,解决了单点登录的跨域问题;
第三次重定向,Session 携带用户信息去访问初始接口;

整个流程图如下:

思考以下几个问题以加深理解:

  1. 用户信息是哪个角色赋值在 Session 中的?

    CAS Server 将用户信息封装在 body 里,服务方读取该 body 数据并填充到 Session 中;

  2. 服务方是怎么验证 Ticket 的?

第一次登录后,后面登录就不需要验证了,流程图如下。

访问其他系统也不需要认证了,流程图如下。

2. 从代码层面剖析单点登录流程

  1. 准备工作:注册拦截资源

    @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());// 拦截白名单}
    }
    
  2. 从前端请求后端服务

    首先从前端调用后端的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;}
    }
    
  3. 后端转发请求到单点登录服务器

    注意:这里的请求转发response.sendRedirect跟上面的重定向可以理解为一个意思。

    在请求单点登录服务器前,需要把注册一个回调地址http://app.example.com/callback,比如步骤1中代码【1】处。

    用户提交表单后,单点登录服务器会跳转至http://cas.example.com/cas/login?service=http://app.example.com/callbackservice 配置的值即http://app.example.com/callback,并携带ticket数据,可以放在http body里面。

  4. /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();
    }
    
  5. 重新请求请求后端服务

    这时再请求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;
}

如何实现系统的单点登录?相关推荐

  1. 通用权限管理系统组件 中集成多个子系统的单点登录(网站入口方式)附源码

    通用权限管理系统组件 (GPM - General Permissions Manager) 中集成多个子系统的单点登录(网站入口方式)附源码 上文中实现了直接连接数据库的方式,通过配置文件,自定义的 ...

  2. java ssm 多租户_(十一)java B2B2C 源码 多级分销springmvc mybatis多租户电子商城系统- SSO单点登录之OAuth2.0登录流程(2)...

    上一篇是站在巨人的肩膀上去研究OAuth2.0,也是为了快速帮助大家认识OAuth2.0,闲话少说,我根据框架中OAuth2.0的使用总结,画了一个简单的流程图(根据用户名+密码实现OAuth2.0的 ...

  3. 一站式登录授权系统(单点登录+授权管理)

    项目地址 https://github.com/minlingchao1/auth-center 项目说明 auth-center是一个轻量级的权限管理系统.其核心目标是实现公司内部各个系统的权限的集 ...

  4. 业务系统接入单点登录服务

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/11377620.html 一:单点登录业务接入场景 对于大型企业,内部有各种各样的办公OA.业务系统,员工使用 ...

  5. 泛微OA如何与其他系统实现单点登录

    因为每一个系统单点登录的认证方式不通,这里主要介绍OA如果获取相应单点需要的数据 <%@ page language="java" contentType="tex ...

  6. 通达OA系统对接 单点登录 标准SaaS技术服务说明

    1  标准技术服务项目 标准业务类型 服务说明 服务项目 预估工期 (人/天) HR接口对接 (人员组织同步) 支持HR接口信息对接(因钉钉服务限制,做钉钉接口需要单独购买服务器进行部署) • 支持平 ...

  7. 通达OA系统对接 单点登录平台使用和开发手册

    企业开放平台使用说明书 企业开放平台用于整合第三方系统,具有单点登录.统一事务代办的功能, 以下操作说明以第三方系统为OA系统简单介绍. 单点登录平台 Step 1 菜单构成 通达OA2017版安装好 ...

  8. 分布式多系统SSO单点登录

    1.整体系统布局 大的布局有两种方式,这两种方式都需要一个独立的SSO认证服务系统称为SSO服务端,而第一种是在SSO服务端只完成登录接口,返回是否登录成功的标识和数据,每个SSO客户端都需要独立的登 ...

  9. 整合公司3个网站后台管理子系统的经验总结 - 实现多系统的单点登录(ASP.NET + ASP)...

    公司有3个网站的后台管理系统,其中2个是ASP编写的网站后台管理系统,1个是ASP.NET编写的网站后台管理系统,各自的用户权限管理,后台的风格都不一样,虽然用起来很好用,但是还是感觉有些凌乱一些,公 ...

最新文章

  1. sqoop操作之HIVE导出到ORACLE
  2. nginx 配置https 并解决重定向后https协议变成了http的问题
  3. 阿里云数据库备份DBS商业化发布,数据库实时备份到OSS
  4. Go实战--也许最快的Go语言Web框架kataras/iris初识二(TOML、Cache、Cookie)
  5. python左移位运算_python 移位运算符只能用于整型吗
  6. solr 7 mysql导入_solr 7.7.0 windows 导入mysql数据库数据
  7. css3 如何动态画一条直线_素描基础学习课:素描长直线的画法!把直线画直的关键!...
  8. 循环单链表 python_循环单链表报错
  9. java语法和python语法的一些区别
  10. Java设计模式——模板方法模式(模板方法设计模式)详解
  11. Python机器学习及实践——特征降维
  12. 随机课堂、随机提问、随机抽检、随机名单,可去重可重复
  13. 强化学习之——表格式Agent实现
  14. Git出现 FETCH_HEAD fatal: refusing to merge unrelated histories解决方法
  15. Java实现ATM机
  16. selenium webdriver的testNG框架的介绍及使用
  17. 【原创】基于WinForm的水晶报表开发
  18. 2023年PMP超全报考指南,速速收藏!
  19. magic4升级鸿蒙系统日期,magic4.0什么时候更新
  20. 徕雨科技HDMI网线延长器

热门文章

  1. I2C、Arduino、ADXL345、
  2. Week-4-作业1
  3. mysql 触发器delete_MySQL之触发器
  4. BoundsChecker的用法
  5. NOI2017酱油记(伪)
  6. P4语言的特性、P4语言和P4交换机的工作原理和流程简介
  7. 20189220 余超《Linux内核原理与分析》第七周作业
  8. 《实用C++》第10课:if 语句实现关系运算
  9. Bugzilla 的安装
  10. 【Bugzilla】我按照bugzilla的官方指导进行的安装。(一)