11# Ruby SAML [ ![ Build Status] ( https://secure.travis-ci.org/onelogin/ruby-saml.svg )] ( http://travis-ci.org/onelogin/ruby-saml ) [ ![ Coverage Status] ( https://coveralls.io/repos/onelogin/ruby-saml/badge.svg?branch=master )] ( https://coveralls.io/r/onelogin/ruby-saml?branch=master ) [ ![ Gem Version] ( https://badge.fury.io/rb/ruby-saml.svg )] ( http://badge.fury.io/rb/ruby-saml )
22
3+ ## Updating from 1.11.x to 1.12.0
4+ Version ` 1.12.0 ` adds support for gcm algorithm and
5+ change/adds specific error messages for signature validations
6+
37## Updating from 1.10.x to 1.11.0
48Version ` 1.11.0 ` deprecates the use of ` settings.issuer ` in favour of ` settings.sp_entity_id ` .
59There are two new security settings: ` settings.security[:check_idp_cert_expiration] ` and ` settings.security[:check_sp_cert_expiration] ` (both false by default) that check if the IdP or SP X.509 certificate has expired, respectively.
@@ -261,8 +265,8 @@ def saml_settings
261265 settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume"
262266 settings.sp_entity_id = "http://#{request.host}/saml/metadata"
263267 settings.idp_entity_id = "https://app.onelogin.com/saml/metadata/#{OneLoginAppId}"
264- settings.idp_sso_target_url = "https://app.onelogin.com/trust/saml2/http-post/sso/#{OneLoginAppId}"
265- settings.idp_slo_target_url = "https://app.onelogin.com/trust/saml2/http-redirect/slo/#{OneLoginAppId}"
268+ settings.idp_sso_service_url = "https://app.onelogin.com/trust/saml2/http-post/sso/#{OneLoginAppId}"
269+ settings.idp_slo_service_url = "https://app.onelogin.com/trust/saml2/http-redirect/slo/#{OneLoginAppId}"
266270 settings.idp_cert_fingerprint = OneLoginAppCertFingerPrint
267271 settings.idp_cert_fingerprint_algorithm = "http://www.w3.org/2000/09/xmldsig#sha1"
268272 settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
@@ -327,7 +331,7 @@ class SamlController < ApplicationController
327331
328332 settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume"
329333 settings.sp_entity_id = "http://#{request.host}/saml/metadata"
330- settings.idp_sso_target_url = "https://app.onelogin.com/saml/signon/#{OneLoginAppId}"
334+ settings.idp_sso_service_url = "https://app.onelogin.com/saml/signon/#{OneLoginAppId}"
331335 settings.idp_cert_fingerprint = OneLoginAppCertFingerPrint
332336 settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
333337
400404The following attributes are set:
401405 * idp_entity_id
402406 * name_identifier_format
403- * idp_sso_target_url
404- * idp_slo_target_url
407+ * idp_sso_service_url
408+ * idp_slo_service_url
405409 * idp_attribute_names
406410 * idp_cert
407411 * idp_cert_fingerprint
@@ -467,6 +471,9 @@ Imagine this `saml:AttributeStatement`
467471 < saml:AttributeValue xmlns:xs=" http://www.w3.org/2001/XMLSchema" xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance" xsi:nil=" true" />
468472 < saml:AttributeValue xmlns:xs=" http://www.w3.org/2001/XMLSchema" xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance" xsi:nil=" 1" />
469473 < /saml:Attribute>
474+ < saml:Attribute Name=" http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname" >
475+ < saml:AttributeValue> usersName< /saml:AttributeValue>
476+ < /saml:Attribute>
470477 < /saml:AttributeStatement>
471478` ` `
472479
@@ -477,7 +484,8 @@ pp(response.attributes) # is an OneLogin::RubySaml::Attributes object
477484 "another_value"=>["value1", "value2"],
478485 "role"=>["role1", "role2", "role3"],
479486 "attribute_with_nil_value"=>[nil],
480- "attribute_with_nils_and_empty_strings"=>["", "valuePresent", nil, nil]}>
487+ "attribute_with_nils_and_empty_strings"=>["", "valuePresent", nil, nil]
488+ "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"=>["usersName"]}>
481489
482490# Active single_value_compatibility
483491OneLogin::RubySaml::Attributes.single_value_compatibility = true
@@ -494,6 +502,9 @@ pp(response.attributes.single(:role))
494502pp(response.attributes.multi(:role))
495503# => ["role1", "role2", "role3"]
496504
505+ pp(response.attributes.fetch(:role))
506+ # => "role1"
507+
497508pp(response.attributes[:attribute_with_nil_value])
498509# => nil
499510
@@ -509,6 +520,9 @@ pp(response.attributes.single(:not_exists))
509520pp(response.attributes.multi(:not_exists))
510521# => nil
511522
523+ pp(response.attributes.fetch(/givenname/))
524+ # => "usersName"
525+
512526# Deactive single_value_compatibility
513527OneLogin::RubySaml::Attributes.single_value_compatibility = false
514528
@@ -524,6 +538,9 @@ pp(response.attributes.single(:role))
524538pp(response.attributes.multi(:role))
525539# => ["role1", "role2", "role3"]
526540
541+ pp(response.attributes.fetch(:role))
542+ # => ["role1", "role2", "role3"]
543+
527544pp(response.attributes[:attribute_with_nil_value])
528545# => [nil]
529546
@@ -538,6 +555,9 @@ pp(response.attributes.single(:not_exists))
538555
539556pp(response.attributes.multi(:not_exists))
540557# => nil
558+
559+ pp(response.attributes.fetch(/givenname/))
560+ # => ["usersName"]
541561` ` `
542562
543563The ` saml:AuthnContextClassRef` of the AuthNRequest can be provided by ` settings.authn_context` ; possible values are described at [SAMLAuthnCxt]. The comparison method can be set using ` settings.authn_context_comparison` parameter. Possible values include: ' exact' , ' better' , ' maximum' and ' minimum' (default value is ' exact' ).
@@ -623,21 +643,27 @@ def sp_logout_request
623643 # LogoutRequest accepts plain browser requests w/o paramters
624644 settings = saml_settings
625645
626- if settings.idp_slo_target_url .nil?
646+ if settings.idp_slo_service_url .nil?
627647 logger.info " SLO IdP Endpoint not found in settings, executing then a normal logout'"
628648 delete_session
629649 else
630650
631- # Since we created a new SAML request, save the transaction_id
632- # to compare it with the response we get back
633651 logout_request = OneLogin::RubySaml::Logoutrequest.new ()
634- session[:transaction_id] = logout_request.uuid
635- logger.info " New SP SLO for userid '#{session[:userid]}' transactionid '#{session[:transaction_id]}'"
652+ logger.info " New SP SLO for userid '#{session[:userid]}' transactionid '#{logout_request.uuid}'"
636653
637654 if settings.name_identifier_value.nil?
638655 settings.name_identifier_value = session[:userid]
639656 end
640657
658+ # Ensure user is logged out before redirect to IdP, in case anything goes wrong during single logout process (as recommended by saml2int [SDP-SP34])
659+ logged_user = session[:userid]
660+ logger.info " Delete session for '#{session[:userid]}'"
661+ delete_session
662+
663+ # Save the transaction_id to compare it with the response we get back
664+ session[:transaction_id] = logout_request.uuid
665+ session[:logged_out_user] = logged_user
666+
641667 relayState = url_for controller: ' saml' , action: ' index'
642668 redirect_to(logout_request.create(settings, :RelayState => relayState))
643669 end
@@ -665,7 +691,7 @@ def process_logout_response
665691 logger.error " The SAML Logout Response is invalid"
666692 else
667693 # Actually log out this session
668- logger.info " Delete session for '#{session[:userid ]}'"
694+ logger.info " SLO completed for '#{session[:logged_out_user ]}'"
669695 delete_session
670696 end
671697end
674700def delete_session
675701 session[:userid] = nil
676702 session[:attributes] = nil
703+ session[:transaction_id] = nil
704+ session[:logged_out_user] = nil
677705end
678706` ` `
679707
@@ -741,6 +769,14 @@ class SamlController < ApplicationController
741769end
742770` ` `
743771
772+ You can add ValidUntil and CacheDuration to the XML Metadata using instead
773+ ` ` ` ruby
774+ # Valid until => 2 days from now
775+ # Cache duration = 604800s = 1 week
776+ valid_until = Time.now + 172800
777+ cache_duration = 604800
778+ meta.generate(settings, false, valid_until, cache_duration)
779+ ` ` `
744780
745781# # Clock Drift
746782
0 commit comments