Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support on LogoutRequest with Encrypted NameID #671

Merged
merged 3 commits into from
Sep 30, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 39 additions & 7 deletions lib/onelogin/ruby-saml/slo_logoutrequest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,26 +62,58 @@
# @return [String] Gets the NameID of the Logout Request.
#
def name_id
@name_id ||= begin
node = REXML::XPath.first(document, "/p:LogoutRequest/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
Utils.element_text(node)
end
@name_id ||= Utils.element_text(name_id_node)
end

alias_method :nameid, :name_id

# @return [String] Gets the NameID Format of the Logout Request.
#
def name_id_format
@name_id_node ||= REXML::XPath.first(document, "/p:LogoutRequest/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
@name_id_format ||=
if @name_id_node && @name_id_node.attribute("Format")
@name_id_node.attribute("Format").value
if name_id_node && name_id_node.attribute("Format")
name_id_node.attribute("Format").value
end
end

alias_method :nameid_format, :name_id_format

def name_id_node
@name_id_node ||=
begin
encrypted_node = REXML::XPath.first(document, "/p:LogoutRequest/a:EncryptedID", { "p" => PROTOCOL, "a" => ASSERTION })
if encrypted_node
node = decrypt_nameid(encrypted_node)
else
node = REXML::XPath.first(document, "/p:LogoutRequest/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
end
end
end

# Decrypts an EncryptedID element
# @param encryptedid_node [REXML::Element] The EncryptedID element
# @return [REXML::Document] The decrypted EncrypedtID element
#
def decrypt_nameid(encrypt_node)

if settings.nil? || !settings.get_sp_key
raise ValidationError.new('An ' + encrypt_node.name + ' found and no SP private key found on the settings to decrypt it')
end

node_header = '<node xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">'

elem_plaintext = OneLogin::RubySaml::Utils.decrypt_data(encrypt_node, settings.get_sp_key)
# If we get some problematic noise in the plaintext after decrypting.
# This quick regexp parse will grab only the Element and discard the noise.
elem_plaintext = elem_plaintext.match(/(.*<\/(\w+:)?NameID>)/m)[0]
Dismissed Show dismissed Hide dismissed

# To avoid namespace errors if saml namespace is not defined
# create a parent node first with the namespace defined
elem_plaintext = node_header + elem_plaintext + '</node>'
doc = REXML::Document.new(elem_plaintext)
doc.root[0]
end

# @return [String|nil] Gets the ID attribute from the Logout Request. if exists.
#
def id
Expand Down
Loading