main
1# frozen_string_literal: true
2
3module Saml
4 module Kit
5 # This class can be used to parse a SAML AuthnRequest or generate one.
6 #
7 # To generate an AuthnRequest use the builder API.
8 #
9 # request = AuthenticationRequest.build do |builder|
10 # builder.name_id_format = [Saml::Kit::Namespaces::EMAIL_ADDRESS]
11 # end
12 #
13 # <?xml version="1.0" encoding="UTF-8"?>
14 # <samlp:AuthnRequest
15 # xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
16 # xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
17 # ID="_ca3a0e72-9530-41f1-9518-c53716de88b2"
18 # Version="2.0"
19 # IssueInstant="2017-12-19T16:27:44Z"
20 # Destination="http://hartmann.info"
21 # AssertionConsumerServiceURL="https://carroll.com/acs">
22 # <saml:Issuer>Day of the Dangerous Cousins</saml:Issuer>
23 # <samlp:NameIDPolicy
24 # Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"/>
25 # </samlp:AuthnRequest>
26 #
27 # Example:
28 #
29 # {include:file:spec/examples/authentication_request_spec.rb}
30 class AuthenticationRequest < Document
31 include Requestable
32
33 # Create an instance of an AuthnRequest document.
34 #
35 # @param xml [String] the raw xml.
36 # @param configuration [Saml::Kit::Configuration] defaults to the global
37 # configuration.
38 def initialize(xml, configuration: Saml::Kit.configuration)
39 super(xml, name: 'AuthnRequest', configuration: configuration)
40 end
41
42 # Extract the AssertionConsumerServiceURL from the AuthnRequest
43 # <samlp:AuthnRequest
44 # AssertionConsumerServiceURL="https://carroll.com/acs">
45 # </samlp:AuthnRequest>
46 def assertion_consumer_service_url
47 at_xpath('./*/@AssertionConsumerServiceURL').try(:value)
48 end
49
50 # Returns the ForceAuthn attribute as a boolean.
51 def force_authn
52 at_xpath('./*/@ForceAuthn').try(:value) == 'true'
53 end
54
55 def name_id_format
56 name_id_policy
57 end
58
59 # Extract the NameIDPolicy from the AuthnRequest
60 # <samlp:AuthnRequest>
61 # <samlp:NameIDPolicy
62 # Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"/>
63 # </samlp:AuthnRequest>
64 def name_id_policy
65 at_xpath('./*/samlp:NameIDPolicy/@Format').try(:value)
66 end
67
68 # Generate a Response for a specific user.
69 # @param user [Object] this is a custom user object that can be used for
70 # generating a nameid and assertion attributes.
71 # @param binding [Symbol] the SAML binding to use
72 # `:http_post` or `:http_redirect`.
73 # @param configuration [Saml::Kit::Configuration] the configuration to
74 # use to build the response.
75 def response_for(
76 user, binding:, relay_state: nil, configuration: Saml::Kit.configuration
77 )
78 response =
79 Response.builder(user, self, configuration: configuration) do |x|
80 x.embed_signature = provider.want_assertions_signed
81 yield x if block_given?
82 end
83 provider
84 .assertion_consumer_service_for(binding: binding)
85 .serialize(response, relay_state: relay_state)
86 end
87 end
88 end
89end