checking headers

Francis Daly francis at daoine.org
Tue May 31 23:06:19 UTC 2016


On Tue, May 31, 2016 at 04:48:19PM -0400, Larry Martell wrote:
> On Tue, May 31, 2016 at 4:19 PM, Francis Daly <francis at daoine.org> wrote:
> > On Tue, May 31, 2016 at 12:33:56PM -0400, Larry Martell wrote:

Hi there,

> > It sounds like your design is that your client sends a http request to
> > port 8004; the http service there returns a 301 redirect to a url on port
> > 8000 and includes a particular response header; and you want your client
> > to follow the redirect by making a new request to port 8000 and include a
> > request header that mirrors the particular response header that you sent.
> 
> With the django app, what you are saying is correct.
> 
> > If you are using the client that you wrote, then you can make sure that
> > it does that.
> >
> > If you are using a general http client, it is unlikely to do that.
> 
> I am knida new to all this. The apps were written by someone who quit
> and then this was all dropped in my lap.

It might be instructive for you to find out *why* they quit.

If it was related to them being required to implement a design which they
knew can't possibly work, it would be good for you to learn that early.

But that's beside the point, here.

> I thought I was clear on what
> a client and server were in life, in this app it's somewhat screwy.

Probably a good thing you can do for you, is take a pencil and paper
and write down the intended data flow of this application.

Until you are happy that the design is right, you probably can't accept
responsibility for implementing it.

In general, the app is a chain of events. At each point, one client is
making one request of one server.

When you can see the data flow design, it will be clearer to you.

> What is behind port 8000 is nginx routing to some Angular code that
> sends a request out. So the Angular code, although client side, is
> acting like a server in that it is invoked in response to a request.

I don't follow all of those words, but that's ok: I don't have to.

> Then it turns about and acts like a client and sends a request out.
> So, who's the server here? nginx?

Whatever is making the request is the client at this instant; whatever
is receiving the request is the server at this instant.

> There are 2 approved ways to send a request to port 8000. One is from
> an app we wrote that is in C++ and it directly sends the request to
> port 8000. These requests are always previously authenticated and are
> good to go. The second is from a django endpoint listening on 8004. It
> does some authentication and if all is good, redirects to 8000. So
> with both of these cases I want to request to port 8000 to go through.
> 
> Then, of course, there are myriad other ways for a request to get port
> 8000 - from a browser, curl, wget, etc. In all of these cases I want
> the request to be blocked and return a 401.

nginx on port 8000 does not care whether the request came from your C++
app or from my curl command.

All it cares about is what it is configured to do: which is to accept a
http request that includes the "I promise I am authorised" token.

browser, curl, wget, etc, can all include that token, without touching
your django app or your C++ program.

If that is your design, and the authorisation actually matters for
anything, then your design is broken and you need to re-design.

> I was hoping to do this with a custom header, but that appears not to
> work. Can anyone recommend another way to achieve this?

One possibility might be to use auth_request
(http://nginx.org/r/auth_request) within nginx to authorise-and-return
the content in one step (as far as the client is concerned) in nginx.

Another possibility might be to use "X-Accel-Redirect" from the
reverse-proxied authorisation-checker. Again, from the client perspective,
the request with credentials results in the desired response directly.

The current two-step process of one request with credentials which are
checked, returning a "I am authorised" token; followed by another request
with that token which the second server does not authenticate at all;
leads to you being able to use "curl" to pretend to be authorised.

> > Perhaps an alternate design involving reverse-proxying would be valid?
> 
> How would that help me?

As above, nginx could reverse-proxy to the authorisation checker; or
alternatively the django app could reverse-proxy to nginx; and then you
could put in external (firewall?) rules which mean that only your C++
app and your django app can get to nginx on port 8000.

Good luck with it,

	f
-- 
Francis Daly        francis at daoine.org



More information about the nginx mailing list