通过 Nginx 拦截授权的一种方式

背景

当前有个一个 A 系统,运行良好,含登录认证功能;现在需要接入 B 系统,但是不方便改造 B 系统,然而又需要对接口进行鉴权。

实现

  • 在 B 系统的配置文件中关闭 B 系统自带的认证(若有)
  • 设置 B 系统仅能通过 Nginx 所在机器访问过来
  • 配置 Nginx
upstream prod-api {
    server 192.168.xx.xxx:8811;
}

upstream prod-api-xxx {
    server 192.168.xx.xxx:8822;
}

server {
    listen 8080;
    server_name '192.168.xx.xxx';
    index index.html;
    client_body_buffer_size 10M;
    client_max_body_size 20M;
    proxy_buffers 1024 4k;
    proxy_read_timeout 300;

    location / {
        root /data/frontend/xxx;
        index index.html;
        try_files $uri $uri/ /index.html;
    }

    location ^~ /prod-api/xxx/ {
        auth_request /test_auth;
        auth_request_set $auth_status $upstream_status;
        # error_page 401 =403 /forbidden.html;
        error_page 401 =403 @send_401_json;

        proxy_pass http://prod-api-xxx/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    location /prod-api/ {
        proxy_pass http://prod-api/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    
    location = /test_auth {
        internal;
        #return 401;
    
        proxy_pass              http://prod-api/auth/isLogin;
        proxy_pass_request_body off;
        proxy_set_header        Content-Length "";
    
        # 传递完整的原始URI(包含查询参数)
        proxy_set_header X-Original-URI $request_uri;
        # 也可以单独传递查询参数
        proxy_set_header X-Original-Query $query_string;
    
        proxy_set_header        Host $host;
        proxy_set_header        Cookie $http_cookie;
        proxy_set_header        Authorization $http_authorization;
    }

    location @send_401_json {
        default_type application/json;
        return 403 '{"code":401,"msg":"认证失败,无法访问系统资源","data":null}';
    }
}
  • 在 A 系统中添加接口
@RequestMapping(value = "/isLogin", method = {RequestMethod.HEAD, RequestMethod.GET})
public void isLogin(HttpServletRequest request, HttpServletResponse response) {
    if (StpUtil.isLogin()) {
        response.setStatus(HttpServletResponse.SC_OK);
    } else {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    }
}

这样,就让 A B 两个系统都统一使用了 A 系统的认证功能了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容