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