nginx-shib / nginx-http-shibboleth

Shibboleth auth request module for nginx
https://github.com/nginx-shib/nginx-http-shibboleth/wiki
Other
209 stars 27 forks source link

Is this module compatible with SAML 2 in HTTP POST mode? #16

Closed radix closed 8 years ago

radix commented 8 years ago

Description of Issue/Question

I've been struggling to deploy an nginx/FCGI/Shibboleth SP stack, and I'm wondering if one of my problems is that the IdPs I'm testing with are using HTTP POST for authentication instead of just request parameters. I noticed this caveat in the README:

The one (potentially significant) caveat is that due to the way Nginx operates at present with regards to subrequests (what an Authorizer effectively requires), the request body will not be forwarded to the authorizer, and similarly, the response body from the authorizer will not be returned to the client.

Does this mean the HTTP POST SAML binding is completely ruled out? Am I unable to use the Shibboleth FastCGI authorizer unless I'm using HTTP Redirect or some other binding?

Versions and Systems

nginx-http-shibboleth 2.0.0, nginx 1.6.2, shibboleth SP 2.5.6.

davidjb commented 8 years ago

This should be fine, assuming your SAML2 POST is configured that same as mine, the POST request from the IdP goes to /Shibboleth.sso/SAML2/POST, which is the Shibboleth responder. As it is just a standard FastCGI application, it's fully compatible with all aspects of HTTP once you've made it available through an nginx location block (eg https://github.com/nginx-shib/nginx-http-shibboleth/blob/master/CONFIG.rst#configure-nginx). You can test it directly by making a GET to URLs like /Shibboleth.sso/Login or /Shibboleth.sso/Status (depending on your config).

The Shibboleth authorizer is used to decide what to do with a request (allow, deny, redirect, inject Shib variables etc based on your shibboleth2.xml config) and is enabled when the shib_request directive is placed in a given nginx location block. It's used internally within nginx and the user or IdP never talk to it directly. In the case of example config like so:

location /secure {
    shib_request /shibauthorizer;
    shib_request_use_headers on;
    proxy_pass http://localhost:8080;
}

the user's incoming request to /secure causes a subrequest inside nginx to the location block for /shibauthorizer. The Shib FastCGI authorizer then decides what to do based upon your shibboleth2.xml (eg <RequestMapper>, <ApplicationDefaults>, <Sessions> etc). Because nginx doesn't support forwarding request bodies in subrequests, the body of the original user's won't be forwarded to /shibauthorizer. The FastCGI Authorizer standard requires the subrequest body to be forwarded, which makes this module's implementation fine for Shibboleth but ultimately incompatible with the FastCGI spec (and hence the note).

If you can capture the whole request flow during an auth cycle, that'll help reveal where the problem is occurring. In my prod environment, a POST to /Shibboleth.sso/SAML2/POST produces a response of 302 Found, with the user redirected to the URL they accessed originally. The subsequent GET request to the original URL is allowed (200) and the Shibboleth variables are copied into the request that gets sent to the backend.

radix commented 8 years ago

Thanks very much, @davidjb! Your response exceeds necessity, and is very helpful. I've also discovered that one of the biggest blockers was that I had my RequestMapper misconfigured, and was getting the mysterious auth "successes" which you also very helpfully documented in your Configuration "Gotchas": https://github.com/nginx-shib/nginx-http-shibboleth/blob/master/CONFIG.rst#gotchas

Sorry for the bother and thanks again for your time; I think between your comment and your documentation I should be able to at least get much further :)

davidjb commented 8 years ago

Never a bother @radix! If you've got suggestions on how to improve the docs to make things clearer, we'd appreciate a PR. Shibboleth is a complex beast in itself, so once you mix in its less-than-documented FastCGI applications that never log anything it's tough.

This module is very verbose on what it does when nginx is build with debugging support, so that might help you out too.

Ah yes, fond memories of the mysterious auth successes. I lost a lot of time on that one.

pgchamberlin commented 7 years ago

@davidjb I hope you don't mind a drive-by question tacked on here, but I'm wondering if the module support SP-initiated POST binding. Is that precluded by the issues around response bodies in Nginx/FastCGI?

davidjb commented 7 years ago

@pgchamberlin It comes down to what is generating the response body, eg with the form in it that generates the POST. My services all use redirections to WAYF (so the flow is request -> nginx -> shibauthorizer (matches URL/path) -> returns 302 redirect with WAYF URL -> select IdP -> Login at IdP -> POST back to /Shibboleth.sso/SAML2/POST -> redirect to application) -- the bit in bold is where a response body won't make it back to the client (eg generated by the shibauthorizer). In my case, because shibauthorizer is generating a redirect (via headers), I'm okay -- in your case, if that's what's generating the POST binding, it won't work.

I haven't implemented this sort of thing before, so I'd recommend you test it out and report back; feel free to open a PR with your findings and add info to the README.md.