1  单点登录

关于单点登录的原理,我觉得下面这位老哥讲的比较清楚,有兴趣可以看一下,下面我把其中的重点在此做个笔记总结

https://juejin.cn/post/6844904079274197005

主流的单点登录都是基于共享 cookie 来实现的

1.1  同域单点登录

适用场景:都是企业内部系统,所有系统都适用同一个一级域名,并通过不同的二级域名区分

举个例子:公司有一个一级域名cjs.com,我们有三个系统需要实现单点登录,分别是门户系统(sso.cjs.com)、应用系统1(app1.cjs.com)、应用系统2(app2.cjs.com)

核心原理

  1. 门户系统设置 Cookie 的 domain 为一级域名也就是 cjs.com,这样就可以共享门户的 Cookie 给所有的使用该域名(xxx.cjs.com)的系统
  2. 使用 Spring Session 等技术让所有系统共享 Session
  3. 所有登录都跳转到门户系统去登录,也就说门户系统有两个页面就够了:登录页(login.html)和首页(index.html)。通过首页链接可以进入到各子业务系统。
  4. 可以在加一层网关(Spring Cloud Gateway)

1.2  跨域单点登录

由于域名不一样不能共享 Cookie 了,这样就需要通过一个单独的授权服务(UAA)来做统一登录,并基于共享UAA的 Cookie 来实现单点登录。

举个例子:公司接到一个大项目,把其中部分系统外包给第三方来做,或者直接采购第三方服务商的系统,或者是子业务系统1采购服务商A的系统,子系统2采购B服务商的系统。无论什么情况,总之系统集成就需要单点登录。

核心原理

  1. 用户访问系统1,如果未登录,则跳转到UAA系统请求授权,并输入用户名/密码完成登录
  2. 登录成功后UAA系统把登录信息保存到 Session 中,并在浏览器写入域为 sso.com 的 Cookie
  3. 用户访问系统2,如未登录,则跳转到UAA系统请求授权
  4. 由于是跳转到UAA系统的域名 sso.com 下,所以能通过浏览器中UAA的 Cookie 读取到 Session 中之前的登录信息完成单点登录

1.3  基于OAuth2的跨域单点登录

1.4  前后端分离的跨域单点登录

前后端分离的核心概念是后端仅返回前端所需的数据,不再渲染HTML页面,前端HTML页面通过AJAX调用后端的RESTFUL API接口并使用JSON数据进行交互

跨域间的前后端分离项目也是基于共享统一授权服务(UAA)的cookie来实现单点登录的,但是与非前后分离不一样的是存在以下问题需要解决

  1. 没有过滤器/拦截器,需要在前端判断登录状态
  2. 需要自己实现oauth2的授权码模式交互逻辑
  3. 需要解决安全性问题,oauth2的clientSecret参数放在前端不安全

补充:前端获取授权码

  • redirect_uri写前端地址
  • 重定向到前端页面,页面获取到授权码code,拿code换token

示例参考:

http://localhost:9000/callback.html?code=xxx

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="jquery-3.6.0.min.js"></script>
<script>
/**
* 获取指定请求参数的值
* @param name 请求参数名称
* @returns {string|null}
*/
function getQueryParameter(name) {
let queryString = window.location.search.substring(1);
let params = queryString.split("&");
for (let i = 0; i < params.length; i++) {
let pair = params[i].split("=");
if (name == pair[0]) {
return pair[1];
}
}
return null;
}
/**
* 获取指定请求参数的值
* @param name 请求参数名称
* @returns {string|null}
*/
function getUrlParameter(name) {
let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
let queryString = window.location.search.substring(1);
let result = queryString.match(reg);
if (null != result) {
return unescape(result[2])
}
return null;
}
let authorizationCode = getUrlParameter("code");
$.post("http://localhost:8081/auth/oauth/token", {
grant_type: "authorization_code",
code: authorizationCode,
redirect_uri: "http://localhost:9000/callback.html"
}, function (resp) {
console.log(resp);
sessionStorage.setItem("token", resp.access_token);
});
</script>
</head>
<body> </body>

</html>

2  Spring Security OAuth 2.0迁移指南

从 Spring Security 5.2.x 开始,OAuth 2.0 Clients 和 Resource Servers 已经从 Security OAuth 2.x 迁移到 从 Spring Security,而且 Spring Security 不再提供 Authorization Server 的支持。

总之呢,Spring Security OAuth这个项目以后就处于维护状态了,不会再更新了,建议使用Spring Security

迁移以后,很多地方都不一样了,就我注意到的说下几点变化

首先,以前单点登录使用@EnableOAuth2Sso注解,现在推荐使用oauth2Login()方法

其次,授权服务器的写法不一样了

默认的端点都变成 /oauth2 开头了

更多变化可以阅读源码,亦可参见 OAuth 2.0 Features Matrix 查看二者支持的特性

3  @EnableOAuth2Sso的作用

@EnableOAuth2Sso: 标记服务作为一个OAuth 2.0客户端。这意味着它将负责将资源所有者(最终用户)重定向到授权服务器,在那里用户必须输入他们的凭据。完成后,用户被重定向回客户端,并携带授权码。然后,客户端获取授权码,并通过调用授权服务器以获取访问令牌。只有在此之后,客户端才能使用访问令牌调用资源服务器。

4  补充:根据pid递归查找子机构


package com.soa.supervision.gateway.service.impl; import com.alibaba.fastjson.JSON;
import com.soa.supervision.gateway.entity.SysDept;
import com.soa.supervision.gateway.repository.SysDeptRepository;
import com.soa.supervision.gateway.service.SysDeptService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit; /**
* 机构表 服务实现类
*
* @author ChengJianSheng
* @since 2022-03-08
*/
@Service
public class SysDeptServiceImpl implements SysDeptService {
private static final String CACHE_PREFIX = "DEPT:";
@Resource
private SysDeptRepository sysDeptRepository;
@Resource
private StringRedisTemplate stringRedisTemplate; /**
* 递归 向下查找当前机构的所有子机构
*/
@Override
public List getAllByPid(Integer pid, List list) {
List subDeptIdList = sysDeptRepository.findIdByPid(pid);
if (CollectionUtils.isEmpty(subDeptIdList)) {
return new ArrayList<>();
} else {
list.addAll(subDeptIdList);
subDeptIdList.forEach(e->{
getAllByPid(e, list);
});
}
return list;
} @Override
public String getSubDeptIdListByPid(Integer pid) {
String key = CACHE_PREFIX + pid;
String val = stringRedisTemplate.opsForValue().get(key);
if (StringUtils.isBlank(val)) {
synchronized (SysDept.class) {
if (StringUtils.isBlank(val)) {
List deptIds = getAllByPid(pid, new ArrayList<>());
deptIds.add(pid);
val = JSON.toJSONString(deptIds);
stringRedisTemplate.opsForValue().set(key, val, 1, TimeUnit.HOURS);
}
}
}
return val;
}
} package com.soa.supervision.gateway.repository; import com.soa.supervision.gateway.entity.SysDept;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import java.util.List; /**
* @Author ChengJianSheng
* @Date 2022/3/8
*/
public interface SysDeptRepository extends JpaRepository { @Query(value = "SELECT id FROM sys_dept WHERE pid = :pid", nativeQuery = true)
List findIdByPid(@Param("pid") Integer pid);
}

5  有用的文档

Spring Security相关

Spring Boot OAuth相关

Spring Security OAuth 笔记的更多相关文章

  1. Spring Security OAuth笔记

    因为工作需要,系统权限安全方面可能要用到Spring Security OAuth2.0,所以,近几天了解了一下OAuth相关的东西.目前好像还没有系统的学习资料,学习主要是通过博客,内容都是大同小异 ...

  2. Spring Security + OAuth系统环境搭建(一)

    最近在做权限管理系统的重构工作,系统基于Spring Security + OAuth架构,整体架构.技术和之前调研的结果差不多,架构调研时有在这篇博客做过简单记录“Spring Cloud微服务下的 ...

  3. SpringBoot + Spring Security 学习笔记(五)实现短信验证码+登录功能

    在 Spring Security 中基于表单的认证模式,默认就是密码帐号登录认证,那么对于短信验证码+登录的方式,Spring Security 没有现成的接口可以使用,所以需要自己的封装一个类似的 ...

  4. SpringBoot + Spring Security 学习笔记(三)实现图片验证码认证

    整体实现逻辑 前端在登录页面时,自动从后台获取最新的验证码图片 服务器接收获取生成验证码请求,生成验证码和对应的图片,图片响应回前端,验证码保存一份到服务器的 session 中 前端用户登录时携带当 ...

  5. Spring Security OAuth 2.0

    续·前一篇<OAuth 2.0> OAuth 2.0 Provider 实现 在OAuth 2.0中,provider角色事实上是把授权服务和资源服务分开,有时候它们也可能在同一个应用中, ...

  6. Spring Security OAuth 2开发者指南译

    Spring Security OAuth 2开发者指南译 介绍 这是用户指南的支持OAuth 2.0.对于OAuth 1.0,一切都是不同的,所以看到它的用户指南. 本用户指南分为两部分,第一部分为 ...

  7. 【微服务】 数据库案例理解Spring Security OAuth

    突然被问,你是做技术的怎么不走技术路线呢?是啊~仔细想想至今做了这么多年的技术,研发过的系统&产品五花八门,涉及到的领域各行各业:政府.军队.公安.国安.石油&石化.金融.教育.华为等 ...

  8. Spring Security OAuth 格式化 token 输出

    个性化token 背景 上一篇文章<Spring Security OAuth 个性化token(一)>有提到,oauth2.0 接口默认返回的报文格式如下: {     "ac ...

  9. Spring Security OAuth正式终止维护,已从官网下架

    Spring Security团队正式宣布Spring Security OAuth终止维护. 目前官网的主页已经高亮提醒彻底停止维护. 旧的Spring Security OAuth项目终止到2.5 ...

随机推荐

  1. 『无为则无心』Python日志 — 66、将日志信息保存到文件中

    目录 1.把日志信息保存到文件中 2.拓展 (1)观察代码 (2)提出问题 (3)问题说明 1.把日志信息保存到文件中 代码如下所示: """ logging模块是Pyt ...

  2. 微信小程序使用weui扩展组件踩坑

    最近在做微信小程序,引入weui的时候踩坑了好久,这里记录一下遇到的问题. 微信官方文档给了两种weui引入方式: 通过 useExtendedLib 扩展库 的方式引入,这种方式引入的组件将不会计入 ...

  3. xlrd》操作excel 出现的问题:File "D:\python37\lib\site-packages\xlrd\formula.py", line 1150, in evaluate_name_formula assert len(tgtobj.stack) == 1

    xlrd>操作excel  出现的问题 报错如下: D:\python37\python.exe D:/testWang/waimai/tools/get_excelData.py*** for ...

  4. UML类图的补充及软件设计原则

    UML类图的补充及软件设计原则 UML 从目标系统的不同角度出发,定义了用例图.类图.对象图.状态图.活动图.时序图.协作图.构件图.部署图等 9 种图. 1.uml补充 统一建模语言(Unified ...

  5. 转发有关tomcat和nginx

    nginx 与 tomcat 组合搭建web服务   部分内容转自 http://www.cnblogs.com/naaoveGIS/ 1. Web服务 nginx是常用的web服务器,用于获取静态资 ...

  6. springboot----二、Hello,SpringBoot!

    二.Hello,SpringBoot! 2.1.环境搭建 java version 1.8 maven springboot 最新版 开发工具:idea 2.2.创建基础项目说明 Spring官方提供 ...

  7. svelte组件:Svelte3自定义Navbar+Tabbr组件|svelte自定义插件

    基于Svelte3自定义组件Navbar+Tabbar沉浸式导航条|底部凸起菜单栏 Svelte 一种全新的构建用户界面的框架.当下热门的 Vue 和 React 在浏览器中需要做大量的工作,而 Sv ...

  8. 微信退款通知,退款回调数据解密.SHA256签名AEAD_AES_256_GCM解密

    $xmlResult = file_get_contents("php://input");//获取微信的数据$result = $this->xmlToArray($xml ...

  9. 同事都说有SQL注入风险,我非说没有

    前言 现在的项目,在操作数据库的时候,我都喜欢用ORM框架,其中EF是一直以来用的比较多的:EF 的封装的确让小伙伴一心注重业务逻辑就行了,不用过多的关注操作数据库的具体细节.但是在某些场景会选择执行 ...

  10. 硬吃一个P0故障,「在线业务」应该如何调优HBase参数?

    1.背景 由于种种原因,最近将核心业务生产使用的HBase迁移到了云上的弹性MapReduce(EMR)集群上,并使用了EMR的HBase组件默认参数配置. 结果在流量高峰期出现了宿主机故障,挂掉了两 ...