# Writing a new auth module - request for comments

**URL:** <https://www.ruby-forum.com/t/writing-a-new-auth-module-request-for-comments/242348>\
**Category:** NGINX\
**Created:** [June 17, 2015, 11:26am UTC](https://www.ruby-forum.com/t/writing-a-new-auth-module-request-for-comments/242348 "2015-06-17T11:26:09Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![musicdenotation](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ea666f/32.png) [@musicdenotation](https://www.ruby-forum.com/u/musicdenotation)\
**Post date:** [June 17, 2015, 11:26am UTC](https://www.ruby-forum.com/t/writing-a-new-auth-module-request-for-comments/242348/1 "2015-06-17T11:26:09Z")

</div>

Hi,

I’m writing a new module (out-of-tree) for supporting authentication  
using Stormpath’s user management API ([https://stormpath.com/](https://stormpath.com/)).

Basically, the module makes one or more HTTP requests to the  
Stormpath API to determine if the client request should be authorized  
to access a location or not.

Since this is somewhat different than other modules I could learn from,  
and  
since all my knowledge about nginx internals is from looking at how  
other  
modules & core is written, I’m wondering if anyone could comment on how  
I  
designed the module and raise any issues if I did anything problematic,  
wrong or weird.

For reference, the work-in-progress code for the module is available  
here: [GitHub - stormpath/stormpath-nginx-module: This is a deprecated module. Please see: https://github.com/stormpath/stormpath-nginx](https://github.com/stormpath/stormpath-nginx-module)

Since I have to contact the external API I’m using the upstream module  
to  
do it. But I don’t want the users (admins) to have to define an upstream  
block in nginx.conf so my module creates and configures an upstrem  
configuration internally instead.

> <https://github.com/stormpath/stormpath-nginx-module/blob/master/src/ngx_http_auth_stormpath_module.c#L864>

I haven’t seen any other module do that, but I don’t see that  
it’s possible to avoid users having to define upstream manually  
otherwise.

For the above reasons (wanting to handle everything invisible to the  
user),  
I’m not using nginx\_http\_proxy\_module, but implement the upstream  
handler  
(create\_request & friends) myself. But since I have to construct a HTTP  
request, parse status line, parse headers, parse body (eg. if it’s  
chunked  
transfer-encoding), I end up duplicating a lot of functionality already  
in http proxy (although greatly simplified because I know exactly how to  
talk to the upstream server and what to expect in return).

One example is I parse the headers manually, because I haven’t found a  
way  
to init the http\_upstream header parser hash, and to reuse the parser  
(originally the init is done in ngx\_http\_upstream\_init\_main\_conf).

> <https://github.com/stormpath/stormpath-nginx-module/blob/master/src/ngx_http_auth_stormpath_module.c#L304>

(I’ll also hit similar problems with caching the requests to the  
upstream.  
I’d like to reuse the caching functionality already in nginx, but it  
seems  
to me like http\_proxy\_module does a lot of manual heavy lifting in that  
regard that I’d have to reimplement (or _shudder_ copy-paste) to  
support it?)

Does the above make sense? Is there an obvious way to do it differently  
that  
I’ve missed? Are there any guides or documentation on how this should be  
done (besides Evan M.'s obsolete-but-useful guides I went through  
already)?

Any comments, suggestions, warnings or flames are welcome.

Thanks,  
Senko

---

<div class="post-metadata">

**Author:** ![Senko\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/3e96dc/32.png) [@Senko\_R](https://www.ruby-forum.com/u/Senko_R)\
**Post date:** [June 17, 2015, 5:30pm UTC](https://www.ruby-forum.com/t/writing-a-new-auth-module-request-for-comments/242348/2 "2015-06-17T17:30:07Z")

</div>

On Wednesday 17 June 2015 11:25:33 Senko R. wrote:

> Hi,
> 
> I’m writing a new module (out-of-tree) for supporting authentication  
> using Stormpath’s user management API ([https://stormpath.com/](https://stormpath.com/)).
> 
> Basically, the module makes one or more HTTP requests to the  
> Stormpath API to determine if the client request should be authorized  
> to access a location or not.

[..]

Have you checked the auth\_request module?

See: [Module ngx\_http\_auth\_request\_module](http://nginx.org/en/docs/http/ngx_http_auth_request_module.html)

wbr, Valentin V. Bartenev

---

<div class="post-metadata">

**Author:** ![Senko\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/3e96dc/32.png) [@Senko\_R](https://www.ruby-forum.com/u/Senko_R)\
**Post date:** [June 18, 2015, 9:42am UTC](https://www.ruby-forum.com/t/writing-a-new-auth-module-request-for-comments/242348/3 "2015-06-18T09:42:46Z")

</div>

Hi,

thanks for your reply Valentin. I have checked auth\_request module, in  
fact  
the module I’m writing started as modifications to auth\_request module.

To clarify, I’m not trying to do one-off setup for my server using the  
Stormpath API. The idea is to provide a module so any Stormpath’s user  
can  
easily integrate the two.

Specifically, the reasons why auth\_request wasn’t enough:

- It requires another location on the local server to be provided (that  
location can be proxied using http\_proxy\_module, but still has to be  
added) to which it’ll make the requests. I wanted to avoid forcing the  
users to need to add another location block and proxy\_pass directives  
to  
the external API (felt like a hack).

- It requires specific semantics regarding the response (200, 401, 403  
are interpreted as usual, everything else is server error).  
Stormpath’s  
API has different semantics so it wouldn’t work anyways.

- You can’t do more than one auth request per client request. In some  
cases, I need two - first to authenticate the client, then to check if  
the user is in a specific group (and to be able to do this, I need to  
parse the response body).

So it looks like auth\_request module would be ideal if the users provide  
a small authorization web service that does whichever auth logic is  
needed,  
and then responds according to auth\_request semantics. If I just wanted  
to  
implement the integration for my (one) specific use-case, I’d likely do  
that.

But the motivation for the module is to avoid forcing users to do these  
one-off auth services, and instead just compile in and use a module that  
provides this.

Best,  
Senko

On Wed, Jun 17, 2015 at 5:29 PM, Valentin V. Bartenev [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> [..]  
> [mailman.nginx.org archive](http://mailman.nginx.org/mailman/listinfo/nginx)  
> –  
> Senko R.

---

<div class="post-metadata">

**Author:** ![Senko\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/3e96dc/32.png) [@Senko\_R](https://www.ruby-forum.com/u/Senko_R)\
**Post date:** [June 18, 2015, 12:33pm UTC](https://www.ruby-forum.com/t/writing-a-new-auth-module-request-for-comments/242348/4 "2015-06-18T12:33:56Z")

</div>

Hi Senko,

I am Andrew H. and am a Developer Advocate for Nginx. Part of my  
job is to help the community writing such modules and aiding  
communication between the community and Nginx’s internal teams.

It is worth noting that at some point in the 1.9.x mainline release we  
will be adding dynamic modules which will let you compile modules  
out-of-tree and load them on starting Nginx. I’ll reply as best I can  
inline.

> On 17 Jun 2015, at 12:25, Senko R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> Hi,
> 
> I’m writing a new module (out-of-tree) for supporting authentication  
> using Stormpath’s user management API ([https://stormpath.com/](https://stormpath.com/)).
> 
> Basically, the module makes one or more HTTP requests to the  
> Stormpath API to determine if the client request should be authorized  
> to access a location or not.

Excellent 🙂

> Since this is somewhat different than other modules I could learn from, and  
> since all my knowledge about nginx internals is from looking at how other  
> modules & core is written, I’m wondering if anyone could comment on how I  
> designed the module and raise any issues if I did anything problematic,  
> wrong or weird.

I have scanned through some of the module so far and there doesn’t  
appear to be anything wrong or weird.

> I haven’t seen any other module do that, but I don’t see that  
> it’s possible to avoid users having to define upstream manually otherwise.

I agree I have not seen anyone else do this so far. That isn’t to say it  
is a bad thing. It is an interesting take on it.

> (originally the init is done in ngx\_http\_upstream\_init\_main\_conf).

> <https://github.com/stormpath/stormpath-nginx-module/blob/master/src/ngx_http_auth_stormpath_module.c#L304>

This appears to be the correct way to do it as far as I can see, but I’m  
happy to defer to the main Nginx developers on this.

> (I’ll also hit similar problems with caching the requests to the upstream.  
> I’d like to reuse the caching functionality already in nginx, but it seems  
> to me like http\_proxy\_module does a lot of manual heavy lifting in that  
> regard that I’d have to reimplement (or _shudder_ copy-paste) to  
> support it?)
> 
> Does the above make sense? Is there an obvious way to do it differently that  
> I’ve missed? Are there any guides or documentation on how this should be  
> done (besides Evan M.'s obsolete-but-useful guides I went through  
> already)?

At the moment there isn’t much beyond Evan M.'s guides and the Nginx  
Wiki. I will be creating more up-to-date documentation as we head  
towards the dynamic modules feature being released.

> Any comments, suggestions, warnings or flames are welcome.

If you have any questions feel free to contact me directly.

## Kind Regards

Andrew H. (LinuxJedi)  
Senior Developer Advocate  
Nginx Inc.
