Commit 88f4350
Changed files (14)
lib
lib/saml/kit/builders/authentication_request.rb
@@ -6,7 +6,7 @@ module Saml
attr_accessor :version
def initialize(configuration: Saml::Kit.configuration, sign: true)
- @id = "_#{SecureRandom.uuid}"
+ @id = Id.generate
@issuer = configuration.issuer
@name_id_format = Namespaces::PERSISTENT
@now = Time.now.utc
lib/saml/kit/builders/identity_provider_metadata.rb
@@ -7,7 +7,7 @@ module Saml
attr_reader :logout_urls, :single_sign_on_urls
def initialize(configuration = Saml::Kit.configuration)
- @id = "_#{SecureRandom.uuid}"
+ @id = Id.generate
@entity_id = configuration.issuer
@attributes = []
@name_id_formats = [Namespaces::PERSISTENT]
lib/saml/kit/builders/logout_response.rb
@@ -9,7 +9,7 @@ module Saml
@user = user
@now = Time.now.utc
@request = request
- @id = "_#{SecureRandom.uuid}"
+ @id = Id.generate
@version = "2.0"
@status_code = Namespaces::SUCCESS
@sign = sign
lib/saml/kit/builders/response.rb
@@ -10,8 +10,8 @@ module Saml
def initialize(user, request)
@user = user
@request = request
- @id = "_#{SecureRandom.uuid}"
- @reference_id = "_#{SecureRandom.uuid}"
+ @id = Id.generate
+ @reference_id = Id.generate
@now = Time.now.utc
@version = "2.0"
@status_code = Namespaces::SUCCESS
lib/saml/kit/builders/service_provider_metadata.rb
@@ -6,7 +6,7 @@ module Saml
attr_accessor :want_assertions_signed
def initialize(configuration = Saml::Kit.configuration)
- @id = "_#{SecureRandom.uuid}"
+ @id = Id.generate
@configuration = configuration
@entity_id = configuration.issuer
@acs_urls = []
lib/saml/kit/id.rb
@@ -0,0 +1,9 @@
+module Saml
+ module Kit
+ class Id
+ def self.generate
+ "_#{SecureRandom.uuid}"
+ end
+ end
+ end
+end
lib/saml/kit.rb
@@ -36,6 +36,7 @@ require "saml/kit/logout_response"
require "saml/kit/logout_request"
require "saml/kit/metadata"
require "saml/kit/response"
+require "saml/kit/id"
require "saml/kit/identity_provider_metadata"
require "saml/kit/invalid_document"
require "saml/kit/self_signed_certificate"
spec/saml/builders/logout_request_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Saml::Kit::Builders::LogoutRequest do
it 'produces the expected xml' do
travel_to 1.second.from_now
- subject.id = "_#{SecureRandom.uuid}"
+ subject.id = Saml::Kit::Id.generate
subject.destination = FFaker::Internet.http_url
subject.issuer = FFaker::Internet.http_url
subject.name_id_format = Saml::Kit::Namespaces::TRANSIENT
spec/saml/builders/response_spec.rb
@@ -5,7 +5,7 @@ RSpec.describe Saml::Kit::Builders::Response do
let(:email) { FFaker::Internet.email }
let(:assertion_consumer_service_url) { FFaker::Internet.uri("https") }
let(:user) { double(:user, name_id_for: SecureRandom.uuid, assertion_attributes_for: { email: email, created_at: Time.now.utc.iso8601 }) }
- let(:request) { double(:request, id: "_#{SecureRandom.uuid}", assertion_consumer_service_url: assertion_consumer_service_url, issuer: issuer, name_id_format: Saml::Kit::Namespaces::EMAIL_ADDRESS, provider: provider, trusted?: true, signed?: true) }
+ let(:request) { double(:request, id: Saml::Kit::Id.generate, assertion_consumer_service_url: assertion_consumer_service_url, issuer: issuer, name_id_format: Saml::Kit::Namespaces::EMAIL_ADDRESS, provider: provider, trusted?: true, signed?: true) }
let(:provider) { double(want_assertions_signed: false, encryption_certificates: [Saml::Kit::Certificate.new(encryption_pem, use: :encryption)]) }
let(:encryption_pem) { Saml::Kit.configuration.stripped_encryption_certificate }
let(:issuer) { FFaker::Internet.uri("https") }
spec/saml/authentication_request_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
RSpec.describe Saml::Kit::AuthenticationRequest do
subject { described_class.new(raw_xml) }
- let(:id) { "_#{SecureRandom.uuid}" }
+ let(:id) { Saml::Kit::Id.generate }
let(:assertion_consumer_service_url) { "https://#{FFaker::Internet.domain_name}/acs" }
let(:issuer) { FFaker::Movie.title }
let(:destination) { FFaker::Internet.http_url }
@@ -77,7 +77,7 @@ RSpec.describe Saml::Kit::AuthenticationRequest do
end
it 'validates the schema of the request' do
- id = "_#{SecureRandom.uuid}"
+ id = Saml::Kit::Id.generate
signed_xml = Saml::Kit::Signature.sign(sign: true) do |xml, signature|
xml.tag!('samlp:AuthnRequest', "xmlns:samlp" => Saml::Kit::Namespaces::PROTOCOL, AssertionConsumerServiceURL: assertion_consumer_service_url, ID: id) do
signature.template(id)
@@ -92,7 +92,7 @@ RSpec.describe Saml::Kit::AuthenticationRequest do
it 'validates a request without a signature' do
now = Time.now.utc
raw_xml = <<-XML
-<samlp:AuthnRequest AssertionConsumerServiceURL='#{assertion_consumer_service_url}' ID='_#{SecureRandom.uuid}' IssueInstant='#{now.iso8601}' Version='2.0' xmlns:saml='#{Saml::Kit::Namespaces::ASSERTION}' xmlns:samlp='#{Saml::Kit::Namespaces::PROTOCOL}'>
+<samlp:AuthnRequest AssertionConsumerServiceURL='#{assertion_consumer_service_url}' ID='#{Saml::Kit::Id.generate}' IssueInstant='#{now.iso8601}' Version='2.0' xmlns:saml='#{Saml::Kit::Namespaces::ASSERTION}' xmlns:samlp='#{Saml::Kit::Namespaces::PROTOCOL}'>
<saml:Issuer>#{issuer}</saml:Issuer>
<samlp:NameIDPolicy AllowCreate='true' Format='#{Saml::Kit::Namespaces::EMAIL_ADDRESS}'/>
</samlp:AuthnRequest>
spec/saml/logout_request_spec.rb
@@ -107,7 +107,7 @@ RSpec.describe Saml::Kit::LogoutRequest do
end
it 'validates the schema of the request' do
- id = "_#{SecureRandom.uuid}"
+ id = Saml::Kit::Id.generate
signed_xml = Saml::Kit::Signature.sign(sign: true) do |xml, signature|
xml.LogoutRequest ID: id do
signature.template(id)
spec/saml/response_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
RSpec.describe Saml::Kit::Response do
describe "#valid?" do
- let(:request) { instance_double(Saml::Kit::AuthenticationRequest, id: "_#{SecureRandom.uuid}", issuer: FFaker::Internet.http_url, assertion_consumer_service_url: FFaker::Internet.http_url, name_id_format: Saml::Kit::Namespaces::PERSISTENT, provider: nil, signed?: true, trusted?: true) }
+ let(:request) { instance_double(Saml::Kit::AuthenticationRequest, id: Saml::Kit::Id.generate, issuer: FFaker::Internet.http_url, assertion_consumer_service_url: FFaker::Internet.http_url, name_id_format: Saml::Kit::Namespaces::PERSISTENT, provider: nil, signed?: true, trusted?: true) }
let(:user) { double(:user, name_id_for: SecureRandom.uuid, assertion_attributes_for: { id: SecureRandom.uuid }) }
let(:registry) { instance_double(Saml::Kit::DefaultRegistry) }
let(:metadata) { instance_double(Saml::Kit::IdentityProviderMetadata) }
@@ -54,7 +54,7 @@ RSpec.describe Saml::Kit::Response do
it 'validates the schema of the response' do
allow(registry).to receive(:metadata_for).and_return(metadata)
allow(metadata).to receive(:matches?).and_return(true)
- id = "_#{SecureRandom.uuid}"
+ id = Saml::Kit::Id.generate
signed_xml = Saml::Kit::Signature.sign(sign: true) do |xml, signature|
xml.tag! "samlp:Response", "xmlns:samlp" => Saml::Kit::Namespaces::PROTOCOL, ID: id do
signature.template(id)
@@ -144,7 +144,7 @@ RSpec.describe Saml::Kit::Response do
destination = FFaker::Internet.uri("https")
raw_xml = <<-XML
<?xml version="1.0"?>
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="_#{SecureRandom.uuid}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{destination}" Consent="#{Saml::Kit::Namespaces::UNSPECIFIED}" InResponseTo="#{request.id}">
+<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{Saml::Kit::Id.generate}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{destination}" Consent="#{Saml::Kit::Namespaces::UNSPECIFIED}" InResponseTo="#{request.id}">
<Issuer xmlns="#{Saml::Kit::Namespaces::ASSERTION}">#{request.issuer}</Issuer>
<samlp:Status>
<samlp:StatusCode Value="#{Saml::Kit::Namespaces::RESPONDER_ERROR}"/>
@@ -160,19 +160,19 @@ RSpec.describe Saml::Kit::Response do
describe "#signed?" do
let(:now) { Time.now.utc }
- let(:id) { SecureRandom.uuid }
+ let(:id) { Saml::Kit::Id.generate }
let(:url) { FFaker::Internet.uri("https") }
it 'returns true when the Assertion is signed' do
xml = <<-XML
<?xml version="1.0"?>
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="_#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
- <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="_#{id}" IssueInstant="#{now.iso8601}" Version="2.0">
+<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
- <ds:Reference URI="#_#{id}">
+ <ds:Reference URI="##{id}">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
@@ -198,12 +198,12 @@ RSpec.describe Saml::Kit::Response do
it 'returns true when the Response is signed' do
xml = <<-XML
<?xml version="1.0"?>
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="_#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
+<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
- <ds:Reference URI="#_#{id}">
+ <ds:Reference URI="##{id}">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
@@ -219,7 +219,7 @@ RSpec.describe Saml::Kit::Response do
</ds:X509Data>
</KeyInfo>
</ds:Signature>
- <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="_#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
</samlp:Response>
XML
subject = described_class.new(xml)
@@ -229,8 +229,8 @@ RSpec.describe Saml::Kit::Response do
it 'returns false when there is no signature' do
xml = <<-XML
<?xml version="1.0"?>
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="_#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
- <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="_#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
+<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
</samlp:Response>
XML
subject = described_class.new(xml)
@@ -240,20 +240,20 @@ RSpec.describe Saml::Kit::Response do
describe "#certificate" do
let(:now) { Time.now.utc }
- let(:id) { SecureRandom.uuid }
+ let(:id) { Saml::Kit::Id.generate }
let(:url) { FFaker::Internet.uri("https") }
let(:certificate) { FFaker::Movie.title }
it 'returns the certificate when the Assertion is signed' do
xml = <<-XML
<?xml version="1.0"?>
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="_#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
- <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="_#{id}" IssueInstant="#{now.iso8601}" Version="2.0">
+<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
- <ds:Reference URI="#_#{id}">
+ <ds:Reference URI="##{id}">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
@@ -279,12 +279,12 @@ RSpec.describe Saml::Kit::Response do
it 'returns the certificate when the Response is signed' do
xml = <<-XML
<?xml version="1.0"?>
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="_#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
+<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
- <ds:Reference URI="#_#{id}">
+ <ds:Reference URI="##{id}">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
@@ -300,7 +300,7 @@ RSpec.describe Saml::Kit::Response do
</ds:X509Data>
</KeyInfo>
</ds:Signature>
- <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="_#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
</samlp:Response>
XML
subject = described_class.new(xml)
@@ -310,8 +310,8 @@ RSpec.describe Saml::Kit::Response do
it 'returns nil when there is no signature' do
xml = <<-XML
<?xml version="1.0"?>
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="_#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
- <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="_#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
+<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{url}" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_#{SecureRandom.uuid}">
+ <Assertion xmlns="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" IssueInstant="#{now.iso8601}" Version="2.0"></Assertion>
</samlp:Response>
XML
subject = described_class.new(xml)
@@ -320,14 +320,14 @@ RSpec.describe Saml::Kit::Response do
end
describe "encrypted assertion" do
- let(:id) { SecureRandom.uuid }
+ let(:id) { Saml::Kit::Id.generate }
let(:now) { Time.now.utc }
let(:assertion_consumer_service_url) { FFaker::Internet.uri("https") }
let(:password) { FFaker::Movie.title }
let(:assertion) do
FFaker::Movie.title
<<-XML
-<Assertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion" ID="_11d39a7f-1b86-43ed-90d7-68090a857ca8" IssueInstant="2017-11-23T04:33:58Z" Version="2.0">
+<Assertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion" ID="#{id}" IssueInstant="2017-11-23T04:33:58Z" Version="2.0">
<Issuer>#{FFaker::Internet.uri("https")}</Issuer>
<Subject>
<NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">fdddf7ad-c4a4-443c-b96d-c953913b7b4e</NameID>
@@ -371,7 +371,7 @@ XML
encrypted = cipher.update(assertion) + cipher.final
xml = <<-XML
-<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" xmlns:saml="#{Saml::Kit::Namespaces::ASSERTION}" ID="_#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{assertion_consumer_service_url}" InResponseTo="_#{SecureRandom.uuid}">
+<samlp:Response xmlns:samlp="#{Saml::Kit::Namespaces::PROTOCOL}" xmlns:saml="#{Saml::Kit::Namespaces::ASSERTION}" ID="#{id}" Version="2.0" IssueInstant="#{now.iso8601}" Destination="#{assertion_consumer_service_url}" InResponseTo="#{Saml::Kit::Id.generate}">
<saml:Issuer>#{FFaker::Internet.uri("https")}</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="#{Saml::Kit::Namespaces::SUCCESS}"/>
spec/saml/service_provider_metadata_spec.rb
@@ -101,7 +101,7 @@ RSpec.describe Saml::Kit::ServiceProviderMetadata do
it 'is invalid when 0 ACS endpoints are specified' do
xml = <<-XML
<?xml version="1.0" encoding="UTF-8"?>
-<EntityDescriptor xmlns="#{Saml::Kit::Namespaces::METADATA}" ID="_#{SecureRandom.uuid}" entityID="#{entity_id}">
+<EntityDescriptor xmlns="#{Saml::Kit::Namespaces::METADATA}" ID="#{Saml::Kit::Id.generate}" entityID="#{entity_id}">
<SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="#{Saml::Kit::Namespaces::PROTOCOL}">
<SingleLogoutService Binding="#{Saml::Kit::Bindings::HTTP_POST}" Location="#{FFaker::Internet.uri("https")}"/>
<NameIDFormat>#{Saml::Kit::Namespaces::PERSISTENT}</NameIDFormat>
spec/saml/signature_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe Saml::Kit::Signature do
config
end
- let(:reference_id) { "_#{SecureRandom.uuid}" }
+ let(:reference_id) { Saml::Kit::Id.generate }
let(:rsa_key) { OpenSSL::PKey::RSA.new(2048) }
let(:public_key) { rsa_key.public_key }
let(:certificate) do