Skip to content

Commit 041d198

Browse files
committed
Add support for Subjects on AuthNRequests by the new name_identifier_value_requested setting
1 parent 96094d8 commit 041d198

File tree

5 files changed

+45
-1
lines changed

5 files changed

+45
-1
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,17 @@ def init
189189
end
190190
```
191191
192+
If the SP knows who should be authenticated in the IdP, then can provide that info as follows:
193+
194+
```ruby
195+
def init
196+
request = OneLogin::RubySaml::Authrequest.new
197+
saml_settings.name_identifier_value_requested = "[email protected]"
198+
saml_settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
199+
redirect_to(request.create(saml_settings))
200+
end
201+
```
202+
192203
Once you've redirected back to the identity provider, it will ensure that the user has been authorized and redirect back to your application for final consumption. This can look something like this (the `authorize_success` and `authorize_failure` methods are specific to your application):
193204

194205
```ruby
@@ -503,6 +514,9 @@ pp(response.attributes.multi(:not_exists))
503514
The `saml:AuthnContextClassRef` of the AuthNRequest can be provided by `settings.authn_context`; possible values are described at [SAMLAuthnCxt]. The comparison method can be set using `settings.authn_context_comparison` parameter. Possible values include: 'exact', 'better', 'maximum' and 'minimum' (default value is 'exact').
504515
To add a `saml:AuthnContextDeclRef`, define `settings.authn_context_decl_ref`.
505516
517+
In a SP-initiaited flow, the SP can indicate to the IdP the subject that should be authenticated. This is done by defining the `settings.name_identifier_value_requested` before
518+
building the authrequest object.
519+
506520
507521
## Signing
508522

lib/onelogin/ruby-saml/authrequest.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,18 @@ def create_xml_document(settings)
121121
issuer = root.add_element "saml:Issuer"
122122
issuer.text = settings.issuer
123123
end
124+
125+
if settings.name_identifier_value_requested != nil
126+
subject = root.add_element "saml:Subject"
127+
128+
nameid = subject.add_element "saml:NameID"
129+
nameid.attributes['Format'] = settings.name_identifier_format if settings.name_identifier_format
130+
nameid.text = settings.name_identifier_value_requested
131+
132+
subject_confirmation = subject.add_element "saml:SubjectConfirmation"
133+
subject_confirmation.attributes['Method'] = "urn:oasis:names:tc:SAML:2.0:cm:bearer"
134+
end
135+
124136
if settings.name_identifier_format != nil
125137
root.add_element "samlp:NameIDPolicy", {
126138
# Might want to make AllowCreate a setting?

lib/onelogin/ruby-saml/settings.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def initialize(overrides = {}, keep_security_attributes = false)
4545
attr_accessor :sp_name_qualifier
4646
attr_accessor :name_identifier_format
4747
attr_accessor :name_identifier_value
48+
attr_accessor :name_identifier_value_requested
4849
attr_accessor :sessionindex
4950
attr_accessor :compress_request
5051
attr_accessor :compress_response

test/request_test.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,23 @@ class RequestTest < Minitest::Test
121121
assert_match /<samlp:NameIDPolicy[^<]* Format='urn:oasis:names:tc:SAML:2.0:nameid-format:transient'/, inflated
122122
end
123123

124+
it "create the SAMLRequest URL parameter with Subject" do
125+
settings.name_identifier_value_requested = "[email protected]"
126+
settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
127+
auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
128+
assert_match /^http:\/\/example\.com\?SAMLRequest=/, auth_url
129+
payload = CGI.unescape(auth_url.split("=").last)
130+
decoded = Base64.decode64(payload)
131+
zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
132+
inflated = zstream.inflate(decoded)
133+
zstream.finish
134+
zstream.close
135+
136+
assert inflated.include?('<saml:Subject>')
137+
assert inflated.include?("<saml:NameID Format='urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'>[email protected]</saml:NameID>")
138+
assert inflated.include?("<saml:SubjectConfirmation Method='urn:oasis:names:tc:SAML:2.0:cm:bearer'/>")
139+
end
140+
124141
it "accept extra parameters" do
125142
auth_url = OneLogin::RubySaml::Authrequest.new.create(settings, { :hello => "there" })
126143
assert_match /&hello=there$/, auth_url

test/settings_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class SettingsTest < Minitest::Test
1515
:idp_cert, :idp_cert_fingerprint, :idp_cert_fingerprint_algorithm, :idp_cert_multi,
1616
:idp_attribute_names, :issuer, :assertion_consumer_service_url, :assertion_consumer_service_binding,
1717
:single_logout_service_url, :single_logout_service_binding,
18-
:sp_name_qualifier, :name_identifier_format, :name_identifier_value,
18+
:sp_name_qualifier, :name_identifier_format, :name_identifier_value, :name_identifier_value_requested,
1919
:sessionindex, :attributes_index, :passive, :force_authn,
2020
:compress_request, :double_quote_xml_attribute_values, :protocol_binding,
2121
:security, :certificate, :private_key,

0 commit comments

Comments
 (0)