spid-es 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- N2NhNjg3NDRlNGYxYTcyYzk4MzRmZGUyOGRmNTE2ZjE4NDc2MDYyMg==
4
+ MDMxZWQyMjdjMjFjMjRjNWQyODI3ZjgzNWUzZDMyOWEzNTJmYzM5ZA==
5
5
  data.tar.gz: !binary |-
6
- OTBjMTI4YzdmNTkyMzQ3NDYwMzlhZDk2NTczNWExMWVkYWYzMmZhZg==
6
+ M2FkYzdiYzU5NThkNDA1ODM2MzVmMThmMmY4MTY0MTEwZDg0ZmRjNA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZTg4OTVhZjliMTA3YTBlY2ZhODI1YWIwZjQ2NTdjNjk5NzczZTdhODM3ZWJm
10
- Nzc2OGJiZGJlZmJhZmUzNDUxZWU2ZWYxZDE1NjdiMjUwYmVhMjdkZGEwNWRj
11
- MDlmZWM2OTk2Y2UzODg5ODBjMDMzYjAyOGQyYjIxMGE1NjI5MzY=
9
+ ZGExNjg1YTM2NGQ0ZjkzOTk2ZjM0MDBkYWI2MjRhMzg5OTFjOWQ2YjY1ZDM0
10
+ OTY3NjVlMDg0NTIxNTlkMGQ3MTk0YWM2ZjA2N2Y5ZjMwMjIzYWQzMzZkMzgz
11
+ NWMxNjljODczY2JhMzRkZGVkM2JjZTBkMjMxOTkzMzhjODJiMTE=
12
12
  data.tar.gz: !binary |-
13
- NjkzMGNhNjdhMjg0NjZhZjk5ZGY5MjEzZmIwZTdkYzNjMjZhNjU0MjMzN2I4
14
- ZTBmNzQwYWJiNDczMmUwNDdiN2M2Nzk3NDJiY2I2YzIwYjk0MDI1NDlhYTE2
15
- ZDdkOTM2YWE1ZmE5NTk0ODJhMTM0Y2VhN2JkODUzMTQ5Mzc3YzY=
13
+ NjcwYzc5NTcwOGQyMzRkMTI4Y2E5ZDZlMmJmZjJhNzA4OWE2YjgzZDEwMzg0
14
+ NmE1OThiNDc4MzIxMzM2MTJiNmYwZTE4ZWNkNjdlNDA5Y2M0MTE5NDhiODI2
15
+ ZWU5NzA3ZjM2MjJmNmJhYzc2Yjg4MmQ2ZTlkMGMzYWUyMWNmMDI=
data/README.md CHANGED
@@ -1,94 +1,109 @@
1
1
  # SPID Euro Servizi
2
2
 
3
- The Ruby SAML Spid library is a fork of Ruby SAML and it is used for implementing the client side of a SAML authorization, initialization and confirmation requests
4
- with SPID.
3
+ La libreria è un fork della libreria Ruby SAML e serve per l'integrazione di un client (Service Provider) con l'autenticazione SPID (Sistema Pubblico di Identità Digitale)
4
+ Utilizza lo standard SAML 2 come previsto dalla normativa (Regole tecniche v1. http://www.agid.gov.it/sites/default/files/circolari/spid-regole_tecniche_v1.pdf)
5
5
 
6
6
 
7
- ## The initialization phase
7
+ ## Fase iniziale
8
8
 
9
- This is the first request you will get from the identity provider. It will hit your application at a specific URL (that you've announced as being your SAML initialization point). The response to this initialization, is a redirect back to the identity provider, which can look something like this:
9
+ Azione di partenza in cui viene creata la request da inviare all'idp e viene fatto un redirect all'identity provider.
10
10
 
11
11
  ```ruby
12
12
  def init
13
- #your login with Spid method..
13
+ #creo un istanza di Spid::Saml::Authrequest
14
+ saml_settings = get_saml_settings
14
15
  #create an instance of Spid::Saml::Authrequest
15
- request = Spid::Saml::Authrequest.new(get_saml_settings)
16
+ request = Spid::Saml::Authrequest.new(saml_settings)
16
17
  auth_request = request.create
17
18
  # Based on the IdP metadata, select the appropriate binding
18
19
  # and return the action to perform to the controller
19
- meta = Spid::Saml::Metadata.new(get_saml_settings)
20
+ meta = Spid::Saml::Metadata.new(saml_settings)
20
21
  signature = get_signature(auth_request.uuid,auth_request.request,"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256")
21
- redirect meta.create_sso_request( auth_request.request, { :RelayState => request.uuid,
22
- :SigAlg => "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
23
- :Signature => signature
24
- } )
22
+ sso_request = meta.create_sso_request( auth_request.request, { :RelayState => request.uuid,
23
+ :SigAlg => "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
24
+ :Signature => signature } )
25
+ redirect_to sso_request
25
26
  end
26
27
 
27
-
28
+ ```
29
+ ## Generazione della firma
30
+
31
+ ```ruby
28
32
  def get_signature(relayState, request, sigAlg)
29
- #url encode of relayState
33
+ #url encode relayState
30
34
  relayState_encoded = escape(relayState)
31
-
32
- #deflate and base64 of samlrequest
35
+ #deflate e base64 della samlrequest
33
36
  deflate_request_B64 = encode(deflate(request))
34
-
35
- #url encode of samlrequest
37
+ #url encode della samlrequest
36
38
  deflate_request_B64_encoded = escape(deflate_request_B64)
37
-
38
- #url encode of sigAlg
39
+ #url encode della sigAlg
39
40
  sigAlg_encoded = escape(sigAlg)
40
-
41
41
  querystring="SAMLRequest=#{deflate_request_B64_encoded}&RelayState=#{relayState_encoded}&SigAlg=#{sigAlg_encoded}"
42
- digest = OpenSSL::Digest::SHA1.new(querystring.strip)
43
- pk = OpenSSL::PKey::RSA.new File.read(File.join("path.of.cert.pem"))
42
+ #puts "**QUERYSTRING** = "+querystring
43
+ digest = OpenSSL::Digest::SHA256.new(querystring.strip) #sha2 a 256
44
+ chiave_privata = xxxxxx #path della chiave privata con cui firmare
45
+ pk = OpenSSL::PKey::RSA.new File.read(chiave_privata) #chiave privata
44
46
  qssigned = pk.sign(digest,querystring.strip)
45
47
  Base64.encode64(qssigned).gsub(/\n/, "")
46
- end
48
+ end
47
49
  ```
48
50
 
49
51
 
50
- 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 is can look something like this (the authorize_success and authorize_failure methods are specific to your application):
52
+ Questo metodo è l'endpoint impostato a livello di metadata del service provider come 'assertion consumer', riceve la response saml con i dati di registrazione fatta su SPID dagli utenti.
51
53
 
52
54
  ```ruby
53
- def consume
54
- #your assertion_consumer method...
55
+ def assertion_consumer
56
+ #id dell' idp che manda response (es: 'infocert','poste')
57
+ provider_id = @request.params['ProviderID']
58
+ #response saml inviata dall'idp
55
59
  saml_response = @request.params['SAMLResponse']
56
60
  if !saml_response.nil?
57
- #read the settings
58
- settings = get_saml_settings
59
- #create an instance of response
60
- response = Spid::Saml::Response.new(saml_response)
61
- response.settings = settings
62
-
63
- #validation of response
64
- if response.is_valid?
65
- authorize_success(response.attributes)
66
- else
67
- authorize_failure(response.attributes)
68
- end
61
+ #assegno i settaggi
62
+ settings = get_saml_settings
63
+ #creo un oggetto response
64
+ response = Spid::Saml::Response.new(saml_response)
65
+ #assegno alla response i settaggi
66
+ response.settings = settings
67
+ #estraggo dal Base64 l'xml
68
+ saml_response_dec = Base64.decode64(saml_response)
69
+ #puts "**SAML RESPONSE DECODIFICATA: #{saml_response_dec}"
70
+
71
+ #validation of response
72
+ if response.is_valid?
73
+ attributi_utente = response.attributes
74
+ ...
75
+ else
76
+ #autenticazione fallita!
77
+ end
69
78
  end
70
79
  end
71
80
  ```
72
81
 
73
- In the above there are a few assumptions in place, one being that the response.name_id is an email address. This is all handled with how you specify the settings that are in play via the saml_settings method. That could be implemented along the lines of this:
82
+ Questo metodo va a impostare le varie configurazioni che servono per connettersi ad un idp. ( NB: nel caso di SPID ci sono vari idp (Poste, TIM, Info Cert) )
74
83
 
75
84
  ```ruby
76
85
  def get_saml_settings
77
86
  settings = Spid::Saml::Settings.new
78
- settings.assertion_consumer_service_url = ...String, url of your assertion consumer.
79
- settings.issuer = ...String, host of your service provider or metadata url.
80
- settings.sp_cert = ...String, path of your cert.pem.
81
- settings.single_logout_service_url = ...String, url of idp logout service'.
82
- settings.sp_name_qualifier = ...String, name qualifier of service processor (like your metadata url).
83
- settings.idp_name_qualifier = ...String, name qualifier of identity provider (idp metadata).
84
- settings.name_identifier_format = ...Array, format names ( ["urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", "urn:oasis:names:tc:SAML:2.0:nameid-format:transient", "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"] ).
85
- settings.destination_service_url = ...String, url of proxy for single sign on (in Idp).
86
- settings.single_logout_destination = ...String, url of logout request.
87
- settings.authn_context = ...Array, types of permissions allowed (["urn:oasis:names:tc:SAML:2.0:ac:classes:Smartcard", "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"]).
88
- settings.requester_identificator = ...unique id of your service provider domain.
89
- settings.skip_validation = ...Bool, skip validation of assertion or response (false).
90
- settings.idp_sso_target_url = ...String, url of idp sso proxy ("https://federatest.lepida.it/gw/SSOProxy/SAML2").
91
- settings.idp_metadata = ...String, url of idp metadata ("https://federatest.lepida.it/gw/metadata").
87
+ settings.assertion_consumer_service_url #= ...String, url dell' assertion consumer al quale arriva la response dell' idp.
88
+ settings.issuer #= ...String, host del service provider o url dei metadata.
89
+ settings.sp_cert #= ...String, path del certificato pubblico in formato pem.
90
+ settings.sp_private_key #= ...String, path della chiave privata in formato pem.
91
+ settings.single_logout_service_url #= ...String, url del servizio di logout dell'idp.
92
+ settings.sp_name_qualifier #= ...String, nome qualificato del service provider o url dei metadata.
93
+ settings.idp_name_qualifier #= ...String, nome qualificato dell' identity provider o url dei metadata dell' idp.
94
+ settings.name_identifier_format #= ...Array, formato di nomi ( impostare: ["urn:oasis:names:tc:SAML:2.0:nameid-format:transient"] ).
95
+ settings.destination_service_url #= ...String, url del servizio per l'identity provider, usato come proxy per il sso.
96
+ settings.single_logout_destination #= ...String, url di destinazione per la request logout.
97
+ settings.authn_context #= ...Array, tipi di autorizzazioni permesse (impostare: ["urn:oasis:names:tc:SAML:2.0:ac:classes:Smartcard",
98
+ "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"]).
99
+ settings.requester_identificator #= ...Array con id dei richiedenti (non usato).
100
+ settings.skip_validation #= ...Bool, imposta se evitare la validazione della response o delle asserzioni (false).
101
+ settings.idp_sso_target_url #= ...String, url target del sso dell' identity provider.
102
+ settings.idp_metadata #= ...String, url dei metadata dell' idp.
103
+ settings.requested_attribute #= ...Array, contiene i nomi dei campi richiesti dal servizio nei metadata.
104
+ settings.metadata_signed #= ...String, imposta se firmare i metadata.
105
+ settings.organization #= ...Hash, contiene nome breve (org_name), nome esteso (org_display_name) e url (org_url)
106
+ dell' organizzazione fornitore di servizi.
92
107
  settings
93
108
  end
94
109
  ```
@@ -97,28 +112,16 @@ In the above there are a few assumptions in place, one being that the response.n
97
112
 
98
113
  ## Service Provider Metadata
99
114
 
100
- To form a trusted pair relationship with the IdP, the SP (you) need to provide metadata XML
101
- to the IdP for various good reasons. (Caching, certificate lookups, relying party permissions, etc)
102
-
103
- The class Onelogin::Saml::Metdata takes care of this by reading the Settings and returning XML. All
104
- you have to do is add a controller to return the data, then give this URL to the IdP administrator.
105
- The metdata will be polled by the IdP every few minutes, so updating your settings should propagate
106
- to the IdP settings.
115
+ Per una relazione sicura con l'idp, il Service Provider deve fornire i metadata in formato xml.
116
+ La classe Spid::Saml::Metadata legge i settaggi e fornisce l'xml richiesto dagli idp.
107
117
 
108
118
  ```ruby
109
- class SamlController < ApplicationController
110
- # ... the rest of your controller definitions ...
111
- def metadata
112
- meta = Spid::Saml::Metadata.new
113
- settings = get_saml_settings
114
- render :xml => meta.generate(settings)
119
+ def sp_metadata
120
+ settings = get_saml_settings
121
+ meta = Spid::Saml::Metadata.new
122
+
123
+ @response.headers['Content-Type'] = 'application/samlmetadata+xml'
124
+ $out << meta.generate(settings)
115
125
  end
116
- end
117
126
  ```
118
127
 
119
- ## Note on Patches/Pull Requests
120
-
121
- * Fork the project.
122
- * Make your feature addition or bug fix.
123
- * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
124
- * Send me a pull request.
@@ -27,30 +27,33 @@ module Spid::Saml
27
27
  time = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
28
28
  self.issue_instant = time
29
29
  # Create AuthnRequest root element using REXML
30
- request_doc = REXML::Document.new
30
+ request_doc = Spid::XMLSecurityNew::Document.new
31
31
  request_doc.context[:attribute_quote] = :quote
32
- root = request_doc.add_element "saml2p:AuthnRequest", { "xmlns:saml2p" => "urn:oasis:names:tc:SAML:2.0:protocol" }
32
+ root = request_doc.add_element "saml2p:AuthnRequest", { "xmlns:saml2p" => "urn:oasis:names:tc:SAML:2.0:protocol",
33
+ "xmlns:saml" => "urn:oasis:names:tc:SAML:2.0:assertion"
34
+ }
33
35
  root.attributes['ID'] = uuid
34
36
  root.attributes['IssueInstant'] = time
35
37
  root.attributes['Version'] = "2.0"
36
- root.attributes['ProtocolBinding'] = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
37
- root.attributes['AttributeConsumingServiceIndex'] = "1"
38
- root.attributes['ForceAuthn'] = "false"
38
+ #root.attributes['ProtocolBinding'] = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
39
+ root.attributes['AttributeConsumingServiceIndex'] = "0"
40
+ root.attributes['ForceAuthn'] = "true"
39
41
  #root.attributes['IsPassive'] = "false"
40
42
  #usato AssertionConsumerServiceURL e ProtocolBinding in alternativa, pag 8 regole tecniche
41
- #root.attributes['AssertionConsumerServiceIndex'] = 1
43
+ root.attributes['AssertionConsumerServiceIndex'] = "0"
42
44
 
43
- # Conditionally defined elements based on settings
44
- if @settings.assertion_consumer_service_url != nil
45
- root.attributes["AssertionConsumerServiceURL"] = @settings.assertion_consumer_service_url
46
- end
45
+ #Tolto, utilizzo AssertionConsumerServiceIndex
46
+ # # Conditionally defined elements based on settings
47
+ # if @settings.assertion_consumer_service_url != nil
48
+ # root.attributes["AssertionConsumerServiceURL"] = @settings.assertion_consumer_service_url
49
+ # end
47
50
 
48
51
  if @settings.destination_service_url != nil
49
52
  root.attributes["Destination"] = @settings.destination_service_url
50
53
  end
51
54
 
52
55
  if @settings.issuer != nil
53
- issuer = root.add_element "saml2:Issuer", { "xmlns:saml2" => "urn:oasis:names:tc:SAML:2.0:assertion" }
56
+ issuer = root.add_element "saml:Issuer"
54
57
  issuer.attributes['NameQualifier'] = @settings.issuer
55
58
  issuer.attributes['Format'] = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
56
59
  issuer.text = @settings.issuer
@@ -58,8 +61,8 @@ module Spid::Saml
58
61
 
59
62
  #opzionale
60
63
  if @settings.sp_name_qualifier != nil
61
- subject = root.add_element "saml2:Subject", { "xmlns:saml2" => "urn:oasis:names:tc:SAML:2.0:assertion" }
62
- name_id = subject.add_element "saml2:NameID", { "xmlns:saml2" => "urn:oasis:names:tc:SAML:2.0:assertion" }
64
+ subject = root.add_element "saml:Subject"
65
+ name_id = subject.add_element "saml:NameID"
63
66
  name_id.attributes['Format'] = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
64
67
  name_id.attributes['NameQualifier'] = @settings.sp_name_qualifier
65
68
  end
@@ -70,8 +73,7 @@ module Spid::Saml
70
73
  root.add_element "saml2p:NameIDPolicy", {
71
74
  # Might want to make AllowCreate a setting?
72
75
  #{}"AllowCreate" => "true",
73
- "Format" => @settings.name_identifier_format[1],
74
- "SPNameQualifier" => @settings.sp_name_qualifier
76
+ "Format" => @settings.name_identifier_format[0]
75
77
  }
76
78
  end
77
79
 
@@ -80,13 +82,11 @@ module Spid::Saml
80
82
  # the IdP will choose default rules for authentication. (Shibboleth IdP)
81
83
  if @settings.authn_context != nil
82
84
  requested_context = root.add_element "saml2p:RequestedAuthnContext", {
83
- "Comparison" => "exact"
85
+ "Comparison" => "minimum"
84
86
  }
85
87
  context_class = []
86
88
  @settings.authn_context.each_with_index{ |context, index|
87
- context_class[index] = requested_context.add_element "saml2:AuthnContextClassRef", {
88
- "xmlns:saml2" => "urn:oasis:names:tc:SAML:2.0:assertion"
89
- }
89
+ context_class[index] = requested_context.add_element "saml:AuthnContextClassRef"
90
90
  context_class[index].text = context
91
91
  }
92
92
 
@@ -104,13 +104,20 @@ module Spid::Saml
104
104
 
105
105
  end
106
106
 
107
- request_doc << REXML::XMLDecl.new(version='1.0', encoding='UTF-8')
108
- ret = ""
109
- # pretty print the XML so IdP administrators can easily see what the SP supports
110
- request_doc.write(ret, 1)
111
-
112
- @request = ""
113
- request_doc.write(@request)
107
+ request_doc << REXML::XMLDecl.new("1.0", "UTF-8")
108
+
109
+ #LA FIRMA VA MESSA SOLO NEL CASO CON HTTP POST
110
+ # cert = @settings.get_sp_cert
111
+ # # embed signature
112
+ # if @settings.metadata_signed && @settings.sp_private_key && @settings.sp_cert
113
+ # private_key = @settings.get_sp_key
114
+ # request_doc.sign_document(private_key, cert)
115
+ # end
116
+
117
+ # stampo come stringa semplice i metadata per non avere problemi con validazione firma
118
+ #ret = request_doc.to_s
119
+
120
+ @request = request_doc.to_s
114
121
 
115
122
  #Logging.debug "Created AuthnRequest: #{@request}"
116
123
 
@@ -22,12 +22,12 @@ module Spid::Saml
22
22
  # The IdP sent us a LogoutRequest (IdP initiated SLO)
23
23
  else
24
24
  begin
25
- @request = XMLSecurity::SignedDocument.new( decode( opt[:request] ))
25
+ @request = Spid::XMLSecurity::SignedDocument.new( decode( opt[:request] ))
26
26
  raise if @request.nil?
27
27
  raise if @request.root.nil?
28
28
  raise if @request.root.namespace != PROTOCOL
29
29
  rescue
30
- @request = XMLSecurity::SignedDocument.new( inflate( decode( opt[:request] ) ) )
30
+ @request = Spid::XMLSecurity::SignedDocument.new( inflate( decode( opt[:request] ) ) )
31
31
  end
32
32
  Logging.debug "LogoutRequest is: \n#{@request}"
33
33
  end
@@ -16,7 +16,7 @@ module Spid
16
16
  # We've recieved a LogoutResponse from the IdP
17
17
  if opt[:response]
18
18
  begin
19
- @response = XMLSecurity::SignedDocument.new(decode( opt[:response] ))
19
+ @response = Spid::XMLSecurity::SignedDocument.new(decode( opt[:response] ))
20
20
  # Check to see if we have a root tag using the "protocol" namespace.
21
21
  # If not, it means this is deflated text and we need to raise to
22
22
  # the rescue below
@@ -25,7 +25,7 @@ module Spid
25
25
  raise if @response.root.namespace != PROTOCOL
26
26
  document
27
27
  rescue
28
- @response = XMLSecurity::SignedDocument.new( inflate(decode( opt[:response] ) ) )
28
+ @response = Spid::XMLSecurity::SignedDocument.new( inflate(decode( opt[:response] ) ) )
29
29
  end
30
30
  end
31
31
  # We plan to create() a new LogoutResponse
@@ -4,7 +4,7 @@ require "net/https"
4
4
  require "uri"
5
5
  require "digest/md5"
6
6
  require "nokogiri"
7
- require "xml_security_new" #fa il require della nokogiri
7
+ require_relative "../xml_security_new" #fa il require della nokogiri
8
8
  require "uuid"
9
9
 
10
10
  # Class to return SP metadata based on the settings requested.
@@ -30,7 +30,7 @@ module Spid
30
30
 
31
31
  def generate(settings)
32
32
  #meta_doc = REXML::Document.new
33
- meta_doc = ::XMLSecurityNew::Document.new
33
+ meta_doc = Spid::XMLSecurityNew::Document.new
34
34
  root = meta_doc.add_element "md:EntityDescriptor", {
35
35
  "xmlns:md" => "urn:oasis:names:tc:SAML:2.0:metadata",
36
36
  "xmlns:xml" => "http://www.w3.org/XML/1998/namespace"
@@ -227,31 +227,32 @@ module Spid
227
227
  def binding_select(service)
228
228
  # first check if we're still using the old hard coded method for
229
229
  # backwards compatability
230
- if service == "SingleSignOnService" && @settings.idp_metadata == nil && @settings.idp_sso_target_url != nil
230
+ if service == "SingleSignOnService" && @settings.idp_sso_target_url != nil
231
231
  return @settings.idp_sso_target_url
232
232
  end
233
- if service == "SingleLogoutService" && @settings.idp_metadata == nil && @settings.idp_slo_target_url != nil
233
+ if service == "SingleLogoutService" && @settings.idp_slo_target_url != nil
234
234
  return @settings.idp_slo_target_url
235
235
  end
236
236
 
237
237
  meta_doc = get_idp_metadata
238
238
 
239
239
  return nil unless meta_doc
240
- # first try POST
241
- sso_element = REXML::XPath.first(meta_doc, "/EntityDescriptor/IDPSSODescriptor/#{service}[@Binding='#{HTTP_POST}']")
240
+ # first try GET (REDIRECT)
241
+ sso_element = REXML::XPath.first(meta_doc, "/EntityDescriptor/IDPSSODescriptor/#{service}[@Binding='#{HTTP_GET}']")
242
242
  if !sso_element.nil?
243
243
  @URL = sso_element.attributes["Location"]
244
- #Logging.debug "binding_select: POST to #{@URL}"
244
+ Logging.debug "binding_select: GET from #{@URL}"
245
245
  return @URL
246
246
  end
247
-
248
- # next try GET
249
- sso_element = REXML::XPath.first(meta_doc, "/EntityDescriptor/IDPSSODescriptor/#{service}[@Binding='#{HTTP_GET}']")
247
+
248
+ # next try post
249
+ sso_element = REXML::XPath.first(meta_doc, "/EntityDescriptor/IDPSSODescriptor/#{service}[@Binding='#{HTTP_POST}']")
250
250
  if !sso_element.nil?
251
251
  @URL = sso_element.attributes["Location"]
252
- Logging.debug "binding_select: GET from #{@URL}"
252
+ #Logging.debug "binding_select: POST to #{@URL}"
253
253
  return @URL
254
254
  end
255
+
255
256
  # other types we might want to add in the future: SOAP, Artifact
256
257
  end
257
258
 
@@ -1,4 +1,4 @@
1
- require "xml_security"
1
+ require_relative "../xml_security_new"
2
2
  require "time"
3
3
  require "nokogiri"
4
4
  require "base64"
@@ -21,10 +21,10 @@ module Spid
21
21
  self.options = options
22
22
  self.response = response
23
23
  begin
24
- self.document = XMLSecurity::SignedDocument.new(Base64.decode64(response))
24
+ self.document = Spid::XMLSecurityNew::SignedDocument.new(Base64.decode64(response))
25
25
  rescue REXML::ParseException => e
26
26
  if response =~ /</
27
- self.document = XMLSecurity::SignedDocument.new(response)
27
+ self.document = Spid::XMLSecurityNew::SignedDocument.new(response)
28
28
  else
29
29
  raise e
30
30
  end
@@ -95,6 +95,10 @@ module Spid
95
95
  end
96
96
  end
97
97
 
98
+
99
+
100
+ #metodi per ricavare info per tracciatura agid
101
+
98
102
  def issuer
99
103
  @issuer ||= begin
100
104
  node = REXML::XPath.first(document, "/p:Response/a:Issuer", { "p" => PROTOCOL, "a" => ASSERTION })
@@ -103,6 +107,40 @@ module Spid
103
107
  end
104
108
  end
105
109
 
110
+ def response_to_id
111
+ node = REXML::XPath.first(document, "/p:Response", { "p" => PROTOCOL })
112
+ return node.attributes["InResponseTo"]
113
+ end
114
+
115
+ def id
116
+ node = REXML::XPath.first(document, "/p:Response", { "p" => PROTOCOL })
117
+ return node.attributes["ID"]
118
+ end
119
+
120
+ def issue_instant
121
+ node = REXML::XPath.first(document, "/p:Response", { "p" => PROTOCOL })
122
+ return node.attributes["IssueInstant"]
123
+ end
124
+
125
+ def assertion_id
126
+ node = REXML::XPath.first(document, "/p:Response/a:Assertion/", { "p" => PROTOCOL, "a" => ASSERTION })
127
+ return node.attributes["ID"]
128
+ end
129
+
130
+ def assertion_subject
131
+ node = REXML::XPath.first(document, "/p:Response/a:Assertion/a:Subject/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
132
+ return node.text
133
+ end
134
+
135
+ def assertion_subject_name_qualifier
136
+ node = REXML::XPath.first(document, "/p:Response/a:Assertion/a:Subject/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
137
+ return node.attributes["NameQualifier"]
138
+ end
139
+
140
+
141
+
142
+
143
+
106
144
  private
107
145
 
108
146
  def validation_error(message)
@@ -113,7 +151,7 @@ module Spid
113
151
  # prime the IdP metadata before the document validation.
114
152
  # The idp_cert needs to be populated before the validate_response_state method
115
153
 
116
- if settings
154
+ if settings
117
155
  Spid::Saml::Metadata.new(settings).get_idp_metadata
118
156
  end
119
157
  return false if validate_structure(soft) == false
@@ -125,7 +163,7 @@ module Spid
125
163
  return true if settings.skip_validation == true
126
164
 
127
165
  # document.validte populates the idp_cert
128
- return false if document.validate(get_fingerprint, soft) == false
166
+ return false if document.validate_document(get_fingerprint, soft) == false
129
167
 
130
168
  # validate response code
131
169
  return false if success? == false
@@ -163,10 +201,12 @@ module Spid
163
201
  end
164
202
 
165
203
  def get_fingerprint
204
+ idp_metadata = Spid::Saml::Metadata.new(settings).get_idp_metadata
205
+
166
206
  if settings.idp_cert
167
207
  cert_text = Base64.decode64(settings.idp_cert)
168
208
  cert = OpenSSL::X509::Certificate.new(cert_text)
169
- Digest::SHA1.hexdigest(cert.to_der).upcase.scan(/../).join(":")
209
+ Digest::SHA2.hexdigest(cert.to_der).upcase.scan(/../).join(":")
170
210
  else
171
211
  settings.idp_cert_fingerprint
172
212
  end
@@ -1,4 +1,4 @@
1
- require "xml_security_new"
1
+ require_relative "../xml_security_new"
2
2
 
3
3
  module Spid
4
4
  module Saml
@@ -30,7 +30,7 @@ module Spid
30
30
  idp_cert_fingerprint || begin
31
31
  idp_cert = get_idp_cert
32
32
  if idp_cert
33
- fingerprint_alg = XMLSecurity::BaseDocument.new.algorithm(idp_cert_fingerprint_algorithm).new
33
+ fingerprint_alg = Spid::XMLSecurity::BaseDocument.new.algorithm(idp_cert_fingerprint_algorithm).new
34
34
  fingerprint_alg.hexdigest(idp_cert.to_der).upcase.scan(/../).join(":")
35
35
  end
36
36
  end
@@ -77,7 +77,7 @@ module Spid
77
77
  #
78
78
  def self.verify_signature(params)
79
79
  cert, sig_alg, signature, query_string = [:cert, :sig_alg, :signature, :query_string].map { |k| params[k]}
80
- signature_algorithm = XMLSecurityNew::BaseDocument.new.algorithm(sig_alg)
80
+ signature_algorithm = Spid::XMLSecurityNew::BaseDocument.new.algorithm(sig_alg)
81
81
  return cert.public_key.verify(signature_algorithm.new, Base64.decode64(signature), query_string)
82
82
  end
83
83