Skip to content
This repository

A flexible security framework for Rack (and Rails) apps. Good for integration with legacy systems, CAS SSO (including proxying), machine and interactive authentication, and much more.

Fix issue reference for changelog. #31.

latest commit ff43606a88
David Yip authored September 16, 2013
Octocat-spinner-32 assets Move assets to be in-line with previous rename from Aker::Modes::Form… July 19, 2011
Octocat-spinner-32 examples Rename the "aker" rack environment variable to "aker.check". July 17, 2011
Octocat-spinner-32 features Add CAS server startup to CI test script. September 16, 2013
Octocat-spinner-32 lib Return a correct content-type for form mode responses. February 11, 2013
Octocat-spinner-32 spec Address RSpec deprecation warnings. August 22, 2013
Octocat-spinner-32 tool-patches Monkey patch rcov encoding bug that showed up in 1.9.1 after switchin… September 12, 2010
Octocat-spinner-32 .autotest Autotest support. February 11, 2011
Octocat-spinner-32 .gitignore Remove rake tasks and other infrastructure that are not necessary for… July 17, 2011
Octocat-spinner-32 .rspec Autotest support. February 11, 2011
Octocat-spinner-32 .rvmrc Bulk rename Bcsec -> Aker. July 17, 2011
Octocat-spinner-32 .yardopts Rename static documentation files so that GitHub will detect them as … July 17, 2011
Octocat-spinner-32 CHANGELOG.md Fix issue reference for changelog. #31. September 16, 2013
Octocat-spinner-32 Gemfile Add CAS server startup to CI test script. September 16, 2013
Octocat-spinner-32 LICENSE Added missing LICENSE. Closes #9. August 23, 2011
Octocat-spinner-32 README.md Add note and link to rubydoc.info. July 18, 2011
Octocat-spinner-32 Rakefile JRuby-compatible spawn options. September 16, 2013
Octocat-spinner-32 aker.gemspec Extend #valid_credentials! with more user-setup options. #25. December 03, 2012
Octocat-spinner-32 ci-exec.sh Add CAS server startup to CI test script. September 16, 2013
Octocat-spinner-32 ci_local_url Use URLs for configuring all test servers. September 11, 2013
Octocat-spinner-32 cucumber.yml Add a mechanism for skipping integrated tests on a per-platform basis… April 28, 2010
Octocat-spinner-32 gen_local_url Use URLs for configuring all test servers. September 11, 2013
Octocat-spinner-32 init.rakefile Remove rake tasks and other infrastructure that are not necessary for… July 17, 2011
README.md

Aker

Aker is a library for managing authentication and authorization in ruby applications (particularly Rack applications). It is designed to extensibly work with your existing (possibly legacy) authentication infrastructure.

Aker is made up of authorities which provide user security information, modes which integrate authentication with HTTP (via Rack), and a configuration which specifies which of these to use and how to set them up.

Reader's note: this README uses YARD markup to provide links to Aker's API documentation. If you aren't already, consider reading it on rubydoc.info so that the links will be followable.

Aker concepts

Authorities

An authority in Aker is the encapsulation of a mechanism for providing authentication and/or authorization. The methods which an authority may implement (all are optional) are described in detail in the documentation for the {Aker::Authorities::Composite composite authority}. All the included authorities are described in the documentation for the {Aker::Authorities} module. See their documentation for more information.

More than one authority can be used in a particular configuration. When validating credentials or performing any of the other actions provided by the authority interface, all the authorities will be consulted. The documentation for the composite authority describes how the results are aggregated for each action.

Modes

An Aker mode is a mechanism for receiving credentials in the context of a web application. Aker modes come in variants that are intended for use in human-user-facing contexts (UI modes) and machine-facing contexts (API modes). It is possible for the same mode to act in both capacities.

An application may have zero-to-many API modes, but only one UI mode. API modes work within a standard RFC2617 HTTP Authorization interface, while UI modes have broad access to the Rack environment to prompt the user as necessary.

All the included modes are described in the documentation of the {Aker::Modes} module. See their documentation for more information. If you would like to implement your own mode, see {Aker::Modes::Base}.

API vs. UI

Aker uses the following heuristic to determine whether to attempt to authenticate a particular request using the configured UI mode or API mode(s):

  • If there are no API modes configured, requests are always handled by the UI mode.
  • If the HTTP Accept header includes text/html (literally includes it, not matches it), the request is handled by the UI mode.
  • If the HTTP User-Agent header includes Mozilla, the request is handled by the UI mode.
  • Otherwise, the request is handled by the API mode(s).

Configuration

The aker configuration is where you define the authorities and modes (and their parameters) for your application. It's a class whose instances can be initialized both {Aker::Configuration traditionally} and using a {Aker::ConfiguratorLanguage DSL}. There's a global instance ({Aker.configuration}) which will be sufficient for most uses and which can be updated using the DSL via {Aker.configure}.

Since {Aker.configure} updates the configuration (rather than replacing it), it is worthwhile to consider splitting up your configuration into environment-specific and common parts. For instance, you might have the common configuration:

Aker.configure {
  ui_mode :form
  api_mode :http_basic
}

And then for your development environment use:

Aker.configure {
  authority Aker::Authorities::Static.from_file("#{Rails.root}/environments/development-users.yml")
  central "/etc/nubic/aker-local.yml"
}

And in your tests use:

Aker.configure {
  authority Aker::Authorities::Static.from_file("#{Rails.root}/spec/test-users.yml")
}

But then in production use:

Aker.configure {
  authorities :ldap
  central "/etc/nubic/aker-prod.yml"
}

Using form authentication

Aker's {Aker::Form::Mode :form} mode provides a traditional HTML form for user authentication. It works with one or more authorities which handle the :user credential kind — compatible authorities that ship with Aker are {Aker::Ldap::Authority :ldap}, and {Aker::Authorities::Static :static}.

:form is the default UI mode. If you want to explicitly configure it, do like so:

Aker.configure {
  authorities :static # whatever is appropriate for your app
  ui_mode :form
}

Using CAS

Aker's {Aker::Cas::ServiceMode :cas} mode provides interactive user authentication via an external CAS 2 server. The {Aker::Cas::ProxyMode :cas_proxy} mode complements :cas by providing non-interactive authentication using CAS proxy tickets. Each of these modes works with an authority which can handle the corresponding credential kind (i.e., :cas needs a :cas-handling authority). The {Aker::Cas::Authority :cas} authority handles both. Here's an example configuration:

Aker.configure {
  authority :cas
  ui_mode :cas
  api_mode :cas_proxy # don't include unless needed
}

(The :static authority can also verify :cas and :cas_proxy credentials, but it is relatively awkward to set up and so is left as an exercise for the adventurous integrated tester.)

Since the CAS server provides authentication only, you may also want to configure an authority to provide authorization information.

Authenticating a RESTful API

As noted above, Aker has specific support for RFC2617-style standard HTTP authentication. It supports multiple simultaneous API authentication modes. The most common case for multiple API modes will be CAS-protected APIs which also need to provide non-interactive API access (e.g., for cron jobs, since they are not run in the context of a user logged into any particular application). Here's a sample configuration:

Aker.configure {
  ui_mode :cas
  api_mode :http_basic, :cas_proxy

  authorities :cas, :ldap

  central "/etc/nubic/aker-local.yml"
}

In this case, the CAS server will be used for interactive logins and for CAS proxy ticket validation, while HTTP Basic-authenticated requests will be validated using the :ldap authority.

Rack (and Rails) integration

Aker's web application integration is based on Rack. This means it can be used with nearly any ruby web framework, including Sinatra, Camping, etc., in addition to Rails.

In your Aker-protected Rack application, you have access to a "aker.check" key in the Rack environment. This key will yield an instance of {Aker::Rack::Facade} which provides methods for determining who is logged in, checking permissions, requiring authentication, etc. See its API documentation for more information.

To configure Aker into your Rack application, use {Aker::Rack.use_in}. See that method's API documentation for more information.

Rails

While Rack support is built into the main Aker gem, Rails support (for both Rails 2.3 and 3.x) is in a separate gem plugin. See the README in the aker-rails gem for more information about it.

Aker outside of a Rack app

Aker's authorities are independent of its HTTP integration, so they may be used in any ruby script or application. Here's an example:

#!/usr/bin/env ruby

require 'rubygems'
require 'aker'

Aker.configure {
  authorities :ldap, :static
  central "/etc/nubic/aker-staging.yml"
}

u = Aker.authority.valid_credentials?(:user, 'wakibbe', 'ekibder')
    # => valid_credentials? returns a Aker::User on success

if !u
  $stderr.puts "Bad credentials"
  exit(1)
elsif u.permit?('Admin')
  lookedup = Aker.authority.find_user(ARGV[0])
  if lookedup
    puts "#{ARGV[0]} is the username of #{lookedup.full_name}"
  else
    puts "#{ARGV[0]} isn't a valid username"
  end
else
  $stderr.puts "Unauthorized"
  exit(2)
end

See the rest of the API documentation for more information.

Extending Aker

Aker was built for extensibility. Here are the highlights; see the relevant sections above for more.

  • {Aker::Authorities::Composite#valid_credentials? Authentication} and {Aker::Authorities::Composite#amplify! authorization} can be provided by implementing an {Aker::Authorities authority}. An application can configure in multiple authorities and their results will be intelligently combined. Authorities can also implement {Aker::Authorities::Composite#on_authentication_success success} and {Aker::Authorities::Composite#on_authentication_failure failure} callbacks to provide for auditing or {Aker::Authorities::Composite#veto? lockout} features.
  • An HTTP-based credential presentation mechanism can be implemented as a {Aker::Modes mode}. E.g., you would write a mode to adapt to a legacy single-sign-on system.
  • Authorities and modes can be customized through {Aker::Configuration#parameters_for parameters} included in the {Aker::Configuration configuration}.
  • Reusable extensions can be packaged as gems and registered alongside Aker's built-in functionality. Extensions may use {Aker::Configuration::Slice slices} to register themselves, set defaults parameter values, and register middleware that will be included relative to Aker's own middleware.

Limitations

Aker's original iteration was a rails plugin built to assist the Northwestern University Biomedical Informatics Center in transitioning legacy systems to Ruby on Rails. Since then it's been used in dozens of applications, both ports of existing systems and ones newly built.

While it can be adapted to many kinds of applications, it is probably not a good choice if you are not integrating with an existing authentication or authorization backend. It does not include any mechanism for provisioning users or letting users sign up for accounts on their own. Such things could be built for it, but if that's what you need then one of the other existing ruby security frameworks might get you up and running faster.

Something went wrong with that request. Please try again.