NGINX not sending headers or variables to js_content inside auth_request

1.3k views Asked by At

I've been having some problems with NGINX recently. I need to build a NGINX reverse proxy which takes some information inside of specific NGINX variables and sends it to an Authorization Server. Before being sent to said AuthServer though, it needs to be parsed into the body of an HTTP POST request.

In order to do this last step, I've decided to write an NJS function which takes this information and sends it to the Authorization Server through a subrequest.

However, there's a tiny problem: since the NJS function is called inside the auth_request location, it apparently does not have access to the NGINX variables.

So, I've tried to send the variables value to the NJS function through some costum headers added by the configuration (both inside the auth_request location and outside of it). Unfortunately, this didn't solve the problem.

Here's my NGINX config file:

location /operation/ {
    auth_request /authz; 
    auth_request_set $example_variable "Plz work variable";
    add_header X-Example-Header1 "Plz work header 1";
    proxy_set_header X-Example-Header2 "Plz work header 2";
    
    proxy_pass_request_headers on;
    proxy_pass http://service;
}

location /authz {
    internal;
    proxy_pass_header Authorization;
    proxy_set_header Authorization $http_authorization;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;
    proxy_set_header X-Original-METHOD $request_method;
    add_header X-Example-Header3 "Plz work header 3";
    proxy_set_header X-Example-Header4 "Plz work header 4";

    proxy_pass_request_headers on; 

    js_content auth_engine.authorize_operation;
}

Here's the code of the JS function used in js_content:

function authorize_operation(r) {

    r.log(JSON.stringify(r.headersIn));
    r.log(JSON.stringify(r.variables));
    
    // ...some code which sends data to OPA...
}

Both lines of code in authorize_operation do not print the information that should have been added by the NGINX configuration. Specifically, the first r.log prints only the headers of the initial request (and not the headers added by the configuration) and the second one does not print anything, only some curly brackets.

Is there any way to fix this?

2

There are 2 answers

0
Nidhi Rajpal On

2nd query of your question: "r.variables" doesn't print anything.

For using variables in njs (nginx js script), specifying the exact name of variable that you are looking for, helped in my case. for example, trying to access the Request-URI:

var uri = r.variables.request_uri

3
Ivan Shatsky On

This is somewhat too big to be a comment, so I'm writing this as an answer.

You have a weird mix of different purpose directives in your /authz location. First of all, the content handler of this location will be an njs function, declared via

js_content auth_engine.authorize_operation;

Therefore, there is no sense in those proxy_set_header and other directives from the http_proxy_module. If you don't understand what content handler is, read the beginning of this ServerFault answer. Note than you cannot mix two different content handlers within the single location (both js_content and proxy_pass directives are content handler declarations).

If you want to mix njs code with the auth_request subrequest, take a look at the Validating OAuth 2.0 Access Tokens with NGINX and NGINX Plus article. You'd need to invoke an additional subrequest, which will actually make a request to your auth backend, via the r.subrequest method of HTTP Request njs object. The aforementioned article has an excellent example of how this can be implemented.