0

我正在使用 njs ngx_http_auth_request_module。

我有这样的js函数;

function introspectAccessToken(r) {
    r.subrequest("/_oauth2_send_request",
        function(reply) {
            if (reply.status == 200) {
                r.return(204); // Token is valid, return success code
            } else {
                // need 302 here
            }
        }
    );
}

文档说“如果子请求返回 2xx 响应代码,则允许访问。如果它返回 401 或 403,则访问被拒绝并带有相应的错误代码。子请求返回的任何其他响应代码都被视为错误。” http://nginx.org/en/docs/http/ngx_http_auth_request_module.html

如果 subsequest 进入“else”块,我需要向用户返回 302。

有没有办法做到这一点?如果我设置 r.return(302),它会在浏览器中显示错误页面,如文档所述。

编辑:我的 nginx.conf

location /my-webclient {
    auth_request /_oauth2_token_introspection;
    root   /usr/share/nginx/html;
    rewrite ^ /hmb-profile-webclient/index.html break;
}       

location = /_oauth2_token_introspection {
    internal;
    js_content introspectAccessToken;                                       
}   

location /_oauth2_send_request {
    internal;
    proxy_method      POST;
    proxy_set_body    $cookie_jwt;
    proxy_pass http://my-specific-url;
}   

http://my-specific-url 返回

  • 200,如果 jwt cookie 有效
  • 302(带返回位置),如果 jwt cookie 无效
4

1 回答 1

1

明白了——我认为你甚至不需njs要这样做。如果您的令牌自省端点不是用 NJS 构建的,并且它没有验证令牌是否是有效的 json,但它是用其他语言实现的,则此 NGINX 配置将起作用。

#cache for auth_request responses

proxy_cache_path /var/cache/nginx/oauth keys_zone=token_responses:1m max_size=2m;

#Your Server
server {

  listen 80;


  location / {
    #Redirect Unauthed Request to some other location... 
    error_page 401 =302 http://localhost:9000/login;
  
    auth_request /_auth_request;
    proxy_pass http://127.0.0.1:8080;


  }

  location /_auth_request {
    internal;
    proxy_pass http://127.0.0.1:8090;
    ###place caching responses here to be more effective;
    proxy_cache           token_responses; # Enable caching
    proxy_cache_key       $cookie_jwt;    # Cache for each access token
    proxy_cache_lock      on;              # Duplicate tokens must wait
    proxy_cache_valid     200 10s;         # How long to use each response
    proxy_ignore_headers  Cache-Control Expires Set-Cookie;
  }


}

....

如果您想使用 NJS 构建更多逻辑,例如验证令牌结构,您的方法是使用带有 js_set 的 NJS 的正确方法。

js_include oauth2.js; # Location of JavaScript code

server {
    listen 80;

    location / {
        error_page 401 403 =302 http://localhost:9000/login;
        auth_request /_oauth2_token_introspection;
        proxy_pass http://my_backend;
    }

    location = /_oauth2_token_introspection {
        internal;
        js_content introspectAccessToken;                                       
    }

njs 函数

function introspectAccessToken(r) {
    r.subrequest("/_oauth2_send_request",
        function(reply) {
            if (reply.status == 200) {
                var response = JSON.parse(reply.responseBody);
                if (response.active == true) {
                    r.return(204); // Token is valid, return success code
                } else {
                    r.return(403); // Token is invalid, return forbidden code
                }
            } else {
                r.return(401); // Unexpected response, return 'auth required'
            }
        }
    );
}

error_page指令也将起作用。根据您的代码,我假设您已经查看了这篇文章?

https://www.nginx.com/blog/validating-oauth-2-0-access-tokens-nginx/

ICYMI 这是一篇关于这个用例的很棒的博客文章。

于 2021-08-16T23:12:32.933 回答