README.md in rails-auth-0.1.0 vs README.md in rails-auth-0.2.0

- old
+ new

@@ -19,10 +19,101 @@ Rails::Auth can be used to authenticate and authorize end users using browser cookies, service-to-service requests using X.509 client certificates, or any other clients with credentials that have proper authenticating middleware. +## Architecture + +Rails::Auth makes use of multiple, independent, single-purpose middleware +classes to handle specific types of AuthN/AuthZ. + +### AuthN + +Rails::Auth ships with the following AuthN middleware: + +* `Rails::Auth::X509::Middleware`: authenticates X.509 certificates obtained + from the Rack environment. + +The goal of Rails::Auth's AuthN middleware is to authenticate *credentials* +taken from the Rack environment and place objects representing them under +the `"rails-auth.credentials"` key within the Rack environment for use by +subsequent AuthN or AuthZ middleware. The built-in support is for X.509 +client certificates, but other middleware could handle authentication of +cookies or (OAuth) bearer credentials. + +The intended usage is to have multiple AuthN middlewares that are capable +of extracting different types of credentials, but also allowing AuthZ +middleware to apply a single policy to all of them. It's also possible to +chain AuthN middleware together such that one credential obtained earlier +in the middleware stack is used to authenticate another (for e.g. +[channel-bound cookies]). + +[channel-bound cookies]: http://www.browserauth.net/channel-bound-cookies + +### AuthZ + +Rails::Auth ships with one primary AuthZ middleware: + +* `Rails::Auth::ACL::Middleware`: support for Access Control Lists. + +Access Control Lists (ACLs) let you write a single, declarative policy for +authorization in your application. ACLs are pluggable and let you write +a single policy which can authorize access using different types of +credentials. + +ACLs are a declarative approach to authorization, consolidating policies +into a single file that can be easily audited by a security team without +deep understanding of the many eccentricities of Rails. These policies +provide coarse-grained authorization based on routes (as matched by +regexes) and the credentials extracted by the AuthN middleware. However, +the do not provide AuthZ which includes specific domain objects, or +policies around them. + +## Comparison to other Rails/Rack auth libraries/frameworks + +Below is a comparison of how Rails::Auth relates to the existing landscape +of Rails AuthN and AuthZ libraries. These are grouped into two different +categories: libraries Rails::Auth replaces, and libraries with which +Rails::Auth can be used in a complimentary fashion. + +### Replaces: + +* [Warden]: Uses a single "opinionated" Rack middleware providing + user-centric authentication and methods that allow controllers + to imperatively interrogate the authentication context for + authorization purposes. By comparison Rails::Auth is not prescriptive + and much more flexible about credential types (supporting credentials + for both user and service clients) and uses declarative authorization + policies in the form of ACLs. + +* [Devise]: A mature, flexible, expansive framework primarily intended + for user authentication. Some of the same caveats as Warden apply, + however Devise provides a framework for modeling users within a Rails + app along with common authentication flows, making it somewhat + orthogonal to what Rails::Auth provides. Rails::Auth is designed to + easily support [claims-based identity] systems where user identity + is outsourced to a separate microservice. + +### Compliments: + +* [Pundit]: Domain object-centric fine-grained authorization using clean + object-oriented APIs. Pundit makes authorization decisions around particular + objects based on policy objects and contexts. Rails::Auth's credentials + can be used as a powerful policy context for Pundit. + +* [CanCanCan]: a continuation of the popular CanCan AuthZ library after a + period of neglect. Uses a more DSL-like approach to AuthZ than Pundit, + but provides many facilities similar to Pundit for domain object-centric + AuthZ. + +[Warden]: https://github.com/hassox/warden/wiki +[Devise]: https://github.com/plataformatec/devise +[Pundit]: https://github.com/elabs/pundit +[CanCanCan]: https://github.com/CanCanCommunity/cancancan + +[claims-based identity]: https://en.wikipedia.org/wiki/Claims-based_identity + ## Installation Add this line to your application's Gemfile: ```ruby @@ -49,16 +140,41 @@ * **AuthZ**: `Rails::Auth::ACL::Middleware`: support for authorizing requests using Access Control Lists (ACLs). Documentation of these middleware and how to use them is provided below. + +### Controller Methods + +Rails::Auth includes a module of helper methods you can use from Rails +controllers. Include them like so: + +```ruby +class ApplicationController < ActionController::Base + include Rails::Auth::ControllerMethods + + def x509_certificate_ou + credentials[:x509].try(:ou) + end + + def current_username + # Note: Rails::Auth doesn't provide a middleware to extract this, it's + # just an example of how you could use it with your own claims-based + # identity system. + credentials[:identity_claims].try(:username) + end +end +``` + +This defines the following methods: + +* `#credentials`: obtain a HashWithIndifferentAccess containing all of the + credentials that Rails::Auth has extracted using its AuthN middleware. + ### Access Control Lists (ACLs) ACLs are the main tool Rails::Auth provides for AuthZ. ACLs use a set of route-by-route matchers to control access to particular resources. -Unlike some Rails AuthZ frameworks, this gem grants/denies access to -controller actions, rather than helping you provide different content to -different roles or varying the parameters allowed in, say, an update action. Rails::Auth encourages the use of YAML files for storing ACL definitions, although the use of YAML is not mandatory and the corresponding object structure output from `YAML.load` can be passed in instead. The following is an example of an ACL definition in YAML: