轻量级 SSO 方略

2023-10-29 05:20
文章标签 轻量级 sso 方略

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

单点登录 SSO(Single Sign On)是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。打通所有系统的账户密码,只需要记住一个就行,而且登录一个系统后,打开其他系统不需要再登录。广义的单点登录概念还涵盖了第三方登录:己方应用信任第三方应用,用户只需在第三方应用上登录一次,就可以访问己方应用。

更高阶的产品 IAM(Identity and Access Management),即“身份识别与访问管理”,具有单点登录、强大的认证管理、基于策略的集中式授权和审计、动态授权、企业可管理性等功能。参考开源项目 Keycloak。

OIDC

OIDC 是 OpenID Connect,官网介绍。

感觉 OAuth 太负盛名了,以至于后来在 OIDC 反而难以企及前辈 OAuth。倒是大家谈论比较多的是 JWT(例如https://www.cnblogs.com/lyzg/p/6132801.html),——实际谈 JWT 就是在实现 OIDC,反而 OIDC 大家不怎么爱谈!但我们要知道的是,真正诠释这些的,做点单点登录的,——是 OIDC 规范,JWT 只是 OIDC 规范下的一种 Token 协议,再说句难听的,如果 JWT 不满足或者有问题,换别的 Token 实现规则也行。

不过话说回来,OIDC 与 OAuth 看上去大体是相近,只是把应用场景稍作转换,另外就是返回 Token 的不同,OAuth 不限定 Token 具体实现如何,而 OIDC 推荐带用户信息的 JWT。所以,这么说,也不能怪人们总爱谈 JWT 而忽视 OIDC

部署

目标是部署简单,且灵活多种方式。下面是 SSO 中心的部署方式。

单独部署整合部署
部署形态WAR/JAR 包,单独进程运行JAR 包引入依赖,或源码整合
优点独立维护占资源更低

除了 SSO 中心的部署,还有客户端以 JAR 包的形式提供。

无状态设计

传统认证基于 Cookie+Session 的方式,是有状态的;单机时代问题不大,但到了集群的时候,如何同步 Session 是件麻烦的事情。另外一个方法是绑定 Session 到指定某一台机器,但这样不仅带来复杂性,而且还不能彻底解决问题。因此,渐渐有了以下分野:

  • 服务端是无状态的:服务端组件不保存会话状态。
  • 服务端是有状态的:服务端组件保存了会话状态。

我们主张服务端无状态的设计。当服务端组件不保存任何会话状态时,伸缩将比较容易,直接增加/减少物理服务器的台数即可。《Web应用中的状态(会话状态、应用状态、有状态协议、无状态协议、REST无状态约束)》这文章分析得很透彻了。

关于 Token 的设计

Token 从简单到复杂,可以采取下面几种方案。

  • 最简单的 Token,就是随机字符串,那么我们用 UUID/GUID 即可
  • 如果有验证 AuthToken 合法性需求,可以将 UserName+ 时间戳加密生成,服务端解密之后验证合法性
  • JWT。我们后面重点说 JWT

可配置

强调系统的鲁棒性,从最简单的组件到复杂的组件,均可支持,例如,缓存组件,简单点的你可以使用本地的 Servlet Session,高级一点的可以采用 Redis。

应用 App

每个想要接入OAuth 授权服务的第三方客户端都需要事先在服务端这里“备案”,这样可以更好的管理接入的第三方应用。App 多数时候与 Client 的概念是一致的。

注册应用的时候一般需要提供一些基本信息,比如应用名称、网址、logo 等。主要需要以下几个字段:

  • name:应用的名称,这个便于后台管理用的
  • client_id:每个应用客户端的 client_id 是唯一的,相当于用户名,通常是一个随机生成的字符串,client_id 可以直接写在 Javascript 或者源码页面里面
  • client_secret:这个秘钥是应用客户端和 OAuth2.0 服务端共同持有,用于鉴别请求中的身份,通常也是一个随机生成的字符串。client_secret 必须保证绝对机密,不能泄露给其他人。如果你部署的应用无法保证 client_secret 安全的话,比如Javascript 应用或者 Native APP,那么则不能使用 client_secret。一般来说,只有服务器端才可以保存 client_secret
  • redirect_uri:第三方应用的地址。Redirect URI 可以在用户授权完成之后重定向回你的应用。Redirect URI 授权服务器只会重定向用户到已经注册过的 URI,以避免一些恶意攻击

模块设计

表设计及界面设计如下

CREATE TABLE `app` (`id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '主键 id,自增',`pid` INT(10) NOT NULL DEFAULT '0' COMMENT '父级 id',`name` VARCHAR(20) NOT NULL COMMENT '名称' COLLATE 'utf8mb4_unicode_ci',`content` VARCHAR(256) NULL DEFAULT NULL COMMENT '简介' COLLATE 'utf8mb4_unicode_ci',`client_id` VARCHAR(256) NOT NULL COMMENT '客户端 id' COLLATE 'utf8mb4_unicode_ci',`client_secret` VARCHAR(256) NOT NULL COMMENT '客户端秘钥' COLLATE 'utf8mb4_unicode_ci',`redirect_uri` VARCHAR(256) NOT NULL COMMENT '用户授权完成之后重定向回你的应用' COLLATE 'utf8mb4_unicode_ci',`type` VARCHAR(20) NULL DEFAULT 'MISC' COMMENT '应用类型:HTML, APP,API_SERVICE, RPC_SERVICE, MISC' COLLATE 'utf8mb4_unicode_ci',`logo` VARCHAR(200) NULL DEFAULT NULL COMMENT '图标' COLLATE 'utf8mb4_unicode_ci',`stat` TINYINT(3) NULL DEFAULT NULL COMMENT '数据字典:状态',`extend` TEXT NULL DEFAULT NULL COMMENT '扩展 JSON 字段' COLLATE 'utf8mb4_unicode_ci',`creator` VARCHAR(50) NULL DEFAULT NULL COMMENT '创建人名称(可冗余的)' COLLATE 'utf8mb4_bin',`creator_id` INT(10) NULL DEFAULT NULL COMMENT '创建人 id',`create_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期',`updater` VARCHAR(50) NULL DEFAULT NULL COMMENT '修改人名称(可冗余的)' COLLATE 'utf8mb4_bin',`updater_id` INT(10) NULL DEFAULT NULL COMMENT '修改人 id',`update_date` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改日期',PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `id_UNIQUE` (`id`) USING BTREE
)
COMMENT='应用/客户端'

在这里插入图片描述

计划

抽象 App 概念,可纳入 System,利用 pid 做层级。

授权模式对比总结

本文只对前后端授权常见的授权码模式做详细介绍,其他授权模式可自行了解,这里只做简单介绍。

在这里插入图片描述

配置

用户密码的加密规则

用户密码当然不能明文保存到数据库中,因为一旦泄露密码,危害的不止系统本身,还有危害用户的切身利益(因为用户不同系统的密码可能是一样的)。那么怎么实现一个加密规则呢?

AJ-IAM 把这个问题开放出来,允许用户自定义自己的加密规则。下面是一个简单的 MD5 加盐配置例子。

/*** 指定密码的加密规则*/
@Bean("passwordEncode")
Function<String, String> passwordEncode() {return PasswordEncoder::md5salt;
}

因为比较简单的缘故,我们并没有设计一个 Java Interface 去定义,而是一个 Lambda:Function<String, String>搞定。输入参数是明文,返回值是密文。要知道,Spring 对 Lambda 也是可以注入的。PasswordEncoder::md5salt参见:

package com.ajaxjs.user.service.business;import com.ajaxjs.util.Digest;/*** 密码加密规则*/
public class PasswordEncoder {/*** 盐值*/private static final String SALT = "@#D2s!As12";/*** 基本的密码加密** @param psw 明文* @return 密文*/public static String md5salt(String psw) {return Digest.md5(psw + SALT);}
}
  • 认证(Authentication),识别你是谁。即在网站上用来识别某个用户是否是注册过的合法用户。本文前半段皆在讲认证;
  • 授权(Authorization),识别你能做什么。即在网站上用来识别某个用户是否有某方面的权限。本文后半段皆在讲授权。

开源参考

  • 符节开源 JAP https://gitee.com/fujieid/jap、https://gitee.com/fujieid/jap-ids-oauthserver
  • ArkID : 企业级IDaaS/IAM平台系统
  • TopIAM 数字身份管控平台
  • 推荐七个非常实用的OAuth开源项目
  • MITREid Connect

安全考量

Insufficient Redirect URI validation: The risk of allowing to dynamically add arbitrary query parameters and fragments to the redirect_uri。这是一种 OAuth 2.0 和 OpenID Connect 1.0 实现缺陷模式,允许动态添加查询参数和片段到 redirect_uri。如果 redirect_uri 没有得到适当的验证,攻击者可以构造一个包含指向攻击者控制的服务器的 URL 的链接。这可以用来欺骗 AS 将授权代码发送给攻击者。如果用户在用户代理中打开此链接,AS 将重定向用户代理到恶意 URL。攻击者可以捕获伪造 URL 中传递的代码值,然后将其提交给 AS 令牌端点。如果您想测试 AS 是否容易受到不足的重定向 URI 验证,请使用 HTTP 拦截代理(例如 ZAP)捕获流量。启动 OAuth 流并在授权请求处暂停它。更改 redirect_uri 的值并观察响应。调查响应并确定是否接受了任意 redirect_uri 参数。如果 AS 将用户代理重定向到您指定的 redirect_uri,则 AS 未正确验证 redirect_uri。

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



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

相关文章

python+selenium2轻量级框架设计-04读取数据库

#操作sql server数据库 使用mysql则导入pymysqlimport pymssql,pymysqldb =pymssql.connect("localhost","sa","***","****")#使用cursor()方法获取操作游标cursor = db.cursor()sql = "****"try:#执行sqlcursor.execute(sql)#fetchon

python+selenium2轻量级框架设计-03读取配置文件

任何一个项目,都涉及到了配置文件和管理和读写,Python支持很多配置文件的读写,这里介绍读取ini文件。 以读取url和浏览器作为例子 #浏览器引擎类import configparser,time,osfrom selenium import webdriverfrom framework.logger import Loggerlogger = Logger(logger='

python+selenium2轻量级框架设计-02日志类

本文介绍如何写一个Python日志类,用来输出不同级别的日志信息到本地文件夹下的日志文件里。 import logging,time,osclass Logger(object):def __init__(self,logger):'''指定保存日志的文件路径,日志级别,以及调用文件将日志存入到指定的文件中'''#创建loggerself.logger = logging.getLogge

python+selenium2轻量级框架设计-01框架结构

接下来会介绍一个比较简单的框架结构,先看一下分类 config文件夹里放的是配置文件 framework文件夹里面放的是公共类,常用类,还有读配置文件类、日志类、截图类、发送邮件、生成测试报告、操作读取数据库、读取Excel等,后面几篇会一一介绍 logs文件夹存放生成的日志文件 pageobject存放页面类包括元素的定位等 screenshots文件放的是生成的截图 test_

轻量级模型解读——ShuffleNet系列

和MobileNet一样,shuffleNet也是常用的轻量级模型,由旷视科技2017年首次提出 文章目录 1、ShuffleNetv12、ShuffleNetv2 首先上一张ShuffleNetv1和ShuffleNetv2两者参数量及ImageNet数据集上表现情况对比: 1、ShuffleNetv1 2017年,旷视科技提出ShuffleNet,该网络结构专

PHP轻量级高性能HTTP服务框架 - webman

摘要 webman 是一款基于 workerman 开发的高性能 HTTP 服务框架。webman 用于替代传统的 php-fpm 架构,提供超高性能可扩展的 HTTP 服务。你可以用 webman 开发网站,也可以开发 HTTP 接口或者微服务。 除此之外,webman 还支持自定义进程,可以做 workerman 能做的任何事情,例如 websocket 服务、物联网、游戏、TCP 服务、

JWT详解:一种轻量级的身份验证和授权机制

引言 JSON Web Token(JWT)是一种基于JSON格式的开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地传输信息。JWT因其轻量级、可扩展性和安全性,在Web应用程序和RESTful API中得到了广泛应用。本文将详细解析JWT的概念、结构、工作原理、应用场景以及使用时的安全注意事项。 JWT的基本概念 JWT是一种用于在用户和服务器之间传递安全

轻量级模型解读——EfficientNet系列

EfficientNet自2019年谷歌提出以来,经历了三个版本,2019EfficientNet ——> 2020EfficientNet-Lite——> 2021EfficientNetv2 文章目录 1、EfficientNet2、EfficientNetv23、EfficientNet-Lite 对于EfficientNet和EfficientNetv2的解读可

梳理轻量级建模软件Silo中的所有操作(2):修改

前言 修改(Modify)类操作是建模时使用最为频繁的操作,因此几乎每个操作都分配了快捷键。 本篇包含的快捷键有27个: 操作快捷键追加面(P)追加边(Shift+E)倒角(B)布尔减(,)布尔合(Ctrl+,)布尔交(Shift+<)分离(Ctrl+B)桥接(Shift+B)割裂(X)挤出(Z)补洞(Shift+F)拍扁(Alt+Shift+F)插入型缩放(I)局部缩放(Ctrl+E)局部

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

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