SamlCamel - (not production ready)
Installation
Add this line to your application's Gemfile:
gem 'saml_camel'
And then execute:
$ bundle
Usage
IMPORTANT: This step enables security features and is required to use the gem!
- in your environments config (
config/development.rbfor example) ensure that you have caching configured as follows
NOTE: use the cache_store most appropriate for your situation. It may make more sense to use a file store, or a redis server
config.action_controller.perform_caching = true
config.cache_store = :memory_store
- run
rake saml_camel:generate_samlto generate metadata files for each environment. you can also specify a custom environment like thisrake saml_camel:generate_saml environment=acceptance
Note: these steps will use development as an example, if you use separate metadata per environment, you will repeat each step for your chosen environment
from the root of your app open
saml/development/settings.jsonand specify an entity ID of your choice. this is a unique identifier used by the Identity Provider(idp) to recognize your app. Typically it should take the form of a url, however note that it is just an identifier and does not have to resolve (e.g. https://my-app-name/not/a/real/route)Go to https://authentication.oit.duke.edu/manager/register/sp and register your metadata with the identity provider. You will need the values from
saml/development/settings.jsonin addition to thesaml/development/saml_certificate.crt
- copy the entity_id you chose in the
settings.jsonfile and paste it into the "Entity Field" - fill out functional purpose, responsible dept, function owner dept, and audience with information relevant to your application
- copy the cert from
saml/development/saml_certificate.crtand paste it into the Certificate Field - copy the acs value and paste it into the Location field in the Assertion Consumer Service box
- note that the default host value for ACS is
http://locahost:3000which is the defaultrails shost. If you're using a differnet host (such as in production or using docker) you will want to replace the host value with what is relevent for your situation(e.g. https://my-app.duke.edu/saml/consumeSaml), but keep the path/saml/consumeSaml
- note that the default host value for ACS is
In your app mount the engine in config/routes.rb
mount SamlCamel::Engine, at: "/saml"now simply provide the
saml_protectmethod in your controllers (viabefore_action) to protect pathsclass DashboardController < ApplicationController before_action :saml_protect, except: [:home] def home end def index end endto logout simply make a post to
localhost:3000/saml/logout. This will kill the local saml session, and the session with the identity provider.response attributes found in
session[:saml_attributes]note that the session can not store over the 4 kilobyte limit. Keep this in mind in the use case of requesting a significant amount of attributesIt is recommended to set
config.force_ssl = truein theconfig/environments/production.rbfile for securityLogging is turned on by default. Logging is configured in
saml/development/settings.json. To utilize logging saml_logging should be set to true (default), and primary_id must have a value. primary_id is the saml attribute you consider to be a primary identifier for a userUsers can go to http://localhost:3000/saml/attributes to view attributes being passed through
Example settings.json
{
"_comment": "note you will need to restart the application when you make changes to this file",
"settings": {
"acs": "http://localhost:3000/saml/consumeSaml",
"entity_id": "http://my-entity-id.corgi",
"sso_url": "https://shib.oit.duke.edu/idp/profile/SAML2/Redirect/SSO",
"logout_return_url": "http://localhost:3000",
"primary_id": "eduPersonPrincipalName",
"saml_logging": true
},
"attribute_map": {
"urn:oid:1.3.6.1.4.1.5923.1.1.1.9": "eduPersonScopedAffiliation",
"urn:oid:1.3.6.1.4.1.5923.1.1.1.6": "eduPersonPrincipalName",
"urn:oid:2.5.4.3": "cn",
"urn:oid:0.9.2342.19200300.100.1.1": "uid",
"urn:oid:0.9.2342.19200300.100.1.3": "mail",
"urn:oid:1.3.6.1.4.1.5923.1.1.1.5": "eduPersonPrimaryAffiliation",
"urn:oid:2.16.840.1.113730.3.1.241": "displayName",
"urn:mace:duke.edu:idms:unique-id": "duDukeID",
"urn:mace:duke.edu:idms:dku-id": "dku-id",
"urn:oid:1.3.6.1.4.1.5923.1.5.1.1": "isMemberOf",
"urn:oid:2.5.4.42": "givenName",
"urn:oid:2.5.4.4": "sn",
"urn:oid:2.5.4.11": "ou",
"urn:oid:1.3.6.1.4.1.5923.1.1.1.1": "eduPersonAffiliation",
"urn:oid:2.5.4.20": "telephoneNumber",
"urn:oid:2.5.4.12": "title",
"urn:mace:duke.edu:idms:middle-name1": "duMiddleName1",
"urn:mace:duke.edu:idms:proxy-token": "duProxyToken"
}
}
License
The gem is available as open source under the terms of the MIT License.