pax_global_header00006660000000000000000000000064130017104560014507gustar00rootroot0000000000000052 comment=c946c0a27c9d8016be6d8350c04a17798ceff92b omniauth-saml-1.7.0/000077500000000000000000000000001300171045600142725ustar00rootroot00000000000000omniauth-saml-1.7.0/.gitignore000066400000000000000000000001351300171045600162610ustar00rootroot00000000000000Gemfile.lock coverage/ spec/support/example_private_key.pem /gemfiles/*.lock .idea/ .bundle/ omniauth-saml-1.7.0/.rspec000066400000000000000000000000101300171045600153760ustar00rootroot00000000000000--color omniauth-saml-1.7.0/.travis.yml000066400000000000000000000012641300171045600164060ustar00rootroot00000000000000env: global: - JRUBY_OPTS="$JRUBY_OPTS --debug" sudo: false language: ruby cache: bundler before_install: - gem update bundler before_script: - bundle update script: - bundle exec rspec rvm: - 1.9.3 - jruby-19mode - 2.0.0 - 2.1.10 - 2.2.2 - 2.3.1 - jruby-9.0.5.0 - ruby-head gemfile: - gemfiles/rack_1.gemfile - gemfiles/rack_2.gemfile matrix: allow_failures: - rvm: ruby-head fast_finish: true exclude: - rvm: 1.9.3 gemfile: gemfiles/rack_2.gemfile - rvm: jruby-19mode gemfile: gemfiles/rack_2.gemfile - rvm: 2.0.0 gemfile: gemfiles/rack_2.gemfile - rvm: 2.1.10 gemfile: gemfiles/rack_2.gemfile omniauth-saml-1.7.0/Appraisals000066400000000000000000000002011300171045600163050ustar00rootroot00000000000000appraise 'rack-1' do gem 'rack', '~> 1.x' gem 'term-ansicolor', '1.3.2' end appraise 'rack-2' do gem 'rack', '~> 2.x' end omniauth-saml-1.7.0/CHANGELOG.md000066400000000000000000000054751300171045600161160ustar00rootroot00000000000000 ### v1.7.0 (2016-09-18) #### Features * Support for Single Logout ([cd3fc43](/../../commit/cd3fc43)) * Add issuer information to the metadata endpoint, to allow IdPs to properly configure themselves. ([7bbbb67](/../../commit/7bbbb67)) * Added the response object to the extra['response_object'], so we can use the raw response object if we want to. ([76ed3d6](/../../commit/76ed3d6)) #### Chores * Update `ruby-saml` to 1.4.0 to address security fixes. ([638212](/../../commit/638212)) ### v1.6.0 (2016-06-27) * Ensure that subclasses of `OmniAuth::Stategies::SAML` are registered with OmniAuth as strategies (https://github.com/omniauth/omniauth-saml/pull/95) * Update ruby-saml to 1.3 to address [CVE-2016-5697](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5697) (Signature wrapping attacks) ### v1.5.0 (2016-02-25) * Initialize OneLogin::RubySaml::Response instance with settings * Adding "settings" to Response Class at initialization to handle signing verification * Support custom attributes * change URL from PracticallyGreen to omniauth * Add specs for ACS fallback URL behavior * Call validation earlier to get real error instead of 'response missing name_id' * Avoid mutation of the options hash during requests and callbacks ### v1.4.2 (2016-02-09) * update ruby-saml to 1.1 ### v1.4.1 (2015-08-09) * Configurable attribute_consuming_service ### v1.4.0 (2015-07-23) * update ruby-saml to 1.0.0 ### v1.3.1 (2015-02-26) * Added missing fingerprint key check * Expose fingerprint on the auth_hash ### v1.3.0 (2015-01-23) * add `idp_cert_fingerprint_validator` option ### v1.2.0 (2014-03-19) * provide SP metadata at `/auth/saml/metadata` ### v1.1.0 (2013-11-07) * no longer set a default `name_identifier_format` * pass strategy options to the underlying ruby-saml library * fallback to omniauth callback url if `assertion_consumer_service_url` is not set * add `idp_sso_target_url_runtime_params` option ### v1.0.0 (2012-11-12) * remove SAML code and port to ruby-saml gem * fix incompatibility with OmniAuth 1.1 ### v0.9.2 (2012-03-30) * validate the SAML response * 100% test coverage * now requires ruby 1.9.2+ ### v0.9.1 (2012-02-23) * return first and last name in the info hash * no longer use LDAP OIDs for name and email selection * return SAML attributes as the omniauth raw_info hash ### v0.9.0 (2012-02-14) * initial release * extracts commits from omniauth 0-3-stable branch * port to omniauth 1.0 strategy format * update README with more documentation and license * package as the `omniauth-saml` gem omniauth-saml-1.7.0/CONTRIBUTING.md000066400000000000000000000051321300171045600165240ustar00rootroot00000000000000# Contributing ## Workflow We are using the [Feature Branch Workflow (also known as GitHub Flow)](https://guides.github.com/introduction/flow/), and prefer delivery as pull requests. Our first line of defense is the [Travis CI](https://travis-ci.org/omniauth/omniauth-saml) build defined within [.travis.yml](.travis.yml) and triggered for every pull request. Create a feature branch: ```sh git checkout -B feat/contributing ``` ## Git Commit The cardinal rule for creating good commits is to ensure there is only one "logical change" per commit. Why is this an important rule? * The smaller the amount of code being changed, the quicker & easier it is to review & identify potential flaws. * If a change is found to be flawed later, it may be necessary to revert the broken commit. This is much easier to do if there are not other unrelated code changes entangled with the original commit. * When troubleshooting problems using Git's bisect capability, small well defined changes will aid in isolating exactly where the code problem was introduced. * When browsing history using Git annotate/blame, small well defined changes also aid in isolating exactly where & why a piece of code came from. Things to avoid when creating commits * Mixing whitespace changes with functional code changes. * Mixing two unrelated functional changes. * Sending large new features in a single giant commit. ## Git Commit Conventions We use git commit as per [Conventional Changelog](https://github.com/ajoslin/conventional-changelog): ```none (): ``` Allowed types: * **feat**: A new feature * **fix**: A bug fix * **docs**: Documentation only changes * **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, newline, line endings, etc) * **refactor**: A code change that neither fixes a bug or adds a feature * **perf**: A code change that improves performance * **test**: Adding missing tests * **chore**: Changes to the build process or auxiliary tools and libraries such as documentation generation You can add additional details after a new line to describe the change in detail or automatically close a issue on Github. ```none feat: create initial CONTRIBUTING.md This closes #73 ``` ## Release process Example for version `v1.7.0` 1. Bump the version in `lib/omniauth-saml/version.rb` 1. Update [CHANGELOG.md](CHANGELOG.md) with `bundle exec conventional-changelog version=v1.7.0 since_version=v1.6.0` 1. Commit all your changes 1. Tag the latest commit with `git tag v1.7.0` 1. Contact the maintainers omniauth-saml-1.7.0/Gemfile000066400000000000000000000004351300171045600155670ustar00rootroot00000000000000source 'https://rubygems.org' group :test do gem 'coveralls', '~> 0.8', '>= 0.8.13', require: false # Lock coveralls dependencies to lower versions to work with older rubies gem 'json', '~> 1.8' gem 'tins', '~> 1.6.0' gem 'mime-types', '< 3' end gem 'appraisal' gemspec omniauth-saml-1.7.0/LICENSE.md000066400000000000000000000023021300171045600156730ustar00rootroot00000000000000# License Copyright © 2016 Omniauth-SAML maintainers Copyright © 2011-2014 [Practically Green, Inc.](http://www.practicallygreen.com/). All rights reserved. Released under the MIT license. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. omniauth-saml-1.7.0/README.md000066400000000000000000000212311300171045600155500ustar00rootroot00000000000000# OmniAuth SAML [![Gem Version](http://img.shields.io/gem/v/omniauth-saml.svg)][gem] [![Build Status](http://img.shields.io/travis/omniauth/omniauth-saml.svg)][travis] [![Dependency Status](http://img.shields.io/gemnasium/omniauth/omniauth-saml.svg)][gemnasium] [![Code Climate](http://img.shields.io/codeclimate/github/omniauth/omniauth-saml.svg)][codeclimate] [![Coverage Status](http://img.shields.io/coveralls/omniauth/omniauth-saml.svg)][coveralls] [gem]: https://rubygems.org/gems/omniauth-saml [travis]: http://travis-ci.org/omniauth/omniauth-saml [gemnasium]: https://gemnasium.com/omniauth/omniauth-saml [codeclimate]: https://codeclimate.com/github/omniauth/omniauth-saml [coveralls]: https://coveralls.io/r/omniauth/omniauth-saml A generic SAML strategy for OmniAuth available under the [MIT License](LICENSE.md) https://github.com/omniauth/omniauth-saml ## Requirements * [OmniAuth](http://www.omniauth.org/) 1.3+ * Ruby 1.9.x or Ruby 2.1.x+ ## Versioning We tag and release gems according to the [Semantic Versioning](http://semver.org/) principle. ## Usage Use the SAML strategy as a middleware in your application: ```ruby require 'omniauth' use OmniAuth::Strategies::SAML, :assertion_consumer_service_url => "consumer_service_url", :issuer => "issuer", :idp_sso_target_url => "idp_sso_target_url", :idp_sso_target_url_runtime_params => {:original_request_param => :mapped_idp_param}, :idp_cert => "-----BEGIN CERTIFICATE-----\n...-----END CERTIFICATE-----", :idp_cert_fingerprint => "E7:91:B2:E1:...", :idp_cert_fingerprint_validator => lambda { |fingerprint| fingerprint }, :name_identifier_format => "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" ``` or in your Rails application: in `Gemfile`: ```ruby gem 'omniauth-saml' ``` and in `config/initializers/omniauth.rb`: ```ruby Rails.application.config.middleware.use OmniAuth::Builder do provider :saml, :assertion_consumer_service_url => "consumer_service_url", :issuer => "rails-application", :idp_sso_target_url => "idp_sso_target_url", :idp_sso_target_url_runtime_params => {:original_request_param => :mapped_idp_param}, :idp_cert => "-----BEGIN CERTIFICATE-----\n...-----END CERTIFICATE-----", :idp_cert_fingerprint => "E7:91:B2:E1:...", :idp_cert_fingerprint_validator => lambda { |fingerprint| fingerprint }, :name_identifier_format => "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" end ``` For IdP-initiated SSO, users should directly access the IdP SSO target URL. Set the `href` of your application's login link to the value of `idp_sso_target_url`. For SP-initiated SSO, link to `/auth/saml`. A `OneLogin::RubySaml::Response` object is added to the `env['omniauth.auth']` extra attribute, so we can use it in the controller via `env['omniauth.auth'].extra.response_object` ## Metadata The service provider metadata used to ease configuration of the SAML SP in the IdP can be retrieved from `http://example.com/auth/saml/metadata`. Send this URL to the administrator of the IdP. ## Options * `:assertion_consumer_service_url` - The URL at which the SAML assertion should be received. If not provided, defaults to the OmniAuth callback URL (typically `http://example.com/auth/saml/callback`). Optional. * `:issuer` - The name of your application. Some identity providers might need this to establish the identity of the service provider requesting the login. **Required**. * `:idp_sso_target_url` - The URL to which the authentication request should be sent. This would be on the identity provider. **Required**. * `:idp_slo_target_url` - The URL to which the single logout request and response should be sent. This would be on the identity provider. Optional. * `:slo_default_relay_state` - The value to use as default `RelayState` for single log outs. The value can be a string, or a `Proc` (or other object responding to `call`). The `request` instance will be passed to this callable if it has an arity of 1. If the value is a string, the string will be returned, when the `RelayState` is called. Optional. * `:idp_sso_target_url_runtime_params` - A dynamic mapping of request params that exist during the request phase of OmniAuth that should to be sent to the IdP after a specific mapping. So for example, a param `original_request_param` with value `original_param_value`, could be sent to the IdP on the login request as `mapped_idp_param` with value `original_param_value`. Optional. * `:idp_cert` - The identity provider's certificate in PEM format. Takes precedence over the fingerprint option below. This option or `:idp_cert_fingerprint` or `:idp_cert_fingerprint_validator` must be present. * `:idp_cert_fingerprint` - The SHA1 fingerprint of the certificate, e.g. "90:CC:16:F0:8D:...". This is provided from the identity provider when setting up the relationship. This option or `:idp_cert` or `:idp_cert_fingerprint_validator` MUST be present. * `:idp_cert_fingerprint_validator` - A lambda that MUST accept one parameter (the fingerprint), verify if it is valid and return it if successful. This option or `:idp_cert` or `:idp_cert_fingerprint` MUST be present. * `:name_identifier_format` - Used during SP-initiated SSO. Describes the format of the username required by this application. If you need the email address, use "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress". See http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf section 8.3 for other options. Note that the identity provider might not support all options. If not specified, the IdP is free to choose the name identifier format used in the response. Optional. * `:request_attributes` - Used to build the metadata file to inform the IdP to send certain attributes along with the SAMLResponse messages. Defaults to requesting `name`, `first_name`, `last_name` and `email` attributes. See the `OneLogin::RubySaml::AttributeService` class in the [Ruby SAML gem](https://github.com/onelogin/ruby-saml) for the available options for each attribute. Set to `{}` to disable this from metadata. * `:attribute_service_name` - Name for the attribute service. Defaults to `Required attributes`. * `:attribute_statements` - Used to map Attribute Names in a SAMLResponse to entries in the OmniAuth [info hash](https://github.com/intridea/omniauth/wiki/Auth-Hash-Schema#schema-10-and-later). For example, if your SAMLResponse contains an Attribute called 'EmailAddress', specify `{:email => ['EmailAddress']}` to map the Attribute to the corresponding key in the info hash. URI-named Attributes are also supported, e.g. `{:email => ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress']}`. *Note*: All attributes can also be found in an array under `auth_hash[:extra][:raw_info]`, so this setting should only be used to map attributes that are part of the OmniAuth info hash schema. * See the `OneLogin::RubySaml::Settings` class in the [Ruby SAML gem](https://github.com/onelogin/ruby-saml) for additional supported options. ## Devise Integration Straightforward integration with [Devise](https://github.com/plataformatec/devise), the widely-used authentication solution for Rails. In `config/initializers/devise.rb`: ```ruby Devise.setup do |config| config.omniauth :saml, idp_cert_fingerprint: 'fingerprint', idp_sso_target_url: 'target_url' end ``` Then follow Devise's general [OmniAuth tutorial](https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview), replacing references to `facebook` with `saml`. ## Single Logout Single Logout can be Service Provider initiated or Identity Provider initiated. When using Devise as an authentication solution, the SP initiated flow can be integrated in the `SessionsController#destroy` action. For this to work it is important to preserve the `saml_uid` value before Devise clears the session and redirect to the `/spslo` sub-path to initiate the single logout. Example `destroy` action in `sessions_controller.rb`: ```ruby class SessionsController < Devise::SessionsController # ... def destroy # Preserve the saml_uid in the session saml_uid = session["saml_uid"] super do session["saml_uid"] = saml_uid if SAML_SETTINGS.idp_slo_target_url spslo_url = user_omniauth_authorize_url(:saml) + "/spslo" redirect_to(spslo_url) end end end end ``` ## Authors Authored by [Rajiv Aaron Manglani](http://www.rajivmanglani.com/), Raecoo Cao, Todd W Saxton, Ryan Wilcox, Steven Anderson, Nikos Dimitrakopoulos, Rudolf Vriend and [Bruno Pedro](http://brunopedro.com/). omniauth-saml-1.7.0/gemfiles/000077500000000000000000000000001300171045600160655ustar00rootroot00000000000000omniauth-saml-1.7.0/gemfiles/rack_1.gemfile000066400000000000000000000004741300171045600205640ustar00rootroot00000000000000# This file was generated by Appraisal source "https://rubygems.org" gem "appraisal" gem "rack", "~> 1.x" gem "term-ansicolor", "1.3.2" group :test do gem "coveralls", "~> 0.8", ">= 0.8.13", :require => false gem "json", "~> 1.8" gem "tins", "~> 1.6.0" gem "mime-types", "< 3" end gemspec :path => "../" omniauth-saml-1.7.0/gemfiles/rack_2.gemfile000066400000000000000000000004361300171045600205630ustar00rootroot00000000000000# This file was generated by Appraisal source "https://rubygems.org" gem "appraisal" gem "rack", "~> 2.x" group :test do gem "coveralls", "~> 0.8", ">= 0.8.13", :require => false gem "json", "~> 1.8" gem "tins", "~> 1.6.0" gem "mime-types", "< 3" end gemspec :path => "../" omniauth-saml-1.7.0/lib/000077500000000000000000000000001300171045600150405ustar00rootroot00000000000000omniauth-saml-1.7.0/lib/omniauth-saml.rb000066400000000000000000000001271300171045600201430ustar00rootroot00000000000000require 'omniauth/strategies/saml' require 'omniauth/strategies/saml/validation_error' omniauth-saml-1.7.0/lib/omniauth-saml/000077500000000000000000000000001300171045600176165ustar00rootroot00000000000000omniauth-saml-1.7.0/lib/omniauth-saml/version.rb000066400000000000000000000000761300171045600216330ustar00rootroot00000000000000module OmniAuth module SAML VERSION = '1.7.0' end end omniauth-saml-1.7.0/lib/omniauth/000077500000000000000000000000001300171045600166645ustar00rootroot00000000000000omniauth-saml-1.7.0/lib/omniauth/strategies/000077500000000000000000000000001300171045600210365ustar00rootroot00000000000000omniauth-saml-1.7.0/lib/omniauth/strategies/saml.rb000066400000000000000000000222421300171045600223210ustar00rootroot00000000000000require 'omniauth' require 'ruby-saml' module OmniAuth module Strategies class SAML include OmniAuth::Strategy def self.inherited(subclass) OmniAuth::Strategy.included(subclass) end OTHER_REQUEST_OPTIONS = [:skip_conditions, :allowed_clock_drift, :matches_request_id, :skip_subject_confirmation].freeze option :name_identifier_format, nil option :idp_sso_target_url_runtime_params, {} option :request_attributes, [ { :name => 'email', :name_format => 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', :friendly_name => 'Email address' }, { :name => 'name', :name_format => 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', :friendly_name => 'Full name' }, { :name => 'first_name', :name_format => 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', :friendly_name => 'Given name' }, { :name => 'last_name', :name_format => 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', :friendly_name => 'Family name' } ] option :attribute_service_name, 'Required attributes' option :attribute_statements, { name: ["name"], email: ["email", "mail"], first_name: ["first_name", "firstname", "firstName"], last_name: ["last_name", "lastname", "lastName"] } option :slo_default_relay_state def request_phase options[:assertion_consumer_service_url] ||= callback_url runtime_request_parameters = options.delete(:idp_sso_target_url_runtime_params) additional_params = {} if runtime_request_parameters runtime_request_parameters.each_pair do |request_param_key, mapped_param_key| additional_params[mapped_param_key] = request.params[request_param_key.to_s] if request.params.has_key?(request_param_key.to_s) end end authn_request = OneLogin::RubySaml::Authrequest.new settings = OneLogin::RubySaml::Settings.new(options) redirect(authn_request.create(settings, additional_params)) end def callback_phase raise OmniAuth::Strategies::SAML::ValidationError.new("SAML response missing") unless request.params["SAMLResponse"] # Call a fingerprint validation method if there's one if options.idp_cert_fingerprint_validator fingerprint_exists = options.idp_cert_fingerprint_validator[response_fingerprint] unless fingerprint_exists raise OmniAuth::Strategies::SAML::ValidationError.new("Non-existent fingerprint") end # id_cert_fingerprint becomes the given fingerprint if it exists options.idp_cert_fingerprint = fingerprint_exists end settings = OneLogin::RubySaml::Settings.new(options) # filter options to select only extra parameters opts = options.select {|k,_| OTHER_REQUEST_OPTIONS.include?(k.to_sym)} # symbolize keys without activeSupport/symbolize_keys (ruby-saml use symbols) opts = opts.inject({}) do |new_hash, (key, value)| new_hash[key.to_sym] = value new_hash end handle_response(request.params["SAMLResponse"], opts, settings) do super end rescue OmniAuth::Strategies::SAML::ValidationError fail!(:invalid_ticket, $!) rescue OneLogin::RubySaml::ValidationError fail!(:invalid_ticket, $!) end # Obtain an idp certificate fingerprint from the response. def response_fingerprint response = request.params["SAMLResponse"] response = (response =~ /^ 'http://www.w3.org/2000/09/xmldsig#' }) base64_cert = cert_element.text cert_text = Base64.decode64(base64_cert) cert = OpenSSL::X509::Certificate.new(cert_text) Digest::SHA1.hexdigest(cert.to_der).upcase.scan(/../).join(':') end def other_phase if current_path.start_with?(request_path) @env['omniauth.strategy'] ||= self setup_phase settings = OneLogin::RubySaml::Settings.new(options) if on_subpath?(:metadata) # omniauth does not set the strategy on the other_phase response = OneLogin::RubySaml::Metadata.new if options.request_attributes.length > 0 settings.attribute_consuming_service.service_name options.attribute_service_name settings.issuer = options.issuer options.request_attributes.each do |attribute| settings.attribute_consuming_service.add_attribute attribute end end Rack::Response.new(response.generate(settings), 200, { "Content-Type" => "application/xml" }).finish elsif on_subpath?(:slo) if request.params["SAMLResponse"] handle_logout_response(request.params["SAMLResponse"], settings) elsif request.params["SAMLRequest"] handle_logout_request(request.params["SAMLRequest"], settings) else raise OmniAuth::Strategies::SAML::ValidationError.new("SAML logout response/request missing") end elsif on_subpath?(:spslo) if options.idp_slo_target_url redirect(generate_logout_request(settings)) else Rack::Response.new("Not Implemented", 501, { "Content-Type" => "text/html" }).finish end else call_app! end else call_app! end end uid { @name_id } info do found_attributes = options.attribute_statements.map do |key, values| attribute = find_attribute_by(values) [key, attribute] end Hash[found_attributes] end extra { { :raw_info => @attributes, :response_object => @response_object } } def find_attribute_by(keys) keys.each do |key| return @attributes[key] if @attributes[key] end nil end private def on_subpath?(subpath) on_path?("#{request_path}/#{subpath}") end def handle_response(raw_response, opts, settings) response = OneLogin::RubySaml::Response.new(raw_response, opts.merge(settings: settings)) response.attributes["fingerprint"] = options.idp_cert_fingerprint response.soft = false response.is_valid? @name_id = response.name_id @attributes = response.attributes @response_object = response if @name_id.nil? || @name_id.empty? raise OmniAuth::Strategies::SAML::ValidationError.new("SAML response missing 'name_id'") end session["saml_uid"] = @name_id yield end def slo_relay_state if request.params.has_key?("RelayState") && request.params["RelayState"] != "" request.params["RelayState"] else slo_default_relay_state = options.slo_default_relay_state if slo_default_relay_state.respond_to?(:call) if slo_default_relay_state.arity == 1 slo_default_relay_state.call(request) else slo_default_relay_state.call end else slo_default_relay_state end end end def handle_logout_response(raw_response, settings) # After sending an SP initiated LogoutRequest to the IdP, we need to accept # the LogoutResponse, verify it, then actually delete our session. logout_response = OneLogin::RubySaml::Logoutresponse.new(raw_response, settings, :matches_request_id => session["saml_transaction_id"]) logout_response.soft = false logout_response.validate session.delete("saml_uid") session.delete("saml_transaction_id") redirect(slo_relay_state) end def handle_logout_request(raw_request, settings) logout_request = OneLogin::RubySaml::SloLogoutrequest.new(raw_request) if logout_request.is_valid? && logout_request.name_id == session["saml_uid"] # Actually log out this session session.clear # Generate a response to the IdP. logout_request_id = logout_request.id logout_response = OneLogin::RubySaml::SloLogoutresponse.new.create(settings, logout_request_id, nil, RelayState: slo_relay_state) redirect(logout_response) else raise OmniAuth::Strategies::SAML::ValidationError.new("SAML failed to process LogoutRequest") end end # Create a SP initiated SLO: https://github.com/onelogin/ruby-saml#single-log-out def generate_logout_request(settings) logout_request = OneLogin::RubySaml::Logoutrequest.new() # Since we created a new SAML request, save the transaction_id # to compare it with the response we get back session["saml_transaction_id"] = logout_request.uuid if settings.name_identifier_value.nil? settings.name_identifier_value = session["saml_uid"] end logout_request.create(settings, RelayState: slo_relay_state) end end end end OmniAuth.config.add_camelization 'saml', 'SAML' omniauth-saml-1.7.0/lib/omniauth/strategies/saml/000077500000000000000000000000001300171045600217725ustar00rootroot00000000000000omniauth-saml-1.7.0/lib/omniauth/strategies/saml/validation_error.rb000066400000000000000000000001661300171045600256650ustar00rootroot00000000000000module OmniAuth module Strategies class SAML class ValidationError < Exception end end end endomniauth-saml-1.7.0/omniauth-saml.gemspec000066400000000000000000000022131300171045600204130ustar00rootroot00000000000000require File.expand_path('../lib/omniauth-saml/version', __FILE__) Gem::Specification.new do |gem| gem.name = 'omniauth-saml' gem.version = OmniAuth::SAML::VERSION gem.summary = 'A generic SAML strategy for OmniAuth.' gem.description = 'A generic SAML strategy for OmniAuth.' gem.license = 'MIT' gem.authors = ['Raecoo Cao', 'Ryan Wilcox', 'Rajiv Aaron Manglani', 'Steven Anderson', 'Nikos Dimitrakopoulos', 'Rudolf Vriend', 'Bruno Pedro'] gem.email = 'rajiv@alum.mit.edu' gem.homepage = 'https://github.com/omniauth/omniauth-saml' gem.add_runtime_dependency 'omniauth', '~> 1.3' gem.add_runtime_dependency 'ruby-saml', '~> 1.4' gem.add_development_dependency 'rake', '>= 10', '< 12' gem.add_development_dependency 'rspec', '~>3.4' gem.add_development_dependency 'simplecov', '~> 0.11' gem.add_development_dependency 'rack-test', '~> 0.6', '>= 0.6.3' gem.add_development_dependency 'conventional-changelog', '~> 1.2' gem.files = ['README.md', 'CHANGELOG.md', 'LICENSE.md'] + Dir['lib/**/*.rb'] gem.test_files = Dir['spec/**/*.rb'] gem.require_paths = ["lib"] end omniauth-saml-1.7.0/spec/000077500000000000000000000000001300171045600152245ustar00rootroot00000000000000omniauth-saml-1.7.0/spec/omniauth/000077500000000000000000000000001300171045600170505ustar00rootroot00000000000000omniauth-saml-1.7.0/spec/omniauth/strategies/000077500000000000000000000000001300171045600212225ustar00rootroot00000000000000omniauth-saml-1.7.0/spec/omniauth/strategies/saml_spec.rb000066400000000000000000000260721300171045600235240ustar00rootroot00000000000000require 'spec_helper' RSpec::Matchers.define :fail_with do |message| match do |actual| actual.redirect? && /\?.*message=#{message}/ === actual.location end end def post_xml(xml=:example_response, opts = {}) post "/auth/saml/callback", opts.merge({'SAMLResponse' => load_xml(xml)}) end describe OmniAuth::Strategies::SAML, :type => :strategy do include OmniAuth::Test::StrategyTestCase let(:auth_hash){ last_request.env['omniauth.auth'] } let(:saml_options) do { :assertion_consumer_service_url => "http://localhost:9080/auth/saml/callback", :single_logout_service_url => "http://localhost:9080/auth/saml/slo", :idp_sso_target_url => "https://idp.sso.example.com/signon/29490", :idp_slo_target_url => "https://idp.sso.example.com/signoff/29490", :idp_cert_fingerprint => "C1:59:74:2B:E8:0C:6C:A9:41:0F:6E:83:F6:D1:52:25:45:58:89:FB", :idp_sso_target_url_runtime_params => {:original_param_key => :mapped_param_key}, :name_identifier_format => "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", :request_attributes => [ { :name => 'email', :name_format => 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', :friendly_name => 'Email address' }, { :name => 'name', :name_format => 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', :friendly_name => 'Full name' }, { :name => 'first_name', :name_format => 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', :friendly_name => 'Given name' }, { :name => 'last_name', :name_format => 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', :friendly_name => 'Family name' } ], :attribute_service_name => 'Required attributes' } end let(:strategy) { [OmniAuth::Strategies::SAML, saml_options] } describe 'GET /auth/saml' do context 'without idp runtime params present' do before do get '/auth/saml' end it 'should get authentication page' do expect(last_response).to be_redirect expect(last_response.location).to match /https:\/\/idp.sso.example.com\/signon\/29490/ expect(last_response.location).to match /\?SAMLRequest=/ expect(last_response.location).not_to match /mapped_param_key/ expect(last_response.location).not_to match /original_param_key/ end end context 'with idp runtime params' do before do get '/auth/saml', 'original_param_key' => 'original_param_value', 'mapped_param_key' => 'mapped_param_value' end it 'should get authentication page' do expect(last_response).to be_redirect expect(last_response.location).to match /https:\/\/idp.sso.example.com\/signon\/29490/ expect(last_response.location).to match /\?SAMLRequest=/ expect(last_response.location).to match /\&mapped_param_key=original_param_value/ expect(last_response.location).not_to match /original_param_key/ end end context "when the assertion_consumer_service_url is the default" do before :each do saml_options[:compress_request] = false saml_options.delete(:assertion_consumer_service_url) end it 'should send the current callback_url as the assertion_consumer_service_url' do %w(foo.example.com bar.example.com).each do |host| get "https://#{host}/auth/saml" expect(last_response).to be_redirect location = URI.parse(last_response.location) query = Rack::Utils.parse_query location.query expect(query).to have_key('SAMLRequest') request = REXML::Document.new(Base64.decode64(query['SAMLRequest'])) expect(request.root).not_to be_nil acs = request.root.attributes.get_attribute('AssertionConsumerServiceURL') expect(acs.to_s).to eq "https://#{host}/auth/saml/callback" end end end end describe 'POST /auth/saml/callback' do subject { last_response } let(:xml) { :example_response } before :each do allow(Time).to receive(:now).and_return(Time.utc(2012, 11, 8, 20, 40, 00)) end context "when the response is valid" do before :each do post_xml end it "should set the uid to the nameID in the SAML response" do expect(auth_hash['uid']).to eq '_1f6fcf6be5e13b08b1e3610e7ff59f205fbd814f23' end it "should set the raw info to all attributes" do expect(auth_hash['extra']['raw_info'].all.to_hash).to eq( 'first_name' => ['Rajiv'], 'last_name' => ['Manglani'], 'email' => ['user@example.com'], 'company_name' => ['Example Company'], 'fingerprint' => saml_options[:idp_cert_fingerprint] ) end it "should set the response_object to the response object from ruby_saml response" do expect(auth_hash['extra']['response_object']).to be_kind_of(OneLogin::RubySaml::Response) end end context "when fingerprint is empty and there's a fingerprint validator" do before :each do saml_options.delete(:idp_cert_fingerprint) saml_options[:idp_cert_fingerprint_validator] = lambda { |fingerprint| "C1:59:74:2B:E8:0C:6C:A9:41:0F:6E:83:F6:D1:52:25:45:58:89:FB" } post_xml end it "should set the uid to the nameID in the SAML response" do expect(auth_hash['uid']).to eq '_1f6fcf6be5e13b08b1e3610e7ff59f205fbd814f23' end it "should set the raw info to all attributes" do expect(auth_hash['extra']['raw_info'].all.to_hash).to eq( 'first_name' => ['Rajiv'], 'last_name' => ['Manglani'], 'email' => ['user@example.com'], 'company_name' => ['Example Company'], 'fingerprint' => 'C1:59:74:2B:E8:0C:6C:A9:41:0F:6E:83:F6:D1:52:25:45:58:89:FB' ) end end context "when there is no SAMLResponse parameter" do before :each do post '/auth/saml/callback' end it { should fail_with(:invalid_ticket) } end context "when there is no name id in the XML" do before :each do allow(Time).to receive(:now).and_return(Time.utc(2012, 11, 8, 23, 55, 00)) post_xml :no_name_id end it { should fail_with(:invalid_ticket) } end context "when the fingerprint is invalid" do before :each do saml_options[:idp_cert_fingerprint] = "00:00:00:00:00:0C:6C:A9:41:0F:6E:83:F6:D1:52:25:45:58:89:FB" post_xml end it { should fail_with(:invalid_ticket) } end context "when the digest is invalid" do before :each do post_xml :digest_mismatch end it { should fail_with(:invalid_ticket) } end context "when the signature is invalid" do before :each do post_xml :invalid_signature end it { should fail_with(:invalid_ticket) } end context "when response has custom attributes" do before :each do saml_options[:idp_cert_fingerprint] = "3B:82:F1:F5:54:FC:A8:FF:12:B8:4B:B8:16:61:1D:E4:8E:9B:E2:3C" saml_options[:attribute_statements] = { email: ["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"], first_name: ["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"], last_name: ["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"] } post_xml :custom_attributes end it "should obey attribute statements mapping" do expect(auth_hash[:info]).to eq( 'first_name' => 'Rajiv', 'last_name' => 'Manglani', 'email' => 'user@example.com', 'name' => nil ) end end context "when response is a logout response" do before :each do saml_options[:issuer] = "https://idp.sso.example.com/metadata/29490" post "/auth/saml/slo", { SAMLResponse: load_xml(:example_logout_response), RelayState: "https://example.com/", }, "rack.session" => {"saml_transaction_id" => "_3fef1069-d0c6-418a-b68d-6f008a4787e9"} end it "should redirect to relaystate" do expect(last_response).to be_redirect expect(last_response.location).to match /https:\/\/example.com\// end end context "when request is a logout request" do before :each do saml_options[:issuer] = "https://idp.sso.example.com/metadata/29490" post "/auth/saml/slo", { "SAMLRequest" => load_xml(:example_logout_request), "RelayState" => "https://example.com/", }, "rack.session" => {"saml_uid" => "username@example.com"} end it "should redirect to logout response" do expect(last_response).to be_redirect expect(last_response.location).to match /https:\/\/idp.sso.example.com\/signoff\/29490/ expect(last_response.location).to match /RelayState=https%3A%2F%2Fexample.com%2F/ end end context "when sp initiated SLO" do def test_default_relay_state(static_default_relay_state = nil, &block_default_relay_state) saml_options["slo_default_relay_state"] = static_default_relay_state || block_default_relay_state post "/auth/saml/spslo" expect(last_response).to be_redirect expect(last_response.location).to match /https:\/\/idp.sso.example.com\/signoff\/29490/ expect(last_response.location).to match /RelayState=https%3A%2F%2Fexample.com%2F/ end it "should redirect to logout request" do test_default_relay_state("https://example.com/") end it "should redirect to logout request with a block" do test_default_relay_state do "https://example.com/" end end it "should redirect to logout request with a block with a request parameter" do test_default_relay_state do |request| "https://example.com/" end end it "should give not implemented without an idp_slo_target_url" do saml_options.delete(:idp_slo_target_url) post "/auth/saml/spslo" expect(last_response.status).to eq 501 expect(last_response.body).to match /Not Implemented/ end end end describe 'GET /auth/saml/metadata' do before do saml_options[:issuer] = 'http://example.com/SAML' get '/auth/saml/metadata' end it 'should get SP metadata page' do expect(last_response.status).to eq 200 expect(last_response.header["Content-Type"]).to eq "application/xml" end it 'should configure attributes consuming service' do expect(last_response.body).to match /AttributeConsumingService/ expect(last_response.body).to match /first_name/ expect(last_response.body).to match /last_name/ expect(last_response.body).to match /Required attributes/ expect(last_response.body).to match /entityID/ expect(last_response.body).to match /http:\/\/example.com\/SAML/ end end describe 'subclass behavior' do it 'registers subclasses in OmniAuth.strategies' do subclass = Class.new(described_class) expect(OmniAuth.strategies).to include(described_class, subclass) end end end omniauth-saml-1.7.0/spec/spec_helper.rb000066400000000000000000000011541300171045600200430ustar00rootroot00000000000000if RUBY_VERSION >= '1.9' require 'simplecov' if ENV['TRAVIS'] require 'coveralls' Coveralls.wear! end SimpleCov.start end require 'omniauth-saml' require 'rack/test' require 'rexml/document' require 'rexml/xpath' require 'base64' TEST_LOGGER = Logger.new(StringIO.new) OneLogin::RubySaml::Logging.logger = TEST_LOGGER OmniAuth.config.logger = TEST_LOGGER RSpec.configure do |config| config.include Rack::Test::Methods end def load_xml(filename=:example_response) filename = File.expand_path(File.join('..', 'support', "#{filename.to_s}.xml"), __FILE__) Base64.encode64(IO.read(filename)) end omniauth-saml-1.7.0/spec/support/000077500000000000000000000000001300171045600167405ustar00rootroot00000000000000omniauth-saml-1.7.0/spec/support/custom_attributes.xml000066400000000000000000000145101300171045600232430ustar00rootroot00000000000000 http://localhost:9000/saml2/idp/metadata.php f311FuR1PE2NXct21G5z8Ka/Gfo= 3vfxoQn2PLwcYp1ApVLzlaZKEcHGjNZwLCBHkJC8oHYRonoL8v25iJ+5NFlWWXxSRG0SUA15coH+1gLMm6cF41h1sqHL/3wtiHQARnJUogqRUM76hTePHkSiJMUpr+ZD+Kb/l0DFct9/gJYkW1RPny9v8vdGNsMOQ/qnmk2xtII= MIICWDCCAcGgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBJMQswCQYDVQQGEwJmaTEQMA4GA1UECAwHVXVzaW1hYTERMA8GA1UECgwIRmxvd2RvY2sxFTATBgNVBAMMDGZsb3dkb2NrLmNvbTAeFw0xNTA5MTYwODUxMzdaFw0xNjA5MTUwODUxMzdaMEkxCzAJBgNVBAYTAmZpMRAwDgYDVQQIDAdVdXNpbWFhMREwDwYDVQQKDAhGbG93ZG9jazEVMBMGA1UEAwwMZmxvd2RvY2suY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB gQDntqPTJ4pRMWb5d17e3vImfpOg6Hzr3PFtbsqEyM8uXZAL713Q4oASum+VlKkPp5ybzJKrFYeEeCl4NOdwyuabrOTUoJLE/x6CpGBgU6o+Iavku+4CkDM5scEIguZgroVabvkwoZRs/2TgVbLhNWXwtLD7n1OvVhLI0L9ycK+RNQIDAQABo1AwTjAdBgNVHQ4EFgQU9t1/AYExhABNzP1+hCsuImUpkXAwHwYDVR0jBBgwFoAU9t1/AYExhABNzP1+hCsuImUpkXAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQCoMeBcLW6JTOdmygPXhYtS+c8t9RCg6Ki/XENOkZN98NgBRS7mAw+DZDezw5KTSH6k0DNw04MFAVZ64gaP2/ad9wHnsktH3mvbfQ8RY6XefSqNy0SuKIt03q26Xf3/vi1jrxn2JgnJG4V+AVR3DVoiiAfQF1ijQW2qhnZR3WCnWQ== http://localhost:9000/saml2/idp/metadata.php 20g3ohE5p7icP5ZQ3CSRkSpGaME= m9+Hq+RDNJyKWGsqCpqmkXt/6dz/NQUkdzeF5YHSezVuLFJajB+QC2aSeyic5H5Z0LBkQscjZ1sgme7Hyeo+ZvBgDrBejP6bZfMyaNrET6JTKXxXnrSI0txEL7oXGgnWLJX+oTUWLJgO+PHAUGeS9AgbKcBTQjaW7aW8uh4WtJg= MIICWDCCAcGgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBJMQswCQYDVQQGEwJmaTEQMA4GA1UECAwHVXVzaW1hYTERMA8GA1UECgwIRmxvd2RvY2sxFTATBgNVBAMMDGZsb3dkb2NrLmNvbTAeFw0xNTA5MTYwODUxMzdaFw0xNjA5MTUwODUxMzdaMEkxCzAJBgNVBAYTAmZpMRAwDgYDVQQIDAdVdXNpbWFhMREwDwYDVQQKDAhGbG93ZG9jazEVMBMGA1UEAwwMZmxvd2RvY2suY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB gQDntqPTJ4pRMWb5d17e3vImfpOg6Hzr3PFtbsqEyM8uXZAL713Q4oASum+VlKkPp5ybzJKrFYeEeCl4NOdwyuabrOTUoJLE/x6CpGBgU6o+Iavku+4CkDM5scEIguZgroVabvkwoZRs/2TgVbLhNWXwtLD7n1OvVhLI0L9ycK+RNQIDAQABo1AwTjAdBgNVHQ4EFgQU9t1/AYExhABNzP1+hCsuImUpkXAwHwYDVR0jBBgwFoAU9t1/AYExhABNzP1+hCsuImUpkXAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQCoMeBcLW6JTOdmygPXhYtS+c8t9RCg6Ki/XENOkZN98NgBRS7mAw+DZDezw5KTSH6k0DNw04MFAVZ64gaP2/ad9wHnsktH3mvbfQ8RY6XefSqNy0SuKIt03q26Xf3/vi1jrxn2JgnJG4V+AVR3DVoiiAfQF1ijQW2qhnZR3WCnWQ== _1f6fcf6be5e13b08b1e3610e7ff59f205fbd814f23 sample-saml-strategy urn:oasis:names:tc:SAML:2.0:ac:classes:Password Rajiv Manglani user@example.com omniauth-saml-1.7.0/spec/support/digest_mismatch.xml000066400000000000000000000150111300171045600226240ustar00rootroot00000000000000http://localhost:9000/saml2/idp/metadata.php AAAAAKooo1K7yYnKfXy88BRqgXM=N8G4Meh60EnU5U113JH3fHEr3nA+87kemKZDkqfEZnGHrfwfO2KhSbKEsU6M1ELq8ZCNDxYCFhbfwJOWij5+qkMD1gMYqvH2Hz169l5smEAfkmtovJwq+2lVO7AtVLez065rx2g+n2DmZx82H3ynrMV0vTDEQ2AohJPZjsRoNgY= MIIDHDCCAoWgAwIBAgIJAJq7aJgm4De9MA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTAeFw0xMjExMDgyMDI5NTFaFw0xMjEyMDgyMDI5NTFaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzwg6Rakhf6boh5E2zve9Lp6dSjMTdrJhFQ1WRZwMOfRO7GPD9c7RetnxuPbg6PyBfSdFoGCJvMswDJMa7DZAlbgsf1WyOw9gaHzgf4j79XlFpis3XKJX8i1vUxxEVW7pYrUTJU0xbZ75l3AXtfnHXnxURF0eiD+s51nKBtnSkRcCAwEAAaOBzTCByjAdBgNVHQ4EFgQULih6jYTJ3XNDs53KSVwt4F9G2agwgZoGA1UdIwSBkjCBj4AULih6jYTJ3XNDs53KSVwt4F9G2aihbKRqMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZYIJAJq7aJgm4De9MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAg+rrwZooo8DE47jmaBX+vUJBIVgSKdB45bDkL7FgTca2h1tsmgUL9nFyvp9FDEQ7IYw5599ywhrQf9GfsIZ374G7ie9C8JqURbdiP4/MMvOjV1RzyypXByfaY20tDwgz6JlLs7snh7O3s93FKpWhCjHE434CJwa1q5nHqNTgkZw=http://localhost:9000/saml2/idp/metadata.php 20g3ohE5p7icP5ZQ3CSRkSpGaME=m9+Hq+RDNJyKWGsqCpqmkXt/6dz/NQUkdzeF5YHSezVuLFJajB+QC2aSeyic5H5Z0LBkQscjZ1sgme7Hyeo+ZvBgDrBejP6bZfMyaNrET6JTKXxXnrSI0txEL7oXGgnWLJX+oTUWLJgO+PHAUGeS9AgbKcBTQjaW7aW8uh4WtJg= MIIDHDCCAoWgAwIBAgIJAJq7aJgm4De9MA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTAeFw0xMjExMDgyMDI5NTFaFw0xMjEyMDgyMDI5NTFaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzwg6Rakhf6boh5E2zve9Lp6dSjMTdrJhFQ1WRZwMOfRO7GPD9c7RetnxuPbg6PyBfSdFoGCJvMswDJMa7DZAlbgsf1WyOw9gaHzgf4j79XlFpis3XKJX8i1vUxxEVW7pYrUTJU0xbZ75l3AXtfnHXnxURF0eiD+s51nKBtnSkRcCAwEAAaOBzTCByjAdBgNVHQ4EFgQULih6jYTJ3XNDs53KSVwt4F9G2agwgZoGA1UdIwSBkjCBj4AULih6jYTJ3XNDs53KSVwt4F9G2aihbKRqMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZYIJAJq7aJgm4De9MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAg+rrwZooo8DE47jmaBX+vUJBIVgSKdB45bDkL7FgTca2h1tsmgUL9nFyvp9FDEQ7IYw5599ywhrQf9GfsIZ374G7ie9C8JqURbdiP4/MMvOjV1RzyypXByfaY20tDwgz6JlLs7snh7O3s93FKpWhCjHE434CJwa1q5nHqNTgkZw=_1f6fcf6be5e13b08b1e3610e7ff59f205fbd814f23sample-saml-strategyurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordRajivManglaniuser@example.comExample Company omniauth-saml-1.7.0/spec/support/example_cert.pem000066400000000000000000000064371300171045600221250ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 9a:bb:68:98:26:e0:37:bd Signature Algorithm: sha1WithRSAEncryption Issuer: C=US, ST=Some-State, O=Example Company, CN=OmniAuth SAML Testing Certificate Validity Not Before: Nov 8 20:29:51 2012 GMT Not After : Dec 8 20:29:51 2012 GMT Subject: C=US, ST=Some-State, O=Example Company, CN=OmniAuth SAML Testing Certificate Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (1024 bit) Modulus (1024 bit): 00:cf:08:3a:45:a9:21:7f:a6:e8:87:91:36:ce:f7: bd:2e:9e:9d:4a:33:13:76:b2:61:15:0d:56:45:9c: 0c:39:f4:4e:ec:63:c3:f5:ce:d1:7a:d9:f1:b8:f6: e0:e8:fc:81:7d:27:45:a0:60:89:bc:cb:30:0c:93: 1a:ec:36:40:95:b8:2c:7f:55:b2:3b:0f:60:68:7c: e0:7f:88:fb:f5:79:45:a6:2b:37:5c:a2:57:f2:2d: 6f:53:1c:44:55:6e:e9:62:b5:13:25:4d:31:6d:9e: f9:97:70:17:b5:f9:c7:5e:7c:54:44:5d:1e:88:3f: ac:e7:59:ca:06:d9:d2:91:17 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 2E:28:7A:8D:84:C9:DD:73:43:B3:9D:CA:49:5C:2D:E0:5F:46:D9:A8 X509v3 Authority Key Identifier: keyid:2E:28:7A:8D:84:C9:DD:73:43:B3:9D:CA:49:5C:2D:E0:5F:46:D9:A8 DirName:/C=US/ST=Some-State/O=Example Company/CN=OmniAuth SAML Testing Certificate serial:9A:BB:68:98:26:E0:37:BD X509v3 Basic Constraints: CA:TRUE Signature Algorithm: sha1WithRSAEncryption 83:ea:eb:c1:9a:28:a3:c0:c4:e3:b8:e6:68:15:fe:bd:42:41: 21:58:12:29:d0:78:e5:b0:e4:2f:b1:60:4d:c6:b6:87:5b:6c: 9a:05:0b:f6:71:72:be:9f:45:0c:44:3b:21:8c:39:e7:df:72: c2:1a:d0:7f:d1:9f:b0:86:77:ef:81:bb:89:ef:42:f0:9a:94: 45:b7:62:3f:8f:cc:32:f3:a3:57:54:73:cb:2a:57:07:27:da: 63:6d:2d:0f:08:33:e8:99:4b:b3:bb:27:87:b3:b7:b3:dd:c5: 2a:95:a1:0a:31:c4:e3:7e:02:27:06:b5:ab:99:c7:a8:d4:e0: 91:9c -----BEGIN CERTIFICATE----- MIIDHDCCAoWgAwIBAgIJAJq7aJgm4De9MA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV BAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENv bXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0 ZTAeFw0xMjExMDgyMDI5NTFaFw0xMjEyMDgyMDI5NTFaMGgxCzAJBgNVBAYTAlVT MRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkx KjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTCBnzAN BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzwg6Rakhf6boh5E2zve9Lp6dSjMTdrJh FQ1WRZwMOfRO7GPD9c7RetnxuPbg6PyBfSdFoGCJvMswDJMa7DZAlbgsf1WyOw9g aHzgf4j79XlFpis3XKJX8i1vUxxEVW7pYrUTJU0xbZ75l3AXtfnHXnxURF0eiD+s 51nKBtnSkRcCAwEAAaOBzTCByjAdBgNVHQ4EFgQULih6jYTJ3XNDs53KSVwt4F9G 2agwgZoGA1UdIwSBkjCBj4AULih6jYTJ3XNDs53KSVwt4F9G2aihbKRqMGgxCzAJ BgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxl IENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZp Y2F0ZYIJAJq7aJgm4De9MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEA g+rrwZooo8DE47jmaBX+vUJBIVgSKdB45bDkL7FgTca2h1tsmgUL9nFyvp9FDEQ7 IYw5599ywhrQf9GfsIZ374G7ie9C8JqURbdiP4/MMvOjV1RzyypXByfaY20tDwgz 6JlLs7snh7O3s93FKpWhCjHE434CJwa1q5nHqNTgkZw= -----END CERTIFICATE----- omniauth-saml-1.7.0/spec/support/example_key.pem000066400000000000000000000015671300171045600217570ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQDPCDpFqSF/puiHkTbO970unp1KMxN2smEVDVZFnAw59E7sY8P1 ztF62fG49uDo/IF9J0WgYIm8yzAMkxrsNkCVuCx/VbI7D2BofOB/iPv1eUWmKzdc olfyLW9THERVbulitRMlTTFtnvmXcBe1+cdefFREXR6IP6znWcoG2dKRFwIDAQAB AoGBAItafWbARkUXQvNlgl/jj5qetz7njFVcEk7KUGTAedZUpP8m1BNTp9sqcjNP MeqBdGOamJowAOZsWiZMqlWO2v71qc2rQI+VmPR0xpmBvbBjL16Gc4BbTdXZ1o1T tPHQO90GG2JIIt8on4Tt5uVZ+h2cKAqn8k3phRWrfyaGndmhAkEA9BZnGP3Dh1gG dK8ZWi8KyJUW3BizNudkbfMW3e/cdaQ7DRidiJ8C2W9hVjwDMee3LM/la4lYzG8c iWVoovBBhwJBANki3CZQh5UTTHCHn2O5p6m+nHjQ8Io8jjDhBpQ9eJzlOyTMiYAB XMhqFMgtlkIlYGSaNysHlhCS9cW3Tw2gV/ECQAOhnbEKfXEzBw2PWVI1JvTq+ucV Wv0zHhRgrHNq0R3S7qn4NsfEjddMR+dvhyCj8N6yzRf3eCG6eXM11gOujVsCQQCF P+lN8fliOJeeLvxXXKVRe9HWKpKSopq30EATVK3hyqLC8GopDaz8qGzcc21UZk+D LUhRtbQXs7fzf4yZ1h5hAkBZoR45A2DNHLcAjR6XIg7B6/bZOj3wZLxyaoSYRgK3 nLDigtGmCiMg+DXsaBihyjiQVRskiuPbDktmigbAyyOS -----END RSA PRIVATE KEY----- omniauth-saml-1.7.0/spec/support/example_logout_request.xml000066400000000000000000000006661300171045600242660ustar00rootroot00000000000000 https://idp.sso.example.com/metadata/29490 username@example.com omniauth-saml-1.7.0/spec/support/example_logout_response.xml000066400000000000000000000011311300171045600244200ustar00rootroot00000000000000 https://idp.sso.example.com/metadata/29490 Successfully logged out from service omniauth-saml-1.7.0/spec/support/example_response.xml000066400000000000000000000150111300171045600230310ustar00rootroot00000000000000http://localhost:9000/saml2/idp/metadata.php WSulGKooo1K7yYnKfXy88BRqgXM=N8G4Meh60EnU5U113JH3fHEr3nA+87kemKZDkqfEZnGHrfwfO2KhSbKEsU6M1ELq8ZCNDxYCFhbfwJOWij5+qkMD1gMYqvH2Hz169l5smEAfkmtovJwq+2lVO7AtVLez065rx2g+n2DmZx82H3ynrMV0vTDEQ2AohJPZjsRoNgY= MIIDHDCCAoWgAwIBAgIJAJq7aJgm4De9MA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTAeFw0xMjExMDgyMDI5NTFaFw0xMjEyMDgyMDI5NTFaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzwg6Rakhf6boh5E2zve9Lp6dSjMTdrJhFQ1WRZwMOfRO7GPD9c7RetnxuPbg6PyBfSdFoGCJvMswDJMa7DZAlbgsf1WyOw9gaHzgf4j79XlFpis3XKJX8i1vUxxEVW7pYrUTJU0xbZ75l3AXtfnHXnxURF0eiD+s51nKBtnSkRcCAwEAAaOBzTCByjAdBgNVHQ4EFgQULih6jYTJ3XNDs53KSVwt4F9G2agwgZoGA1UdIwSBkjCBj4AULih6jYTJ3XNDs53KSVwt4F9G2aihbKRqMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZYIJAJq7aJgm4De9MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAg+rrwZooo8DE47jmaBX+vUJBIVgSKdB45bDkL7FgTca2h1tsmgUL9nFyvp9FDEQ7IYw5599ywhrQf9GfsIZ374G7ie9C8JqURbdiP4/MMvOjV1RzyypXByfaY20tDwgz6JlLs7snh7O3s93FKpWhCjHE434CJwa1q5nHqNTgkZw=http://localhost:9000/saml2/idp/metadata.php 20g3ohE5p7icP5ZQ3CSRkSpGaME=m9+Hq+RDNJyKWGsqCpqmkXt/6dz/NQUkdzeF5YHSezVuLFJajB+QC2aSeyic5H5Z0LBkQscjZ1sgme7Hyeo+ZvBgDrBejP6bZfMyaNrET6JTKXxXnrSI0txEL7oXGgnWLJX+oTUWLJgO+PHAUGeS9AgbKcBTQjaW7aW8uh4WtJg= MIIDHDCCAoWgAwIBAgIJAJq7aJgm4De9MA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTAeFw0xMjExMDgyMDI5NTFaFw0xMjEyMDgyMDI5NTFaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzwg6Rakhf6boh5E2zve9Lp6dSjMTdrJhFQ1WRZwMOfRO7GPD9c7RetnxuPbg6PyBfSdFoGCJvMswDJMa7DZAlbgsf1WyOw9gaHzgf4j79XlFpis3XKJX8i1vUxxEVW7pYrUTJU0xbZ75l3AXtfnHXnxURF0eiD+s51nKBtnSkRcCAwEAAaOBzTCByjAdBgNVHQ4EFgQULih6jYTJ3XNDs53KSVwt4F9G2agwgZoGA1UdIwSBkjCBj4AULih6jYTJ3XNDs53KSVwt4F9G2aihbKRqMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZYIJAJq7aJgm4De9MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAg+rrwZooo8DE47jmaBX+vUJBIVgSKdB45bDkL7FgTca2h1tsmgUL9nFyvp9FDEQ7IYw5599ywhrQf9GfsIZ374G7ie9C8JqURbdiP4/MMvOjV1RzyypXByfaY20tDwgz6JlLs7snh7O3s93FKpWhCjHE434CJwa1q5nHqNTgkZw=_1f6fcf6be5e13b08b1e3610e7ff59f205fbd814f23sample-saml-strategyurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordRajivManglaniuser@example.comExample Company omniauth-saml-1.7.0/spec/support/invalid_signature.xml000066400000000000000000000150111300171045600231670ustar00rootroot00000000000000http://localhost:9000/saml2/idp/metadata.php WSulGKooo1K7yYnKfXy88BRqgXM=AAAAAeh60EnU5U113JH3fHEr3nA+87kemKZDkqfEZnGHrfwfO2KhSbKEsU6M1ELq8ZCNDxYCFhbfwJOWij5+qkMD1gMYqvH2Hz169l5smEAfkmtovJwq+2lVO7AtVLez065rx2g+n2DmZx82H3ynrMV0vTDEQ2AohJPZjsRoNgY= MIIDHDCCAoWgAwIBAgIJAJq7aJgm4De9MA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTAeFw0xMjExMDgyMDI5NTFaFw0xMjEyMDgyMDI5NTFaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzwg6Rakhf6boh5E2zve9Lp6dSjMTdrJhFQ1WRZwMOfRO7GPD9c7RetnxuPbg6PyBfSdFoGCJvMswDJMa7DZAlbgsf1WyOw9gaHzgf4j79XlFpis3XKJX8i1vUxxEVW7pYrUTJU0xbZ75l3AXtfnHXnxURF0eiD+s51nKBtnSkRcCAwEAAaOBzTCByjAdBgNVHQ4EFgQULih6jYTJ3XNDs53KSVwt4F9G2agwgZoGA1UdIwSBkjCBj4AULih6jYTJ3XNDs53KSVwt4F9G2aihbKRqMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZYIJAJq7aJgm4De9MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAg+rrwZooo8DE47jmaBX+vUJBIVgSKdB45bDkL7FgTca2h1tsmgUL9nFyvp9FDEQ7IYw5599ywhrQf9GfsIZ374G7ie9C8JqURbdiP4/MMvOjV1RzyypXByfaY20tDwgz6JlLs7snh7O3s93FKpWhCjHE434CJwa1q5nHqNTgkZw=http://localhost:9000/saml2/idp/metadata.php 20g3ohE5p7icP5ZQ3CSRkSpGaME=m9+Hq+RDNJyKWGsqCpqmkXt/6dz/NQUkdzeF5YHSezVuLFJajB+QC2aSeyic5H5Z0LBkQscjZ1sgme7Hyeo+ZvBgDrBejP6bZfMyaNrET6JTKXxXnrSI0txEL7oXGgnWLJX+oTUWLJgO+PHAUGeS9AgbKcBTQjaW7aW8uh4WtJg= MIIDHDCCAoWgAwIBAgIJAJq7aJgm4De9MA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTAeFw0xMjExMDgyMDI5NTFaFw0xMjEyMDgyMDI5NTFaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzwg6Rakhf6boh5E2zve9Lp6dSjMTdrJhFQ1WRZwMOfRO7GPD9c7RetnxuPbg6PyBfSdFoGCJvMswDJMa7DZAlbgsf1WyOw9gaHzgf4j79XlFpis3XKJX8i1vUxxEVW7pYrUTJU0xbZ75l3AXtfnHXnxURF0eiD+s51nKBtnSkRcCAwEAAaOBzTCByjAdBgNVHQ4EFgQULih6jYTJ3XNDs53KSVwt4F9G2agwgZoGA1UdIwSBkjCBj4AULih6jYTJ3XNDs53KSVwt4F9G2aihbKRqMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZYIJAJq7aJgm4De9MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAg+rrwZooo8DE47jmaBX+vUJBIVgSKdB45bDkL7FgTca2h1tsmgUL9nFyvp9FDEQ7IYw5599ywhrQf9GfsIZ374G7ie9C8JqURbdiP4/MMvOjV1RzyypXByfaY20tDwgz6JlLs7snh7O3s93FKpWhCjHE434CJwa1q5nHqNTgkZw=_1f6fcf6be5e13b08b1e3610e7ff59f205fbd814f23sample-saml-strategyurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordRajivManglaniuser@example.comExample Company omniauth-saml-1.7.0/spec/support/no_name_id.xml000066400000000000000000000145721300171045600215630ustar00rootroot00000000000000http://localhost:9000/saml2/idp/metadata.php kzbCl9Y1eWJhqW5Z1a0N1hlrVuI=bdRjpQ1SVr0P/2CRQYK66yIoZ025TRqNN0Gb3rfTu3TiEs5cjsbT+ZAt0qbEekKFmI59TwR890L+81bPb80yQx+pPbSuPB1ull9RYE/UxSR/9mRKRuxFJpCbKxSu3t64TKEfPZp+VMkNxBmJ1GDMaZu1zkB3jVTmeIcmPKYppyo= MIIDHDCCAoWgAwIBAgIJAJq7aJgm4De9MA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTAeFw0xMjExMDgyMDI5NTFaFw0xMjEyMDgyMDI5NTFaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzwg6Rakhf6boh5E2zve9Lp6dSjMTdrJhFQ1WRZwMOfRO7GPD9c7RetnxuPbg6PyBfSdFoGCJvMswDJMa7DZAlbgsf1WyOw9gaHzgf4j79XlFpis3XKJX8i1vUxxEVW7pYrUTJU0xbZ75l3AXtfnHXnxURF0eiD+s51nKBtnSkRcCAwEAAaOBzTCByjAdBgNVHQ4EFgQULih6jYTJ3XNDs53KSVwt4F9G2agwgZoGA1UdIwSBkjCBj4AULih6jYTJ3XNDs53KSVwt4F9G2aihbKRqMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZYIJAJq7aJgm4De9MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAg+rrwZooo8DE47jmaBX+vUJBIVgSKdB45bDkL7FgTca2h1tsmgUL9nFyvp9FDEQ7IYw5599ywhrQf9GfsIZ374G7ie9C8JqURbdiP4/MMvOjV1RzyypXByfaY20tDwgz6JlLs7snh7O3s93FKpWhCjHE434CJwa1q5nHqNTgkZw=http://localhost:9000/saml2/idp/metadata.php 4m3lMEXWyVKoEfMSk8RdwvR1pdQ=THArdS1Zpjj5nC5VgvTkGiqmlYewIgYFBGrxmMPiBo7z3vaDpa7indkSyJZiJXV9BbzFKclHk8l75lLEYuw7G5zDsE+eJ7OmA1P7vOQ25hMk3z7nyUwf6VITLWuvbfE2Tfi39jzyr1LWolKwPL3QQMEUhPJG+UKX2Mtr/FHT+iU= MIIDHDCCAoWgAwIBAgIJAJq7aJgm4De9MA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTAeFw0xMjExMDgyMDI5NTFaFw0xMjEyMDgyMDI5NTFaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzwg6Rakhf6boh5E2zve9Lp6dSjMTdrJhFQ1WRZwMOfRO7GPD9c7RetnxuPbg6PyBfSdFoGCJvMswDJMa7DZAlbgsf1WyOw9gaHzgf4j79XlFpis3XKJX8i1vUxxEVW7pYrUTJU0xbZ75l3AXtfnHXnxURF0eiD+s51nKBtnSkRcCAwEAAaOBzTCByjAdBgNVHQ4EFgQULih6jYTJ3XNDs53KSVwt4F9G2agwgZoGA1UdIwSBkjCBj4AULih6jYTJ3XNDs53KSVwt4F9G2aihbKRqMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxKjAoBgNVBAMTIU9tbmlBdXRoIFNBTUwgVGVzdGluZyBDZXJ0aWZpY2F0ZYIJAJq7aJgm4De9MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAg+rrwZooo8DE47jmaBX+vUJBIVgSKdB45bDkL7FgTca2h1tsmgUL9nFyvp9FDEQ7IYw5599ywhrQf9GfsIZ374G7ie9C8JqURbdiP4/MMvOjV1RzyypXByfaY20tDwgz6JlLs7snh7O3s93FKpWhCjHE434CJwa1q5nHqNTgkZw=sample-saml-strategyurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordRajivManglaniuser@example.comExample Company