Java单点登录技术选型与对比 kisso, sa-token

  1. 背景介绍

       单点登录SSO(Single Sign On),就是在多系统环境下,用户在其中一个系统登录后,就不用在其它系统再登录了。

       早期我们的web系统都是单体应用,所有功能都写到一个war包中,用户登录认证功能处理起来相对比较简单。用户登陆成功后,服务器将用户信息写入到会话中(Session)。会生成 session id来标记这块内存区间是属于你的,并且,这个 session id( jsessionid ) 会写入到你的浏览器 cookie 中,只要你浏览器没关闭,每次向服务器发送请求,服务器就会从你发送过来的 cookie 中去取这个 session id,然后根据这个 session id 到相应的内存中取出你之前存放的数据,但是,如果退出登录。服务器会清除属于你的内存区域,再登录时,重新生成新的 session。

       但是随着应用的访问量不断扩大,单体应用无法满足应用要求,由此分布式应用应运而生。在分布式应用环境下,当某个子系统访问量增加时,我们会把这个系统同时布署多份。当同一个用户登录成功后,由于Nignx反向代理策略不能保存让这个用户访问到同一个子系统,也就是用户登录成功的session是不能在多个子系统中共享的,从而会导致其登录失败。所以在分布式应用中要解决session的同步问题,这就是单点登录的由来。

 

    2. 解决方案:基于kisso的身份认证方案

    kisso = cookie sso 基于 Cookie 的 SSO 中间件,它是一把快速开发 java Web 登录系统(SSO)的瑞士军刀。另外Kisso是基于JWT规范的单点登录中间件。

    开源地址:https://gitee.com/baomidou/kisso.git

### 代码示例 ###

SSOToken ssoToken = SSOToken.create();
ssoToken.setIp(request).setId("1001").setIssuer("admin");
int cookieMaxage = SSOConfig.getInstance().getCookieMaxage();
ssoToken.setTime(new Date().getTime()+cookieMaxage*1000);//设置过期时间
// cookie模式登录,写入加密token值
SSOHelper.setCookie(request, response, ssoToken, true);

// 生成 jwt 票据,访问请求头设置‘ accessToken=票据内容 ’
String jwtToken = ssoToken.getToken();

// 解析票据
SSOToken ssoToken = SSOToken.parser(jwtToken);

// 获取登录用户id, 登录账号
ssoToken = SSOHelper.getSSOToken(request);
String userId = ssoToken.getId();
String loginName = ssoToken.getIssuer();

// 退出登录(清除cookie对应的token信息)
SSOHelper.logout(request, response);


// 多端登录,调用踢人下线,需要实现SSOCache接口
SSOHelper.kickLogin(userId);

// 权限拦截器类 SSOSpringInterceptor
// 注解不拦截 @Login(action = Action.Skip)

// yml 配置 kisso.config....
kisso:
    config:
        signkey: xxxx   #对称签名密钥(非必须)
        cookieName: accessToken  #COOKIE key名称
        cookieDomain: www.domain.com # COOKIE域名

 

    3. 解决方案:基于Sa-Token单点登录+权限认证框架

       如果你的项目属于后台管理系统或者有权限认证相关需求,推荐另一个开源项目:Sa-Token,它是一个轻量级Java权限认证框架;

       主要解决:登录认证、权限认证、Session会话、单点登录、OAuth2.0 等一系列权限相关问题。

       相对于传统老牌框架:Shiro、Spring Security集成时需要自定义Realm,写全局过滤器,写各种配置文件;sa-token的API设计超简单!

       开源地址:https://gitee.com/dromara/sa-token.git  核心功能举例如下:

  • 登录验证 —— 轻松登录鉴权,并提供五种细分场景值
  • 权限验证 —— 适配RBAC权限模型,不同角色不同授权
  • Session会话 —— 专业的数据缓存中心
  • 踢人下线 —— 将违规用户立刻清退下线
  • 分布式会话 —— 提供jwt集成和共享数据中心两种分布式会话方案
  • 微服务网关鉴权 —— 适配Gateway、Soul、Zuul等常见网关组件的请求拦截认证
  • 单点登录 —— 一处登录,处处通行
  • 同端互斥登录 —— 像QQ一样手机电脑同时在线,但是两个手机上互斥登录
### 代码示例 ###
​
// 在登录时写入当前会话的账号id
StpUtil.setLoginId(10001);

// 然后在任意需要校验登录处调用以下API
// 如果当前会话未登录,这句代码会抛出 `NotLoginException`异常
StpUtil.checkLogin();

// 权限认证示例 (只有具有user:add权限的会话才可以进入请求)
@SaCheckPermission("user:add")
@RequestMapping("/user/insert")
public String insert(SysUser user) {
	// ... 
	return "用户增加";
}

// 使账号id为10001的会话注销登录
StpUtil.logoutByLoginId(10001);

StpUtil.setLoginId(10001);                // 标记当前会话登录的账号id
StpUtil.getLoginId();                     // 获取当前会话登录的账号id
StpUtil.isLogin();                        // 获取当前会话是否已经登录, 返回true或false
StpUtil.logout();                         // 当前会话注销登录
StpUtil.logoutByLoginId(10001);           // 让账号为10001的会话注销登录(踢人下线)
StpUtil.hasRole("super-admin");           // 查询当前账号是否含有指定角色标识
StpUtil.hasPermission("user:add");        // 查询当前账号是否含有指定权限, 返回true或false
StpUtil.getSession();                     // 获取当前账号id的Session
StpUtil.getSessionByLoginId(10001);       // 获取账号id为10001的Session
StpUtil.getTokenValueByLoginId(10001);    // 获取账号id为10001的token令牌值
StpUtil.setLoginId(10001, "PC");          // 指定设备标识登录
StpUtil.logoutByLoginId(10001, "PC");     // 指定设备标识进行强制注销 (不同端不受影响)
StpUtil.switchTo(10044);                  // 将当前会话身份临时切换为其它账号

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星梦天河

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值