mesosphere/chaos — pull request #15 by benmccann (2014-09-06 03:43:36+00:00)
Title: Implement auth support

** Getting the Conversation Going **

I wanted to talk about how we might add support for additional authentication and authorization methods to Marathon. This is a change to a core part of the system and relies on some code that might be new to many folks here, so please don't hesitate to ask me for clarification about this proposal.

** What this Gives Us **

This pull request adds a framework for supporting additional authentication types (besides just basic authentication) and for supporting for authorization of resources. This means we'll be able to support people logging in via BasicAuth, DB, LDAP, OAuth, SAML, etc. We can also annotate resources as requiring a certain permission or role. And we can know who the logged in user is to log which user takes certain actions or to show who the logged in user is at the top of the webapp.

** Implementation **

I implemented this using Shiro. I chose Shiro because it gives us the ability to make this functionality very customizable. You can get pretty far just changing options in the shiro.ini. You could also drop in your own jar to further customize (though this already supports most authentication methods). The two main auth frameworks I could find were Shiro and Spring Auth. Spring Auth seemed extremely difficult to implement given that we're not using Spring Dependency Injection (Marathon and Chronos both use a bit of Guice). Shiro was a little tricky to figure out in a few places, but it has great support for a number of things we'd want to do like supporting multiple login methods out of the box and allowing us to use annotations like `@RequiresAuthentication` and `@RequiresPermissions` if we want some urls to be admin-only, read-only, unprotected, etc.

** Example **

I added to the example project a shiro.ini file which reproduces the current behavior of http_credentials.

** Next Steps **

Right now, the way that Marathon / Chronos / Chaos work is to send a basic auth header on every request (e.g. Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==). However, we need a solution that works with LDAP, SAML, etc. Thus, I suggest that we add a login callback which upon successful authentication creates a token, stores it in a cookie (to handle page reloads and futures visits), and then sends it to the server in a customer header (something like "Authorization: Chaos mytoken" or "X-AUTH: mytoken") with each request to the application's REST API. We could create some classes in Chaos to assist with this and an example of it. The auth token would have to be stored in a manner such that it could be accessed by multiple instances of the web server, so we'd probably want to store it in Zookeeper.