欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

Nginx+Lua实现sso单点登录(请求鉴权+获取用户Session信息)

时间:2023-05-15
SSO 解决方案(鉴权+SESSION信息)

项目地址在 https://github.com/1170159634/ssoSolution

一、设计背景

单点登录(SingleSignOn,SSO),就是通过用户的一次性鉴别登录。当用户在身份认证服务器上登录一次以后,即可获得访问单点登录系统中其他关联系统和应用软件的权限,意味着在多个应用系统中,用户只需一次登录就可以访问所有相互信任的应用系统。

但是,鉴权和 session信息应该由谁去处理,如果是后端处理,那么每个系统 只要是对外暴露,或者涉及隐私 或者 必须要求登录情况下操作的接口都需要后端处理,这样做有以下几个缺点:

1)后台服务增加压力,并且nginx到service 请求响应时间会增加

2)增加代码复杂度,因为每个对外暴露的系统都需设计 统一或者 各个组件需要的鉴权方案,容易造成信息不一致性。

3)过多引入 第三方SSO框架会让我们的异常错误不在自己可控制的范围内。同时也不会为我们带来新的单点登录的问题解决方案,不利于提高项目的健壮性及可持续发展。

这不是设计此方案的初衷,我们更希望所有的请求从开始到结束成功或者失败 应该在我们自己的可控范围内。

所以该方案,不借助于第三方框架,并期望请求都先在反向代理做校验, 这样减少了后端压力及代码复杂度,同时方便将组件统一化管理,并可以满足 跨语言系统的实现。

它更适合于 跨语言的系统之间调度,或者 JAVA 老项目(servlet session获取信息),或者希望优化代码的项目中。

二、主要解决的问题

1)请求鉴权,每个请求的访问都有严格的权限控制,公开和非公开

2)全局session管理,各个系统之间仅凭 用户本地cookie就可以拿到用户信息,方便用户操作

3)组件之间鉴权,一旦跨服务,跨系统之间调度,通过组件鉴权提高 系统安全性。

三、技术选型 模块介绍采用组件反向代理openrestySSO服务spring boot (java实现)常规服务 (商品,订单,用户服务)spring boot(java实现)浏览器页面JS四、设计方案-流程 1.系统架构 2.登录流程 3.鉴权流程 3.获取session信息流程 五、核心功能介绍: 1.sso登录

对外暴露的接口 /api/sso/login:

#用户登录 帮助跳到指定页或登录页 location = /api/sso/login { lua_code_cache off; rewrite_by_lua_file lua/sso_login.lua; root /usr/local/Cellar/openresty/1.19.9.1_2/nginx/html; charset utf-8; #默认post请求不支持跳转页面 error_page 405 =200 $uri; }

​ 用户在前端页面,发起登录,nginx收到请求开始处理

nginx先获取post请求体中的用户名和密码,如果没有获取到用户信息,nginx重新跳到登录页nginx发起内部的sso服务登录http请求(api/sso/ssoLogin),将用户信息传入,等待服务返回结果服务如果没有正确返回结果,或者http状态码不为200,nginx重新跳到登录页面如果返回结果,但是登录失败,则跳到登录失败页面如果用户登录成功,lua脚本将信息加密后存入到cookie(ut为用户登录token,uit为用户信息 ),并设置过期时间为30分钟后跳到主页 2.获取用户session信息

对外暴露的接口 /api/sso/getUserInfo:

location = /api/sso/getUserInfo { lua_code_cache off; content_by_lua_file lua/sso_user_info.lua; charset utf-8; }

所有子系统前端页面,通过axios发起获取用户session请求

nginx先获取请求头中的 cookie的加密数据(ut,uit信息),一旦不存在, nginx返回json’{“code”:10001,“msg”:“用户校验失败,请重新登录”}’获取完毕后,解密uit用户信息,取出其中的userId,将用户登录token和userId发起sso服务的鉴权请求(/api/sso/checkLogin)服务如果没有正确返回结果,或者http状态码不为200,nginx 返回json ‘{“code”:10001,“msg”:“用户校,验失败,请重新登录”}’如果返回结果,但是登录失败,则nginx 返回json ‘{“code”:10001,“msg”:“用户校验失败,请重新登录”}’如果返回结果显示校验成功,返回json’{“code”:10000,“msg”:“用户校验成功”,“data”: ’ … decryptData … ‘}’,其中data里的decryptData就为 第二步解密uit用户信息的数据,拿过来直接用 3.访问公开页面(类似于浏览商品,查看商品分类等等)

对外暴露的接口 /api/XXX

location /api/product{ proxy_pass http://127.0.0.1:10082; }

这里不做阐述,直接放行

4.访问私密页面(类似于用户订单,用户收藏,用户好友列表等等)

对外暴露的接口 /api/XXX

location /api/order{ lua_code_cache off; access_by_lua_file lua/sso_filter.lua; proxy_pass http://127.0.0.1:10081; }

浏览器在访问这种的请求时,lua的策略是做权限控制,如果校验通过放行,下发到后面的服务,如果校验不通过,直接让nginx返回 401 500等页面

这里注意:正则表达式可以拦截所有 以/api开头的请求,统一判断,如果请求里包含了"order" “user” "password"等关键字的请求,可以做校验,不然则放行,看个人需要。

nginx先获取请求头中的 cookie的加密数据(ut,uit信息),一旦不存在, nginx直接跳转到400页面获取完毕后,解密uit用户信息,取出其中的userId,将用户登录token和userId发起sso服务的鉴权请求(/api/sso/checkLogin)服务如果没有正确返回结果,或者http状态码不为200,nginx 跳转到500页面如果返回结果,但是登录失败,则nginx跳转到401页面如果返回结果显示校验成功,直接放行 六、后台服务接口文档 1.sso接口 (1)用户登录

【功能定义】

用户登录,并授予用户登录token及session信息(nginx校验用)
接口地址:http://:/sso/ssoLogin

输入:

参数名参数类型是否必填备注user_nameString是用户名user_passwordString是用户密码target_urlString否用户将要访问的资源host_ipString否用户登录地址

输出:

参数参数类型备注codeint10000 校验成功,能够获取用户信息,
10001 校验失败,用户名或密码错误
10002 用户服务异常
10003 未知异常
10004 字段校验错误msgstring中文描述DataJSONObject结果详情 用户session信息,用户token,用户id(2)获取用户session信息

【功能定义】

用于所有系统获取用户已登录后的session信息(nginx校验用)
接口地址:http://:/sso/getUserInfo

输入:

参数名参数类型是否必填备注user_tokenString是用户登录的tokenuser_idString是用户id,和token一起校验host_ipString否用户的登录ip,可判断是否异常登录target_urlString否用户将要访问的资源

输出:

参数参数类型备注codeint10000 校验成功,能够获取用户信息,
10001 校验失败,用户名或密码错误或者token过期
10002 用户服务异常
10003 未知异常
10004 字段校验错误msgstring中文描述(3)校验用户是否登录

【功能定义】

用于校验用户是否处于登录状态(nginx校验使用)
接口地址:http://:/sso/checkToken

输入:

参数名参数类型是否必填备注user_tokenString是用户登录的tokenhost_ipString否用户的登录ip,可判断是否异常登录target_urlString否用户将要访问的资源

输出:

参数参数类型备注codeint10000 校验成功,能够获取用户信息,
10001 校验失败,用户名或密码错误
10002 用户服务异常
10003 未知异常
10004 字段校验错误msgstring中文描述DataJSONObject结果详情 json格式 默认为null2.商品,订单服务接口

没有特殊定义,作为普通服务正常调用接口即可。

注意的是:此次案例以 订单服务作为用户隐私的服务,需要校验登录权限

七、案例

后台所有服务在 sso_all_project下

用户服务:sso-client-user

商品服务:sso-client-product

订单服务:sso-client-user

sso服务:sso-server

nginx和lua配置在sso_nginx_lua_conf下,具体存放位置要基于openresty安装的版本做调整,这里只是列出具体所需文件

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。