Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modular user AuthN, support for SAML #52

Merged
merged 13 commits into from
May 2, 2016
Merged

Modular user AuthN, support for SAML #52

merged 13 commits into from
May 2, 2016

Conversation

ab
Copy link
Contributor

@ab ab commented Mar 23, 2016

@ryan-lane This is definitely a work in progress, opening a PR to get feedback on the approach here before I do too much more. I used the 1.1 branch as the base since there was a bunch of refactoring; I hope that was a good thing to do.

Summary of changes:

  • Add a dependency on python-saml for SAML support.
  • Add an ABC AbstractUserAuthenticator that different user authentication modules can inherit from. These classes must implement log_in() and auth_type(), and may implement log_out() or other custom functionality.
  • The auth module in use is configured by USER_AUTH_MODULE in settings.
  • Convert the existing authentication modules into NullUserAuthenticator (for USE_AUTH=false) and GoogleOauthAuthenticator, which is mostly copy pasted from the existing code.
  • Add a new authentication module SamlAuthenticator, which implements support for SAML. This also requires some custom routes for the callback handlers, which are all namespaced under /v1/saml/.
  • Add rudimentary support for /logout, which either performs a SAML SingleLogOut flow or just clears the session. The goodbye.html is just a stub that I blindly cargo culted from index.html.

Testing:

  • I haven't written any automated tests yet, and I'm sure this breaks the existing tests, but I haven't yet been able to run them.
  • I've manually tested all three auth modules (Null, Google OAuth, and SAML), and they all seem to work!
  • I'm hoping to have time to write documentation howtos on getting each of OAuth and SAML integrated with Google as the identity provider. They're both finicky, but pretty straightforward if you know how to do it.

ab added 10 commits March 19, 2016 11:28
Be sure to delete authnz.pyc for local development, or you'll see wacko
results going forward. :-)
Use a much more modular approach to user authentication. This will help
deliver support for multiple different mechanisms. (Oauth, SAML, etc.)
I don't think any of these were deliberately executable.
- Flesh out SAML authentication module with SingleSignOn and
  SingleLogOut support.
- Add various settings needed for SAML configuration.
- Add rudimentary log out support, with logout link and goodbye page.
- Don't explode if XSRF tokens aren't found.
- Be more accepting of different first_name/last_name SAML attributes.
- Always clear the session immediately when initiating SingleLogOut.
- Remove whitespace from base64-encoded certs/keys.
- Fix SAML_SP_CERT typo.
@@ -96,8 +74,8 @@ def check_csrf_token():
# csrf tokens.
if g.auth_type == 'kms':
return True
token = request.headers.get('X-XSRF-TOKEN')
return safe_str_cmp(token, session.get('XSRF-TOKEN'))
token = request.headers.get('X-XSRF-TOKEN', '')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should check to see if token is None and return False here if so.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good catch.

@ryan-lane ryan-lane mentioned this pull request Mar 25, 2016

# ideally we would call check_csrf_token, but I don't think logout CSRF
# is a serious concern for this application
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Not worried about mass logouts here :)

@ryan-lane
Copy link
Contributor

Mostly just style and nitpicks in my comments. I think the general approach is great!

@pnathan
Copy link

pnathan commented Apr 19, 2016

@ryan-lane is this PR planned to be in 1.1?

@ryan-lane
Copy link
Contributor

@pnathan yep! going to merge it in whenever @ab is ready

@pnathan
Copy link

pnathan commented Apr 20, 2016

👍

On Tue, Apr 19, 2016 at 5:00 PM, Ryan Lane notifications@github.com wrote:

@pnathan https://github.com/pnathan yep! going to merge it in whenever
@ab https://github.com/ab is ready


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
#52 (comment)

@ryan-lane ryan-lane merged commit 8273b8b into lyft:1.1 May 2, 2016
@ryan-lane
Copy link
Contributor

Awesome work @ab. Thanks again for this!

since any page with @authnz.require_auth will redirect to login.
"""
return flask.redirect(
authnz.user_mod.login_redirect_url(return_to='/v1/saml/debug'))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redirect from login to /debug?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's a little weird to leave that in there, since I was using it for debugging the IdP integration. But the reason this endpoint exists is for debugging SAML. You never hit this page unless you type this URL explicitly. When tracing the HTTP requests it's nice to have separate start and end pages — a bit confusing to start and end at the same page the way the @require_auth wrapped endpoints do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants