saml_idp 0.7.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Gemfile +1 -1
- data/README.md +41 -13
- data/lib/saml_idp/configurator.rb +5 -1
- data/lib/saml_idp/controller.rb +9 -5
- data/lib/saml_idp/incoming_metadata.rb +22 -1
- data/lib/saml_idp/metadata_builder.rb +23 -8
- data/lib/saml_idp/persisted_metadata.rb +4 -0
- data/lib/saml_idp/request.rb +22 -3
- data/lib/saml_idp/response_builder.rb +19 -5
- data/lib/saml_idp/saml_response.rb +15 -3
- data/lib/saml_idp/service_provider.rb +15 -6
- data/lib/saml_idp/signable.rb +1 -2
- data/lib/saml_idp/version.rb +1 -1
- data/lib/saml_idp/xml_security.rb +1 -1
- data/saml_idp.gemspec +25 -23
- data/spec/acceptance/idp_controller_spec.rb +5 -4
- data/spec/lib/saml_idp/algorithmable_spec.rb +6 -6
- data/spec/lib/saml_idp/assertion_builder_spec.rb +8 -8
- data/spec/lib/saml_idp/attribute_decorator_spec.rb +8 -8
- data/spec/lib/saml_idp/configurator_spec.rb +8 -7
- data/spec/lib/saml_idp/controller_spec.rb +47 -20
- data/spec/lib/saml_idp/encryptor_spec.rb +4 -4
- data/spec/lib/saml_idp/incoming_metadata_spec.rb +60 -0
- data/spec/lib/saml_idp/metadata_builder_spec.rb +30 -17
- data/spec/lib/saml_idp/name_id_formatter_spec.rb +3 -3
- data/spec/lib/saml_idp/request_spec.rb +22 -22
- data/spec/lib/saml_idp/response_builder_spec.rb +5 -3
- data/spec/lib/saml_idp/saml_response_spec.rb +31 -8
- data/spec/lib/saml_idp/service_provider_spec.rb +2 -2
- data/spec/lib/saml_idp/signable_spec.rb +1 -1
- data/spec/lib/saml_idp/signature_builder_spec.rb +2 -2
- data/spec/lib/saml_idp/signed_info_builder_spec.rb +3 -3
- data/spec/rails_app/app/controllers/saml_controller.rb +5 -1
- data/spec/rails_app/config/application.rb +0 -6
- data/spec/rails_app/config/environments/development.rb +1 -6
- data/spec/rails_app/config/environments/production.rb +1 -0
- data/spec/rails_app/config/environments/test.rb +1 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/certificates/sp_cert_req.csr +12 -0
- data/spec/support/certificates/sp_private_key.pem +16 -0
- data/spec/support/certificates/sp_x509_cert.crt +18 -0
- data/spec/support/saml_request_macros.rb +64 -4
- data/spec/support/security_helpers.rb +10 -0
- data/spec/xml_security_spec.rb +12 -12
- metadata +89 -52
- data/spec/lib/saml_idp/.assertion_builder_spec.rb.swp +0 -0
@@ -9,11 +9,11 @@ module SamlIdp
|
|
9
9
|
) }
|
10
10
|
|
11
11
|
before do
|
12
|
-
Time.
|
12
|
+
allow(Time).to receive(:now).and_return Time.parse("Jul 31 2013")
|
13
13
|
end
|
14
14
|
|
15
15
|
it "builds a legit raw XML file" do
|
16
|
-
subject.raw.
|
16
|
+
expect(subject.raw).to eq("<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/2000/09/xmldsig#rsa-sha256\"/><ds:Reference URI=\"#_abc\"><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#\"/></ds:Transforms><ds:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha256\"/><ds:DigestValue>em8csGAWynywpe8S4nN64o56/4DosXi2XWMY6RJ6YfA=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>jvEbD/rsiPKmoXy7Lhm+FGn88NPGlap4EcPZ2fvjBnk03YESs87FXAIiZZEzN5xq4sBZksUmZe2bV3rrr9sxQNgQawmrrvr66ot7cJiv0ETFArr6kQIZaR5g/V0M4ydxvrfefp6cQVI0hXvmxi830pq0tISiO4J7tyBNX/kvhZk=</ds:SignatureValue><KeyInfo xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><ds:X509Data><ds:X509Certificate>MIIDqzCCAxSgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBhjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA05TVzEPMA0GA1UEBxMGU3lkbmV5MQwwCgYDVQQKDANQSVQxCTAHBgNVBAsMADEYMBYGA1UEAwwPbGF3cmVuY2VwaXQuY29tMSUwIwYJKoZIhvcNAQkBDBZsYXdyZW5jZS5waXRAZ21haWwuY29tMB4XDTEyMDQyODAyMjIyOFoXDTMyMDQyMzAyMjIyOFowgYYxCzAJBgNVBAYTAkFVMQwwCgYDVQQIEwNOU1cxDzANBgNVBAcTBlN5ZG5leTEMMAoGA1UECgwDUElUMQkwBwYDVQQLDAAxGDAWBgNVBAMMD2xhd3JlbmNlcGl0LmNvbTElMCMGCSqGSIb3DQEJAQwWbGF3cmVuY2UucGl0QGdtYWlsLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuBywPNlC1FopGLYfF96SotiK8Nj6/nW084O4omRMifzy7x955RLEy673q2aiJNB3LvE6Xvkt9cGtxtNoOXw1g2UvHKpldQbr6bOEjLNeDNW7j0ob+JrRvAUOK9CRgdyw5MC6lwqVQQ5C1DnaT/2fSBFjasBFTR24dEpfTy8HfKECAwEAAaOCASUwggEhMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgUgMB0GA1UdDgQWBBQNBGmmt3ytKpcJaBaYNbnyU2xkazATBgNVHSUEDDAKBggrBgEFBQcDATAdBglghkgBhvhCAQ0EEBYOVGVzdCBYNTA5IGNlcnQwgbMGA1UdIwSBqzCBqIAUDQRpprd8rSqXCWgWmDW58lNsZGuhgYykgYkwgYYxCzAJBgNVBAYTAkFVMQwwCgYDVQQIEwNOU1cxDzANBgNVBAcTBlN5ZG5leTEMMAoGA1UECgwDUElUMQkwBwYDVQQLDAAxGDAWBgNVBAMMD2xhd3JlbmNlcGl0LmNvbTElMCMGCSqGSIb3DQEJAQwWbGF3cmVuY2UucGl0QGdtYWlsLmNvbYIBATANBgkqhkiG9w0BAQsFAAOBgQAEcVUPBX7uZmzqZJfy+tUPOT5ImNQj8VE2lerhnFjnGPHmHIqhpzgnwHQujJfs/a309Wm5qwcCaC1eO5cWjcG0x3OjdllsgYDatl5GAumtBx8J3NhWRqNUgitCIkQlxHIwUfgQaCushYgDDL5YbIQa++egCgpIZ+T0Dj5oRew//A==</ds:X509Certificate></ds:X509Data></KeyInfo></ds:Signature>")
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -11,15 +11,15 @@ module SamlIdp
|
|
11
11
|
) }
|
12
12
|
|
13
13
|
before do
|
14
|
-
Time.
|
14
|
+
allow(Time).to receive(:now).and_return Time.parse("Jul 31 2013")
|
15
15
|
end
|
16
16
|
|
17
17
|
it "builds a legit raw XML file" do
|
18
|
-
subject.raw.
|
18
|
+
expect(subject.raw).to eq("<ds:SignedInfo xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\"><ds:CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm=\"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256\"></ds:SignatureMethod><ds:Reference URI=\"#_abc\"><ds:Transforms><ds:Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\"></ds:Transform><ds:Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#sha256\"></ds:DigestMethod><ds:DigestValue>em8csGAWynywpe8S4nN64o56/4DosXi2XWMY6RJ6YfA=</ds:DigestValue></ds:Reference></ds:SignedInfo>")
|
19
19
|
end
|
20
20
|
|
21
21
|
it "builds a legit digest of the XML file" do
|
22
|
-
subject.signed.
|
22
|
+
expect(subject.signed).to eq("hKLeWLRgatHcV6N5Fc8aKveqNp6Y/J4m2WSYp0awGFtsCTa/2nab32wI3du+3kuuIy59EDKeUhHVxEfyhoHUo6xTZuO2N7XcTpSonuZ/CB3WjozC2Q/9elss3z1rOC3154v5pW4puirLPRoG+Pwi8SmptxNRHczr6NvmfYmmGfo=")
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -2,7 +2,11 @@ class SamlController < ApplicationController
|
|
2
2
|
|
3
3
|
def consume
|
4
4
|
response = OneLogin::RubySaml::Response.new(params[:SAMLResponse])
|
5
|
-
|
5
|
+
if Gem::Requirement.new('< 4.1') =~ Gem::Version.new(Rails.version)
|
6
|
+
render :text => response.name_id
|
7
|
+
else
|
8
|
+
render :plain => response.name_id
|
9
|
+
end
|
6
10
|
end
|
7
11
|
|
8
12
|
end
|
@@ -50,11 +50,5 @@ module RailsApp
|
|
50
50
|
# in your app. As such, your models will need to explicitly whitelist or blacklist accessible
|
51
51
|
# parameters by using an attr_accessible or attr_protected declaration.
|
52
52
|
# config.active_record.whitelist_attributes = true
|
53
|
-
|
54
|
-
# Enable the asset pipeline
|
55
|
-
config.assets.enabled = true
|
56
|
-
|
57
|
-
# Version of your assets, change this if you want to expire all your assets
|
58
|
-
config.assets.version = '1.0'
|
59
53
|
end
|
60
54
|
end
|
@@ -4,6 +4,7 @@ RailsApp::Application.configure do
|
|
4
4
|
# In the development environment your application's code is reloaded on
|
5
5
|
# every request. This slows down response time but is perfect for development
|
6
6
|
# since you don't have to restart the web server when you make code changes.
|
7
|
+
config.eager_load = false if config.respond_to?(:eager_load)
|
7
8
|
config.cache_classes = false
|
8
9
|
|
9
10
|
# Log error messages when you accidentally call methods on nil.
|
@@ -28,10 +29,4 @@ RailsApp::Application.configure do
|
|
28
29
|
# Log the query plan for queries taking more than this (works
|
29
30
|
# with SQLite, MySQL, and PostgreSQL)
|
30
31
|
#config.active_record.auto_explain_threshold_in_seconds = 0.5
|
31
|
-
|
32
|
-
# Do not compress assets
|
33
|
-
config.assets.compress = false
|
34
|
-
|
35
|
-
# Expands the lines which load the assets
|
36
|
-
config.assets.debug = true
|
37
32
|
end
|
@@ -2,6 +2,7 @@ RailsApp::Application.configure do
|
|
2
2
|
# Settings specified here will take precedence over those in config/application.rb
|
3
3
|
|
4
4
|
# Code is not reloaded between requests
|
5
|
+
config.eager_load = true if config.respond_to?(:eager_load)
|
5
6
|
config.cache_classes = true
|
6
7
|
|
7
8
|
# Full error reports are disabled and caching is turned on
|
@@ -5,6 +5,7 @@ RailsApp::Application.configure do
|
|
5
5
|
# test suite. You never need to work with it otherwise. Remember that
|
6
6
|
# your test database is "scratch space" for the test suite and is wiped
|
7
7
|
# and recreated between test runs. Don't rely on the data there!
|
8
|
+
config.eager_load = true if config.respond_to?(:eager_load)
|
8
9
|
config.cache_classes = true
|
9
10
|
|
10
11
|
# Configure static asset server for tests with Cache-Control for performance
|
data/spec/spec_helper.rb
CHANGED
@@ -43,6 +43,28 @@ RSpec.configure do |config|
|
|
43
43
|
}
|
44
44
|
end
|
45
45
|
end
|
46
|
+
|
47
|
+
# To reset to default config
|
48
|
+
config.after do
|
49
|
+
SamlIdp.instance_variable_set(:@config, nil)
|
50
|
+
SamlIdp.configure do |c|
|
51
|
+
c.attributes = {
|
52
|
+
emailAddress: {
|
53
|
+
name: "email-address",
|
54
|
+
getter: ->(p) { "foo@example.com" }
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
c.name_id.formats = {
|
59
|
+
"1.1" => {
|
60
|
+
email_address: ->(p) { "foo@example.com" }
|
61
|
+
}
|
62
|
+
}
|
63
|
+
end
|
64
|
+
end
|
46
65
|
end
|
47
66
|
|
67
|
+
SamlIdp::Default::SERVICE_PROVIDER[:metadata_url] = 'https://example.com/meta'
|
68
|
+
SamlIdp::Default::SERVICE_PROVIDER[:response_hosts] = ['foo.example.com']
|
69
|
+
SamlIdp::Default::SERVICE_PROVIDER[:assertion_consumer_logout_service_url] = 'https://foo.example.com/saml/logout'
|
48
70
|
Capybara.default_host = "https://app.example.com"
|
@@ -0,0 +1,12 @@
|
|
1
|
+
-----BEGIN CERTIFICATE REQUEST-----
|
2
|
+
MIIByTCCATICAQAwgYgxCzAJBgNVBAYTAmpwMQ4wDAYDVQQIDAVUb2t5bzELMAkG
|
3
|
+
A1UECgwCR1MxIDAeBgNVBAMMF2h0dHBzOi8vZm9vLmV4YW1wbGUuY29tMQwwCgYD
|
4
|
+
VQQHDANGb28xDDAKBgNVBAsMA0JvbzEeMBwGCSqGSIb3DQEJARYPZm9vQGV4YW1w
|
5
|
+
bGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8DVj2mVLQV7AjT+cn
|
6
|
+
Lv3kDnQFvAo3RdUeGGhplsYFacYByzNRD/jeguu1ahrvznDyZN8p3yB7OPbmt0r0
|
7
|
+
aGr+yYzPh6brgkf5u6FMtWTj94vLQuT/uyQGuzdBkiLb5mAWRMtm43oHXDK0v25J
|
8
|
+
tsG1PJnntkXfBDpFP1eWLO+jZwIDAQABoAAwDQYJKoZIhvcNAQENBQADgYEAd/J6
|
9
|
+
5zjrMhgjxuaMuWCiNN7IS4F9SKy+gEmhkpNVCpChbpggruaEIoERjDP/TkZn2dgL
|
10
|
+
VUeHTZB92t+wWfQbHNvEfbzqlV3XkuHkxewCwofnIV/k+8zG1Al5ELSKHehItxig
|
11
|
+
rnTuBrFYsd2j4HEVqLzm4NyCfL+xzn/D4U2ec50=
|
12
|
+
-----END CERTIFICATE REQUEST-----
|
@@ -0,0 +1,16 @@
|
|
1
|
+
-----BEGIN PRIVATE KEY-----
|
2
|
+
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALwNWPaZUtBXsCNP
|
3
|
+
5ycu/eQOdAW8CjdF1R4YaGmWxgVpxgHLM1EP+N6C67VqGu/OcPJk3ynfIHs49ua3
|
4
|
+
SvRoav7JjM+HpuuCR/m7oUy1ZOP3i8tC5P+7JAa7N0GSItvmYBZEy2bjegdcMrS/
|
5
|
+
bkm2wbU8mee2Rd8EOkU/V5Ys76NnAgMBAAECgYEArwclVHCkebIECPnnxbqhKNCj
|
6
|
+
AGtifsuKbrZ9CDoDGSq31xeQLdTV6BSm2nVlmOnmilWEuG4qx0Xf2CGlrBI78kmv
|
7
|
+
vHCfFdaGnTxbmYnD0HN0u4RK2trsxWO+rEkJk14JE2eVD6ZRPrq1UOSMgGPrQSMb
|
8
|
+
SuwAHUu/j94eL8BXuhECQQD3jTlo3Y4VPWttP6XPNqKDP+jRYJs5G0Bch//S9Qy7
|
9
|
+
QzmU9/yAUk0BEOyqYcLxinjJhoq6bR2fiIibn+77z3jtAkEAwnhLwkGYOb7Nt3V6
|
10
|
+
dQLKx1BP9dnYH7qG/sCmAs7GHPv4LGluaz4zsh2pdEDF/Xar4gwTzUpxYo8FpkCH
|
11
|
+
rf4nIwJAVfWnGr/cR4nVVNFGHUcGdXbqvFHEdLb+yWK8NZ+79Qap5w2Zk2GAtb8P
|
12
|
+
vzZFQCRqPuhGIegj4jLB5PBLRwtLHQJBAJiWyWL4ExikRUhBTr/HXBL+Sm9u6i0j
|
13
|
+
L89unBQx6LNPZhB6/Z/6Y5fLvG2ycWgLGJ06usLnOYaLEHS9x3hXpp8CQQCdtQHw
|
14
|
+
xeLBPhRDpfWWbSmFr+bFxyD/4iQHTHToIs3kaecn6OJ4rczIFpGm2Bm7f4X7F3H3
|
15
|
+
DDy4jZ0R6iDqCcQD
|
16
|
+
-----END PRIVATE KEY-----
|
@@ -0,0 +1,18 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIC2DCCAkGgAwIBAgIBADANBgkqhkiG9w0BAQ0FADCBiDELMAkGA1UEBhMCanAx
|
3
|
+
DjAMBgNVBAgMBVRva3lvMQswCQYDVQQKDAJHUzEgMB4GA1UEAwwXaHR0cHM6Ly9m
|
4
|
+
b28uZXhhbXBsZS5jb20xDDAKBgNVBAcMA0ZvbzEMMAoGA1UECwwDQm9vMR4wHAYJ
|
5
|
+
KoZIhvcNAQkBFg9mb29AZXhhbXBsZS5jb20wHhcNMjAwMTIzMDYyMzI5WhcNNDcw
|
6
|
+
NjA5MDYyMzI5WjCBiDELMAkGA1UEBhMCanAxDjAMBgNVBAgMBVRva3lvMQswCQYD
|
7
|
+
VQQKDAJHUzEgMB4GA1UEAwwXaHR0cHM6Ly9mb28uZXhhbXBsZS5jb20xDDAKBgNV
|
8
|
+
BAcMA0ZvbzEMMAoGA1UECwwDQm9vMR4wHAYJKoZIhvcNAQkBFg9mb29AZXhhbXBs
|
9
|
+
ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALwNWPaZUtBXsCNP5ycu
|
10
|
+
/eQOdAW8CjdF1R4YaGmWxgVpxgHLM1EP+N6C67VqGu/OcPJk3ynfIHs49ua3SvRo
|
11
|
+
av7JjM+HpuuCR/m7oUy1ZOP3i8tC5P+7JAa7N0GSItvmYBZEy2bjegdcMrS/bkm2
|
12
|
+
wbU8mee2Rd8EOkU/V5Ys76NnAgMBAAGjUDBOMB0GA1UdDgQWBBQMtOtrh2VS/mh4
|
13
|
+
awGbKA37vVnw+zAfBgNVHSMEGDAWgBQMtOtrh2VS/mh4awGbKA37vVnw+zAMBgNV
|
14
|
+
HRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAHjTTm4Hyx1rfzygknc6q1dYwpEv
|
15
|
+
/3AsPiTnF4AfH/5kGIIXNzwg0ADsziFMJYRRR9eMu97CHQbr8gHt99P8uaen6cmJ
|
16
|
+
4VCwJLP2N8gZrycssimA3M83DWRRVZbxZhpuUWNajtYIxwyUbB7eRSJgz3Tc0opF
|
17
|
+
933YwucWuFzKSqn3
|
18
|
+
-----END CERTIFICATE-----
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'saml_idp/logout_request_builder'
|
2
2
|
|
3
3
|
module SamlRequestMacros
|
4
|
-
def make_saml_request(requested_saml_acs_url = "https://foo.example.com/saml/consume")
|
4
|
+
def make_saml_request(requested_saml_acs_url = "https://foo.example.com/saml/consume", enable_secure_options = false)
|
5
5
|
auth_request = OneLogin::RubySaml::Authrequest.new
|
6
|
-
auth_url = auth_request.create(saml_settings(requested_saml_acs_url))
|
6
|
+
auth_url = auth_request.create(saml_settings(requested_saml_acs_url, enable_secure_options))
|
7
7
|
CGI.unescape(auth_url.split("=").last)
|
8
8
|
end
|
9
9
|
|
@@ -15,19 +15,79 @@ module SamlRequestMacros
|
|
15
15
|
'some_name_id',
|
16
16
|
OpenSSL::Digest::SHA256
|
17
17
|
)
|
18
|
-
request_builder.
|
18
|
+
Base64.strict_encode64(request_builder.signed)
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
21
|
+
def generate_sp_metadata(saml_acs_url = "https://foo.example.com/saml/consume", enable_secure_options = false)
|
22
|
+
sp_metadata = OneLogin::RubySaml::Metadata.new
|
23
|
+
sp_metadata.generate(saml_settings(saml_acs_url, enable_secure_options), true)
|
24
|
+
end
|
25
|
+
|
26
|
+
def saml_settings(saml_acs_url = "https://foo.example.com/saml/consume", enable_secure_options = false)
|
22
27
|
settings = OneLogin::RubySaml::Settings.new
|
23
28
|
settings.assertion_consumer_service_url = saml_acs_url
|
24
29
|
settings.issuer = "http://example.com/issuer"
|
25
30
|
settings.idp_sso_target_url = "http://idp.com/saml/idp"
|
31
|
+
settings.assertion_consumer_logout_service_url = 'https://foo.example.com/saml/logout'
|
26
32
|
settings.idp_cert_fingerprint = SamlIdp::Default::FINGERPRINT
|
27
33
|
settings.name_identifier_format = SamlIdp::Default::NAME_ID_FORMAT
|
34
|
+
add_securty_options(settings) if enable_secure_options
|
28
35
|
settings
|
29
36
|
end
|
30
37
|
|
38
|
+
def add_securty_options(settings, authn_requests_signed: true,
|
39
|
+
embed_sign: true,
|
40
|
+
logout_requests_signed: true,
|
41
|
+
logout_responses_signed: true,
|
42
|
+
digest_method: XMLSecurity::Document::SHA256,
|
43
|
+
signature_method: XMLSecurity::Document::RSA_SHA256)
|
44
|
+
# Security section
|
45
|
+
settings.idp_cert = SamlIdp::Default::X509_CERTIFICATE
|
46
|
+
# Signed embedded singature
|
47
|
+
settings.security[:authn_requests_signed] = authn_requests_signed
|
48
|
+
settings.security[:embed_sign] = embed_sign
|
49
|
+
settings.security[:logout_requests_signed] = logout_requests_signed
|
50
|
+
settings.security[:logout_responses_signed] = logout_responses_signed
|
51
|
+
settings.security[:metadata_signed] = digest_method
|
52
|
+
settings.security[:digest_method] = digest_method
|
53
|
+
settings.security[:signature_method] = signature_method
|
54
|
+
settings.private_key = sp_pv_key
|
55
|
+
settings.certificate = sp_x509_cert
|
56
|
+
end
|
57
|
+
|
58
|
+
def idp_configure(saml_acs_url = "https://foo.example.com/saml/consume", enable_secure_options = false)
|
59
|
+
SamlIdp.configure do |config|
|
60
|
+
config.x509_certificate = SamlIdp::Default::X509_CERTIFICATE
|
61
|
+
config.secret_key = SamlIdp::Default::SECRET_KEY
|
62
|
+
config.password = nil
|
63
|
+
config.algorithm = :sha256
|
64
|
+
config.organization_name = 'idp.com'
|
65
|
+
config.organization_url = 'http://idp.com'
|
66
|
+
config.base_saml_location = 'http://idp.com/saml/idp'
|
67
|
+
config.single_logout_service_post_location = 'http://idp.com/saml/idp/logout'
|
68
|
+
config.single_logout_service_redirect_location = 'http://idp.com/saml/idp/logout'
|
69
|
+
config.attribute_service_location = 'http://idp.com/saml/idp/attribute'
|
70
|
+
config.single_service_post_location = 'http://idp.com/saml/idp/sso'
|
71
|
+
config.name_id.formats = SamlIdp::Default::NAME_ID_FORMAT
|
72
|
+
config.service_provider.metadata_persister = lambda { |_identifier, _service_provider|
|
73
|
+
raw_metadata = generate_sp_metadata(saml_acs_url, enable_secure_options)
|
74
|
+
SamlIdp::IncomingMetadata.new(raw_metadata).to_h
|
75
|
+
}
|
76
|
+
config.service_provider.persisted_metadata_getter = lambda { |_identifier, _settings|
|
77
|
+
raw_metadata = generate_sp_metadata(saml_acs_url, enable_secure_options)
|
78
|
+
SamlIdp::IncomingMetadata.new(raw_metadata).to_h
|
79
|
+
}
|
80
|
+
config.service_provider.finder = lambda { |_issuer_or_entity_id|
|
81
|
+
{
|
82
|
+
response_hosts: [URI(saml_acs_url).host],
|
83
|
+
acs_url: saml_acs_url,
|
84
|
+
cert: sp_x509_cert,
|
85
|
+
fingerprint: Digest::SHA256.hexdigest(OpenSSL::X509::Certificate.new(sp_x509_cert).to_der).scan(/../).join(':')
|
86
|
+
}
|
87
|
+
}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
31
91
|
def print_pretty_xml(xml_string)
|
32
92
|
doc = REXML::Document.new xml_string
|
33
93
|
outbuf = ""
|
@@ -58,4 +58,14 @@ module SecurityHelpers
|
|
58
58
|
def r1_signature_2
|
59
59
|
@signature2 ||= File.read(File.join(File.dirname(__FILE__), 'certificates', 'r1_certificate2_base64'))
|
60
60
|
end
|
61
|
+
|
62
|
+
# Generated by SAML tool https://www.samltool.com/self_signed_certs.php
|
63
|
+
def sp_pv_key
|
64
|
+
@sp_pv_key ||= File.read(File.join(File.dirname(__FILE__), 'certificates', 'sp_private_key.pem'))
|
65
|
+
end
|
66
|
+
|
67
|
+
# Generated by SAML tool https://www.samltool.com/self_signed_certs.php, expired date is 9999
|
68
|
+
def sp_x509_cert
|
69
|
+
@sp_x509_cert ||= File.read(File.join(File.dirname(__FILE__), 'certificates', 'sp_x509_cert.crt'))
|
70
|
+
end
|
61
71
|
end
|
data/spec/xml_security_spec.rb
CHANGED
@@ -7,7 +7,7 @@ module SamlIdp
|
|
7
7
|
let(:base64cert) { document.elements["//ds:X509Certificate"].text }
|
8
8
|
|
9
9
|
it "it run validate without throwing NS related exceptions" do
|
10
|
-
document.validate_doc(base64cert, true).
|
10
|
+
expect(document.validate_doc(base64cert, true)).to be_falsey
|
11
11
|
end
|
12
12
|
|
13
13
|
it "it run validate with throwing NS related exceptions" do
|
@@ -57,22 +57,22 @@ module SamlIdp
|
|
57
57
|
describe "Algorithms" do
|
58
58
|
it "validate using SHA1" do
|
59
59
|
document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha1, false))
|
60
|
-
document.validate("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72").
|
60
|
+
expect(document.validate("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")).to be_truthy
|
61
61
|
end
|
62
62
|
|
63
63
|
it "validate using SHA256" do
|
64
64
|
document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha256, false))
|
65
|
-
document.validate("28:74:9B:E8:1F:E8:10:9C:A8:7C:A9:C3:E3:C5:01:6C:92:1C:B4:BA").
|
65
|
+
expect(document.validate("28:74:9B:E8:1F:E8:10:9C:A8:7C:A9:C3:E3:C5:01:6C:92:1C:B4:BA")).to be_truthy
|
66
66
|
end
|
67
67
|
|
68
68
|
it "validate using SHA384" do
|
69
69
|
document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha384, false))
|
70
|
-
document.validate("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72").
|
70
|
+
expect(document.validate("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")).to be_truthy
|
71
71
|
end
|
72
72
|
|
73
73
|
it "validate using SHA512" do
|
74
74
|
document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha512, false))
|
75
|
-
document.validate("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72").
|
75
|
+
expect(document.validate("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")).to be_truthy
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
@@ -83,7 +83,7 @@ module SamlIdp
|
|
83
83
|
document = XMLSecurity::SignedDocument.new(response)
|
84
84
|
inclusive_namespaces = document.send(:extract_inclusive_namespaces)
|
85
85
|
|
86
|
-
inclusive_namespaces.
|
86
|
+
expect(inclusive_namespaces).to eq %w[xs]
|
87
87
|
end
|
88
88
|
|
89
89
|
it "support implicit namespace resolution for exclusive canonicalization" do
|
@@ -91,7 +91,7 @@ module SamlIdp
|
|
91
91
|
document = XMLSecurity::SignedDocument.new(response)
|
92
92
|
inclusive_namespaces = document.send(:extract_inclusive_namespaces)
|
93
93
|
|
94
|
-
inclusive_namespaces.
|
94
|
+
expect(inclusive_namespaces).to eq %w[#default saml ds xs xsi]
|
95
95
|
end
|
96
96
|
|
97
97
|
it "return an empty list when inclusive namespace element is missing" do
|
@@ -101,7 +101,7 @@ module SamlIdp
|
|
101
101
|
document = XMLSecurity::SignedDocument.new(response)
|
102
102
|
inclusive_namespaces = document.send(:extract_inclusive_namespaces)
|
103
103
|
|
104
|
-
inclusive_namespaces.
|
104
|
+
expect(inclusive_namespaces).to be_empty
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
@@ -116,20 +116,20 @@ module SamlIdp
|
|
116
116
|
|
117
117
|
it "be able to validate a good response" do
|
118
118
|
Timecop.freeze Time.parse('2012-11-28 17:55:00 UTC') do
|
119
|
-
response.
|
120
|
-
response.
|
119
|
+
allow(response).to receive(:validate_subject_confirmation).and_return(true)
|
120
|
+
expect(response).to be_is_valid
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
124
124
|
it "fail before response is valid" do
|
125
125
|
Timecop.freeze Time.parse('2012-11-20 17:55:00 UTC') do
|
126
|
-
response.
|
126
|
+
expect(response).to_not be_is_valid
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
130
130
|
it "fail after response expires" do
|
131
131
|
Timecop.freeze Time.parse('2012-11-30 17:55:00 UTC') do
|
132
|
-
response.
|
132
|
+
expect(response).to_not be_is_valid
|
133
133
|
end
|
134
134
|
end
|
135
135
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saml_idp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Phenow
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -24,32 +24,18 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '3.2'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: uuid
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '2.3'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '2.3'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: builder
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
|
-
- - "
|
31
|
+
- - ">="
|
46
32
|
- !ruby/object:Gem::Version
|
47
33
|
version: '3.0'
|
48
34
|
type: :runtime
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
|
-
- - "
|
38
|
+
- - ">="
|
53
39
|
- !ruby/object:Gem::Version
|
54
40
|
version: '3.0'
|
55
41
|
- !ruby/object:Gem::Dependency
|
@@ -70,98 +56,112 @@ dependencies:
|
|
70
56
|
name: rake
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
|
-
- - "
|
59
|
+
- - ">="
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
61
|
+
version: '0'
|
76
62
|
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
|
-
- - "
|
66
|
+
- - ">="
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
68
|
+
version: '0'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: simplecov
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
|
-
- - "
|
73
|
+
- - ">="
|
88
74
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0
|
75
|
+
version: '0'
|
90
76
|
type: :development
|
91
77
|
prerelease: false
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
93
79
|
requirements:
|
94
|
-
- - "
|
80
|
+
- - ">="
|
95
81
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0
|
82
|
+
version: '0'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: rspec
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
|
-
- - "
|
87
|
+
- - ">="
|
102
88
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
89
|
+
version: 3.7.0
|
104
90
|
type: :development
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
|
-
- - "
|
94
|
+
- - ">="
|
109
95
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
96
|
+
version: 3.7.0
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
98
|
name: ruby-saml
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
114
100
|
requirements:
|
115
|
-
- - "
|
101
|
+
- - ">="
|
116
102
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
103
|
+
version: 1.7.2
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
107
|
requirements:
|
122
|
-
- - "
|
108
|
+
- - ">="
|
123
109
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
110
|
+
version: 1.7.2
|
125
111
|
- !ruby/object:Gem::Dependency
|
126
112
|
name: rails
|
127
113
|
requirement: !ruby/object:Gem::Requirement
|
128
114
|
requirements:
|
129
|
-
- - "
|
115
|
+
- - ">="
|
130
116
|
- !ruby/object:Gem::Version
|
131
117
|
version: '3.2'
|
132
118
|
type: :development
|
133
119
|
prerelease: false
|
134
120
|
version_requirements: !ruby/object:Gem::Requirement
|
135
121
|
requirements:
|
136
|
-
- - "
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.2'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: activeresource
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '3.2'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '3.2'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: capybara
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- - "
|
143
|
+
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: 2.
|
145
|
+
version: '2.16'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- - "
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: 2.
|
152
|
+
version: '2.16'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: timecop
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
|
-
- - "
|
157
|
+
- - ">="
|
158
158
|
- !ruby/object:Gem::Version
|
159
159
|
version: '0.8'
|
160
160
|
type: :development
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
|
-
- - "
|
164
|
+
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0.8'
|
167
167
|
- !ruby/object:Gem::Dependency
|
@@ -178,7 +178,35 @@ dependencies:
|
|
178
178
|
- - ">="
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: 0.6.4
|
181
|
-
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: appraisal
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: byebug
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
209
|
+
description: SAML IdP (Identity Provider) Library for Ruby
|
182
210
|
email: jon.phenow@sportngin.com
|
183
211
|
executables: []
|
184
212
|
extensions: []
|
@@ -220,13 +248,13 @@ files:
|
|
220
248
|
- saml_idp.gemspec
|
221
249
|
- spec/acceptance/acceptance_helper.rb
|
222
250
|
- spec/acceptance/idp_controller_spec.rb
|
223
|
-
- spec/lib/saml_idp/.assertion_builder_spec.rb.swp
|
224
251
|
- spec/lib/saml_idp/algorithmable_spec.rb
|
225
252
|
- spec/lib/saml_idp/assertion_builder_spec.rb
|
226
253
|
- spec/lib/saml_idp/attribute_decorator_spec.rb
|
227
254
|
- spec/lib/saml_idp/configurator_spec.rb
|
228
255
|
- spec/lib/saml_idp/controller_spec.rb
|
229
256
|
- spec/lib/saml_idp/encryptor_spec.rb
|
257
|
+
- spec/lib/saml_idp/incoming_metadata_spec.rb
|
230
258
|
- spec/lib/saml_idp/logout_request_builder_spec.rb
|
231
259
|
- spec/lib/saml_idp/logout_response_builder_spec.rb
|
232
260
|
- spec/lib/saml_idp/metadata_builder_spec.rb
|
@@ -291,6 +319,9 @@ files:
|
|
291
319
|
- spec/spec_helper.rb
|
292
320
|
- spec/support/certificates/certificate1
|
293
321
|
- spec/support/certificates/r1_certificate2_base64
|
322
|
+
- spec/support/certificates/sp_cert_req.csr
|
323
|
+
- spec/support/certificates/sp_private_key.pem
|
324
|
+
- spec/support/certificates/sp_x509_cert.crt
|
294
325
|
- spec/support/responses/adfs_response_sha1.xml
|
295
326
|
- spec/support/responses/adfs_response_sha256.xml
|
296
327
|
- spec/support/responses/adfs_response_sha384.xml
|
@@ -312,14 +343,18 @@ files:
|
|
312
343
|
- spec/support/saml_request_macros.rb
|
313
344
|
- spec/support/security_helpers.rb
|
314
345
|
- spec/xml_security_spec.rb
|
315
|
-
homepage:
|
346
|
+
homepage: https://github.com/saml-idp/saml_idp
|
316
347
|
licenses:
|
317
|
-
-
|
318
|
-
metadata:
|
348
|
+
- MIT
|
349
|
+
metadata:
|
350
|
+
homepage_uri: https://github.com/saml-idp/saml_idp
|
351
|
+
source_code_uri: https://github.com/saml-idp/saml_idp
|
352
|
+
bug_tracker_uri: https://github.com/saml-idp/saml_idp/issues
|
353
|
+
documentation_uri: http://rdoc.info/gems/saml_idp/0.11.0
|
319
354
|
post_install_message: |
|
320
355
|
If you're just recently updating saml_idp - please be aware we've changed the default
|
321
356
|
certificate. See the PR and a description of why we've done this here:
|
322
|
-
https://github.com/
|
357
|
+
https://github.com/saml-idp/saml_idp/pull/29
|
323
358
|
|
324
359
|
If you just need to see the certificate `bundle open saml_idp` and go to
|
325
360
|
`lib/saml_idp/default.rb`
|
@@ -346,21 +381,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
346
381
|
- !ruby/object:Gem::Version
|
347
382
|
version: '0'
|
348
383
|
requirements: []
|
349
|
-
|
350
|
-
rubygems_version: 2.4.5.2
|
384
|
+
rubygems_version: 3.1.2
|
351
385
|
signing_key:
|
352
386
|
specification_version: 4
|
353
|
-
summary: SAML Indentity Provider
|
387
|
+
summary: SAML Indentity Provider for Ruby
|
354
388
|
test_files:
|
355
389
|
- spec/acceptance/acceptance_helper.rb
|
356
390
|
- spec/acceptance/idp_controller_spec.rb
|
357
|
-
- spec/lib/saml_idp/.assertion_builder_spec.rb.swp
|
358
391
|
- spec/lib/saml_idp/algorithmable_spec.rb
|
359
392
|
- spec/lib/saml_idp/assertion_builder_spec.rb
|
360
393
|
- spec/lib/saml_idp/attribute_decorator_spec.rb
|
361
394
|
- spec/lib/saml_idp/configurator_spec.rb
|
362
395
|
- spec/lib/saml_idp/controller_spec.rb
|
363
396
|
- spec/lib/saml_idp/encryptor_spec.rb
|
397
|
+
- spec/lib/saml_idp/incoming_metadata_spec.rb
|
364
398
|
- spec/lib/saml_idp/logout_request_builder_spec.rb
|
365
399
|
- spec/lib/saml_idp/logout_response_builder_spec.rb
|
366
400
|
- spec/lib/saml_idp/metadata_builder_spec.rb
|
@@ -425,6 +459,9 @@ test_files:
|
|
425
459
|
- spec/spec_helper.rb
|
426
460
|
- spec/support/certificates/certificate1
|
427
461
|
- spec/support/certificates/r1_certificate2_base64
|
462
|
+
- spec/support/certificates/sp_cert_req.csr
|
463
|
+
- spec/support/certificates/sp_private_key.pem
|
464
|
+
- spec/support/certificates/sp_x509_cert.crt
|
428
465
|
- spec/support/responses/adfs_response_sha1.xml
|
429
466
|
- spec/support/responses/adfs_response_sha256.xml
|
430
467
|
- spec/support/responses/adfs_response_sha384.xml
|