sso
sso 单点登录
1 单点登录时序图
+-----------------+ +---------------------+ +-----------+
|~* /static/ | |= /auth/verification | |/ |
|= /index_sso.html| |= /butterfly_401 | | | Nginx 配置
|= / | |= /auth/ssologin | | |
+-----------------+ +---------------------+ +-----------+
| | |
+----------+ +---------------+ +--------------+ +----------+ +-----------+
|web browse| |butterfly-admin| |butterfly-auth| |cas-server| |app-backend| 服务
+----------+ +---------------+ +--------------+ +----------+ +-----------+
| | | | |
+-------route------->|/ | | |
|<-------page--------+/index_sso.html | | |
| | | | |
====================================================================not have token
| | | | |
+--V----------------request api---------------------------------------------------->| 1 客户端请求后端接口返回 401
| +-sub request-header not have token--->|(/auth/verification) | |
|<-code=401,targetURL=/auth/ssologin------+ | |
| | | | |
+--window.location.herf=directurl-------->|(/auth/ssologin) | | 2 客户端设置当前页面的 URL 地址为 /auth/ssologin
|<----code=302,Location=cas-server--------+ | |
| | | | |
+-----302 http://cas-server/login login page ----------------->|(/login) | 3 客户端根据 butterfly-auth 返回内容重定向到 cas-server
|<-------------code=302,set Cookie TGT=xxx ---------------------+ |
| | | | |
+-----302 /auth/ssologin?ticket=xxx ----->|(/auth/ssologin) | | 4 客户端根据 cas-server 返回内容重定向到 /auth/ssologin
| | +-------check st----->|(/session/validate)|
| | |<-------st vaild-----+ |
|<--code=302 set Cookie butterfly_token---+ | |
| | | | |
+--302 / ----------->| | | | 5 客户端重新请求首页
|<-------page--------+/index_sso.html | | |
| | | | |
======================================================================== have token
| | | | |
+---V----------------request api--------------------------------------------------->|
| +-sub request-header have token------>|(/auth/verification) | |
|<-------------------response-------------------------------------------------------+
2 butterfly-admin 关键点
2.1 nginx auth request
Authentication Based on Subrequest Result(基于子请求结果的认证)
Nginx auth 子请求是通过 HTTP GET 方法发送的,即使原请求是 POST 请求,auth 子请求也会转为 GET 请求,GET 请求没有 body , body 被丢弃。
nginx 配置
# 认证接口
location = /auth/verification {
internal;
proxy_pass http://127.0.0.1:8001;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
# 真实的请求路径
proxy_set_header X-Original-URI $request_uri;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-PORT $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#对 / 所有做负载均衡 + 反向代理
location / {
auth_request /auth/verification;
auth_request_set $butterfly_location $upstream_http_location;
error_page 401 = /butterfly_401;
proxy_redirect off;
# 后端的 Web 服务器可以通过 X-Forwarded-For 获取用户真实 IP
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_pass http://backend;
}
location = /butterfly_401 {
internal;
default_type application/json;
if ($butterfly_location) {
return 401 '{"success":false,"message":"You are not authorized","data":{"Target_url":"$butterfly_location"}}';
}
}
2.2 amis 全局适配器
// 全局请求适配器。参考:官网 -> 快速开始 -> 控制 amis 的行为
requestAdaptor(api) {
api.headers["Authorization"] = "Bearer: " + Cookies.get('butterfly_token');
//console.log("全局请求适配器", api);
return api;
},
// 全局响应适配器。参考:官网 -> 快速开始 -> 控制 amis 的行为
responseAdaptor(api, payload, query, request, response) {
//console.log("全局响应适配器", response);
if (response.status == 401) {
window.location.href = "/auth/ssologin";
return {
status: 401,
msg: "请登录"
}
}
return payload;
},
2.3 Token 存储方式
单点登录时,需要跳转到 butterfly-admin 单页之外进行登录,则无法使用拦截器进行拦截,故而需要使用 Cookie
浏览器获取 Cookie 方式:
F12,Console,在命令框内输入:document.cookie,显示返回
Last updated