SSO...........

2023-12-13 11:52
文章标签 sso ...........

本文主要是介绍SSO...........,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

单点登录逻辑:

目录

一、用户访问WEB服务器资源

二、WEB服务器过滤请求URL,排除不需要过滤(即不需要鉴权的请求),然后基于请求的cookie或token匹配redis中的session_id

三、匹配成功放行请求执行Controller,否则清空cookie或返回json提示并结束请求。


一、浏览器访问web服务器资源

定义controller接收请求

二、Filter过滤请求

web服务器基于url过滤请求,首先排除不需要过滤url(白名单),然后基于请求的cookie或token匹配redis中的session_id

1、自定义过滤器

① 创建过滤器注册Bean(FilterRegistrationBean)

FilterRegistrationBean 是 Spring 提供的用于配置和注册 Servlet 过滤器的类。它允许通过 Java 代码的方式配置过滤器,并提供了一系列方法来设置过滤器的属性。这类过滤器的初始化参数通常用于在过滤器初始化时提供一些配置信息。

FilterRegistrationBean registration = new FilterRegistrationBean();
通过这行代码创建了一个 FilterRegistrationBean 实例,用于配置和注册过滤器。

设置过滤器名称:
registration.setName("XxlSsoWebFilter");
通过 setName 方法设置了过滤器的名称。这个名称可以在 Servlet 容器中唯一标识这个过滤器。

设置过滤器执行顺序:
registration.setOrder(1);
通过 setOrder 方法设置了过滤器的执行顺序。数字越小,优先级越高。

设置过滤器的 URL 匹配模式:
registration.addUrlPatterns("/*");
通过 addUrlPatterns 方法设置了过滤器要拦截的 URL 模式。这里设置为 "/*" 表示拦截所有请求。

设置过滤器实例:
registration.setFilter(new XxlSsoWebFilter());
通过 setFilter 方法设置了要注册的过滤器实例,这里是 XxlSsoWebFilter 类的一个实例。

设置过滤器的初始化参数:
registration.addInitParameter(Conf.SSO_SERVER, xxlSsoServer);
registration.addInitParameter(Conf.SSO_LOGOUT_PATH, xxlSsoLogoutPath);
registration.addInitParameter(Conf.SSO_EXCLUDED_PATHS, xxlSsoExcludedPaths);

通过 addInitParameter 方法为过滤器设置初始化参数。这些参数在过滤器初始化时会传递给 init 方法,供过滤器内部使用。

这些初始化参数的具体用途,通常由对应的过滤器的实现逻辑来决定。在过滤器的 init 方法中,可以通过 FilterConfig 对象获取这些初始化参数,以便在过滤器运行期间使用。

返回 FilterRegistrationBean 实例:
return registration;
最后,通过 return registration; 将配置好的 FilterRegistrationBean 实例返回,从而使其生效。

过滤器的初始化参数通常在过滤器的 init 方法中用到,这是过滤器的生命周期中的一个阶段,用于执行一些初始化操作。当过滤器被容器初始化时,init 方法被调用,传入一个 FilterConfig 对象,该对象包含了通过 addInitParameter 设置的初始化参数。过滤器可以在 init 方法中读取这些参数,并进行相应的初始化配置。

过滤器的创建时机取决于 Spring 容器和 Servlet 容器的初始化顺序。通常,在 Spring Boot 中,过滤器会在应用启动时由 Spring 容器创建并注册到 Servlet 容器中。当应用启动时,Spring 容器会解析并执行相关的配置类,其中包括 FilterRegistrationBean 的配置,从而创建并注册相应的过滤器。

2、如何匹配路径,判断请求路径是否不需过滤?


基于 Ant表达式 匹配路径,匹配放行,从而排除SSO客户端不需要过滤的路径,达到类似白名单的效果。

3、如何获取cookie或token?


request.getCookies()
request.getParameter()

三、连接redis并操作redis数据


1、采用redis分片存储用户令牌的方式。

private static ShardedJedis getInstance() {if (shardedJedisPool == null) {try {if (INSTANCE_INIT_LOCL.tryLock(2, TimeUnit.SECONDS)) {try {if (shardedJedisPool == null) {// JedisPoolConfigJedisPoolConfig config = new JedisPoolConfig();config.setMaxTotal(200);config.setMaxIdle(50);config.setMinIdle(8);config.setMaxWaitMillis(10000);         // 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1config.setTestOnBorrow(true);           // 在获取连接的时候检查有效性, 默认falseconfig.setTestOnReturn(false);          // 调用returnObject方法时,是否进行有效检查config.setTestWhileIdle(true);          // Idle时进行连接扫描config.setTimeBetweenEvictionRunsMillis(30000);     // 表示idle object evitor两次扫描之间要sleep的毫秒数config.setNumTestsPerEvictionRun(10);               // 表示idle object evitor每次扫描的最多的对象数config.setMinEvictableIdleTimeMillis(60000);        // 表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义// JedisShardInfo ListList<JedisShardInfo> jedisShardInfos = new LinkedList<JedisShardInfo>();String[] addressArr = address.split(",");for (int i = 0; i < addressArr.length; i++) {JedisShardInfo jedisShardInfo = new JedisShardInfo(addressArr[i]);jedisShardInfos.add(jedisShardInfo);}shardedJedisPool = new ShardedJedisPool(config, jedisShardInfos);logger.info(">>>>>>>>>>> xxl-sso, JedisUtil.ShardedJedisPool init success.");}} finally {INSTANCE_INIT_LOCL.unlock();}}} catch (InterruptedException e) {logger.error(e.getMessage(), e);}}if (shardedJedisPool == null) {throw new NullPointerException(">>>>>>>>>>> xxl-sso, JedisUtil.ShardedJedisPool is null.");}ShardedJedis shardedJedis = shardedJedisPool.getResource();return shardedJedis;}

这段代码主要是用于获取 Redis 的 ShardedJedis 实例,通过连接池管理多个 Redis 节点的连接。下面对代码的不同部分进行详细解释:

  1. 为什么使用 ShardedJedis: ShardedJedis 是 Jedis 库提供的一种实现,用于处理 Redis 的分片连接。在分布式 Redis 环境中,可能会有多个 Redis 节点,使用 ShardedJedis 可以将数据分布到不同的节点上,提高数据的存储和读取性能。

  2. 为什么使用 ShardedJedisPool: ShardedJedisPool 是 ShardedJedis 的连接池实现,用于管理和复用连接。连接池的使用可以减少连接的创建和销毁开销,提高性能。

  3. 为什么使用单例模式创建连接池: 使用 INSTANCE_INIT_LOCL 可重入锁进行单例模式的实现,确保在多线程环境下只创建一个连接池。这样可以避免重复创建连接池,提高效率,同时保证线程安全。

  4. 连接池配置:

     

    javaCopy code

    JedisPoolConfig config = new JedisPoolConfig(); // ...(省略了一些连接池的配置,如最大连接数、最小空闲连接数等)

    这里通过 JedisPoolConfig 对象对连接池进行了一些基本配置,如最大连接数、最小空闲连接数等,以及一些其他连接池的配置参数。

  5. Redis 节点信息配置:

     

    javaCopy code

    List<JedisShardInfo> jedisShardInfos = new LinkedList<JedisShardInfo>(); String[] addressArr = address.split(","); for (int i = 0; i < addressArr.length; i++) { JedisShardInfo jedisShardInfo = new JedisShardInfo(addressArr[i]); jedisShardInfos.add(jedisShardInfo); }

    这里根据传入的 Redis 节点地址列表,创建了一个 JedisShardInfo 的列表。每个 JedisShardInfo 对象表示一个 Redis 节点的连接信息。

  6. 创建 ShardedJedisPool:

    shardedJedisPool = new ShardedJedisPool(config, jedisShardInfos);

    最终通过连接池的构造函数创建了 ShardedJedisPool 对象。

  7. 获取 ShardedJedis 实例:

    ShardedJedis shardedJedis = shardedJedisPool.getResource(); return shardedJedis;

    最后通过连接池获取 ShardedJedis 实例,用于执行 Redis 相关的操作。shardedJedisPool.getResource() 表示从连接池中获取一个可用的连接。

  8. 为什么使用可重入锁:

    if (INSTANCE_INIT_LOCL.tryLock(2, TimeUnit.SECONDS)) { // ...(省略了部分代码) }

    使用可重入锁 INSTANCE_INIT_LOCL,确保在多线程环境下只有一个线程创建连接池。这样可以避免多个线程同时创建连接池,导致资源浪费和性能问题。

总体来说,这段代码的目的是确保在多线程环境下创建一个单例的 ShardedJedisPool 对象,用于管理多个 Redis 节点的连接,并提供了一些配置项来优化连接池的性能。

四、匹配成功放行请求执行Controller,否则清空cookie或返回json提示并结束请求。

1、如何清空cookie?


重新new个cookie => 初始化 => response.addCookie(cookie);


2、如何返回json错误提示?


设置响应文本类型         =>  res.setContentType("application/json;charset=utf-8");
构建错误码和错误消息(json字符串)     =>  String errInfo = ""
将错误消息写入响应输出流 =>  res.getWriter().println(errInfo)

这篇关于SSO...........的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/488369

相关文章

API 网关 OpenID Connect 实战:单点登录(SSO)如此简单

作者:戴靖泽,阿里云 API 网关研发,Higress 开源社区 Member 前言 随着企业的发展,所使用的系统数量逐渐增多,用户在使用不同系统时需要频繁登录,导致用户体验较差。单点登录(Single Sign-On,简称 SSO)正是为了解决这一问题。当用户登录一次后,即可获取所有系统的访问权限,不需要对每个单一系统逐一登录。 目前,SSO 的实现方案常见有以下几种: 基于 JWT:

SSO之CAS单点登录

本文目录: 一、概述二、演示环境三、JDK安装配置四、安全证书配置五、部署CAS-Server相关的Tomcat六、部署CAS-Client相关的Tomcat七、 测试验证SSO 一、概述 此文的目的就是为了帮助初步接触SSO和CAS 的人员提供一个入门指南,一步一步演示如何实现基于CAS的单点登录。 CAS的官网:http://www.jasig.org/cas 二、演示环境 本文演

阿里“10”年软件测试经验,面试官通常...........

(一)面试前的准备工作 (1)在家中记背软件测试基础知识性题目以及测试用例的写法。 (2)调查面试公司的网址、公司介绍、公司的地址这些是否是属实。 (3)保持好良好的心态,衣着稍微正式一点不要穿平时在家穿的休闲衣服。女性稍加花点淡妆。塑造一个看起充满自信又美丽的女人或是一个看起充满活力潇洒的男人。 (4)去面试公司的乘坐路线必须在去之前都在网上查好抄在纸上,那个面试公司的、应聘职位、联系方

项目技术总结二之SSO单点登录

中期验收结束后就一直很想写这篇博客,因为我可以说是其中出丑出的最多的,但是我也是成长的最多的,这次验收,我们的所有系统没有实现单点登录,所以当时师哥跟我说的时候我就说因为CAS没有加上我们就没有用,但是当时师哥问了我一个问题就是什么是CAS,我说就是单点登录用的,但是当时说的很没有底气,因为我也是之前听负责这部分研究人员询问过,所以在寒假的时候我就查找了关于这部分的知识!      首

【Cas】(一)cas实现SSO简单介绍

(一)什么是SSO   Single Sign On,SSO是一种统一认证和授权机制,指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用中的受保护资源时,不再需要重新登录验证。     解决了用户只需要登录一次就可以访问所有相互信任的应用系统,而不用重复登录。     用8个字形容SSO,就是“一处登陆,处处穿梭”。 (二)什

springboot shiro 使用redis存储登录信息 实现单点登录sso

shiro 默认使用的是session 存储登录信息的,这对于单体应用来讲是没有什么问题的,但是对于分布式应用或者集群应用就行不通了,因为集群或者分布式系统 应用部署在不同的jvm 上,session不能共享。如果使用redis存储登录信息则可以解决这个问题,这里简单使用 shiro-redis框架 来实现这个功能 具体流程如下 首先我们创建一个springboot 父子工程  父工

Tomcat+Cas整合SSO

配置说明 1.   前提 使用的软件包:tomcat 7,cas-client-3.1.12,cas-server-3.3.5 配置步骤 1. 配置服务器端的数字证书 1.1生成keyStore 生成keyStore ,在命令行输入:   1.生成数字证书    keytool-genkey -alias zhouzhou-keyalg RSA 按照提示来: 输

smart-sso单点登录(三):接入指南

目录 前言1.引入客户端依赖2.应用配置修改3.验证 前言 如果您的SpringBoot应用需要接入到smart-sso,只需要简单的两步即可完成。 1.引入客户端依赖 在您任意的SpringBoot应用中maven的pom.xml配置中增加客户端依赖。 <dependency><groupId>com.smart</groupId><artifactId>smart-s

新浪微博--SSO

1.获取应用的,appkey, appsecret  redirectUrl :分别为应用密钥,应用密码,回调地址。(需要注意bundle id  是否一致) 2.下载新浪微博官网的SDK (注意,在获取用户accesstoken,userid ,expire_in ,返回的有效时间字符串是7为数,需要加上当前的时间戳11位,才是有效时间。) 3.按文档说明一步步处理:在获取用户个人信息时是调

《SSO系列二》自己动手写一个SSO

概述 上篇博客http://blog.csdn.net/bingospunky中大概的介绍了一下SSO。这篇文章介绍一个我学习过程中写的一个Demo,可以让初学者对SSO有一个整体的认识。 线上演示 我已经把我这个Demo部署在我的服务器上,你可以按照如下步骤体验。(需要翻墙) 1.两个业务的地址分别是 http://taobao.mabinbin.com/bzi1/user/index