spid-rails 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +26 -138
  3. data/lib/generators/spid/rails/templates/spid-rails.rb +19 -21
  4. data/lib/spid-rails.rb +4 -38
  5. data/lib/spid-rails/engine.rb +2 -6
  6. data/lib/spid-rails/railtie.rb +11 -0
  7. data/lib/spid-rails/route_helper.rb +52 -0
  8. data/lib/spid-rails/version.rb +1 -3
  9. metadata +34 -29
  10. data/app/controllers/spid/rails/application_controller.rb +0 -9
  11. data/app/controllers/spid/rails/metadata_controller.rb +0 -17
  12. data/app/controllers/spid/rails/single_logout_operations_controller.rb +0 -45
  13. data/app/controllers/spid/rails/single_sign_ons_controller.rb +0 -38
  14. data/app/helpers/spid/rails/application_helper.rb +0 -8
  15. data/app/jobs/spid/rails/application_job.rb +0 -8
  16. data/app/mailers/spid/rails/application_mailer.rb +0 -10
  17. data/app/models/spid/certificate.rb +0 -45
  18. data/app/models/spid/idp.rb +0 -34
  19. data/app/models/spid/metadata.rb +0 -74
  20. data/app/models/spid/rails/application_record.rb +0 -9
  21. data/app/models/spid/settings.rb +0 -92
  22. data/app/models/spid/settings/metadata.rb +0 -11
  23. data/app/models/spid/settings/slo.rb +0 -13
  24. data/app/models/spid/settings/sso.rb +0 -17
  25. data/app/models/spid/slo_request.rb +0 -22
  26. data/app/models/spid/slo_response.rb +0 -27
  27. data/app/models/spid/sso_request.rb +0 -46
  28. data/app/models/spid/sso_response.rb +0 -31
  29. data/app/views/layouts/spid-rails/application.html.erb +0 -14
  30. data/config/routes.rb +0 -16
  31. data/lib/generators/spid/rails/idp_importer_generator.rb +0 -21
  32. data/lib/generators/spid/rails/keys_generator.rb +0 -45
  33. data/lib/generators/spid/rails/templates/idp_import.yml +0 -11
  34. data/lib/spid-rails/onelogin/rubysaml/authrequest.rb +0 -79
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 1924815eea64175525b474b58e83299d8ad3530f
4
- data.tar.gz: 0a8ecc6648870bdb58a687ff5002100a589ca665
2
+ SHA256:
3
+ metadata.gz: 765a5591bc3e28e62861921b202fdd7c20576c6c4337fe5563009b8551bc9ad5
4
+ data.tar.gz: 47643cdc4f367b10a4df58675d6e4fbfecade78fcf373ed4cddb2c56fbbdf65a
5
5
  SHA512:
6
- metadata.gz: 800df0266f21277af9241d116c3412ee18a516ae26a31cabe9db3966b97008d83eec438bd27ec94d4d332ef6fbbdfba54561335b2eaa8caf3483d92fe78a7d4d
7
- data.tar.gz: 0e0ee632888e170ddcfbe0b2a8fbf92962549e51449acc30915fee2f7185a419312e20ea43c211115570d5856a29fd3871e6dc18f1fc5a14f4ae556c9ff222a2
6
+ metadata.gz: 007c881caef48afc8c8f879167f3fec615203eefaf7b5dfec8831d9c6c0ad820f9d1cf951b6c0ca219cbe41d212bd375042250647c6b80b8d61e8ebdd8babe31
7
+ data.tar.gz: 0635115efc70d49c7e131e4e09d74b5a732ab50f35959940b1735097131a0caac19a04a40ac62cf64417f400d0193a9ff72cfed14949c6aabf4d63bcb8356958
data/README.md CHANGED
@@ -12,28 +12,20 @@ repository: https://github.com/rubynetti/rubynetti-rails
12
12
  - [X] Sistema di configurazione
13
13
  - [ ] Integrazione con omniauth
14
14
  - [ ] Integrazione o esempio di integrazione con devise
15
- - [ ] Configurazione richiesta attributi utente
15
+ - [X] Configurazione richiesta attributi utente
16
16
 
17
17
 
18
18
  ## Installazione
19
- All'interno del Gemfile indicare questa gemma:
20
-
19
+ Aggiungere nel Gemfile
21
20
  ```ruby
22
21
  gem 'spid-rails'
23
22
  ```
24
-
25
- Eseguire
23
+ ed eseguire
26
24
 
27
25
  ```bash
28
26
  $ bundle
29
27
  ```
30
28
 
31
-
32
- ## Come si usa?
33
- La gemma può essere aggiunta a qualunque applicazione Rails al fine di utilizzare il sistema di login Spid.
34
- Il metadata generato può essere utilizzato per farsi accreditare e in seguito dialogare con qualunque Identity Provider Spid accreditato.
35
-
36
-
37
29
  ### Configurazione
38
30
 
39
31
  Per creare il file di configurazione:
@@ -41,145 +33,41 @@ Per creare il file di configurazione:
41
33
  ```bash
42
34
  $ rails g spid:rails:config
43
35
  ```
36
+ che creerà il file `config/initializer/spid-rails.rb` con la configurazione default.
44
37
 
45
- Il file viene aggiunto agli initializer dell'applicazione e permette il settaggio personalizzato del mount-point dell'engine e i relativi end-point per le procedure Spid di login, logout e visualizzazione del metadata del Service Provider.
46
-
47
- Le restanti impostazioni permettono di configurare il percorso di sistema dove reperire la coppia chiave privata/certificato e il livello di crittografia per l'eventuale signature.
38
+ Una volta creata la configurazione bisogna aggiungere il middleware **dopo** il middleware di gestione della sessione. In `config/application.rb`
48
39
 
49
40
  ```ruby
50
- # config/initializers/spid-rails.rb
51
-
52
- # Impostazioni di default dello Spid Engine
53
-
54
- Spid::Rails.tap do |config|
55
-
56
- # Mount point di Spid sull'applicazione
57
- # default: 'spid'
58
- # config.mount_point = 'spid'
59
-
60
- # Url alla quale e' disponibile il metadata del provider
61
- # default: 'metadata'
62
- # config.metadata_path = 'metadata'
63
-
64
- # Url alla quale ricevere le risposte di autenticazione Saml
65
- # default: 'sso'
66
- # config.sso_path = 'sso'
67
-
68
- # Url alla quale ricevere le risposte di logout Saml
69
- # default: 'slo'
70
- # config.slo_path = 'slo'
71
-
72
- # Percorso relativo alla root dell'app
73
- # al quale reperire la coppia chiave privata - certificato
74
- # default: 'lib/.keys'
75
- # config.keys_path = 'lib/.keys/'
76
-
77
- # Livello di crittografia SHA per la generazione delle signature
78
- # default: 256
79
- # config.sha = 256
80
-
41
+ # config/application.rb
42
+
43
+ module MyApplication
44
+ class Application < ::Rails::Application
45
+ config.middleware.insert_after(
46
+ ::ActionDispatch::Session::CookieStore,
47
+ ::Spid::Rack
48
+ )
49
+ end
81
50
  end
82
51
  ```
83
52
 
53
+ Questa gemma è un wrapper della gemma [spid-ruby](https://github.com/italia/spid-ruby) con funzionalità per semplificare l'utilizzo con rails
84
54
 
85
- Per utilizzare Identity provider custom o modificare quelli presenti:
86
-
87
- ```bash
88
- $ rails g spid:rails:idp_importer
89
- ```
90
-
91
- Il file viene aggiunto alla cartella _config/spid-rails_ e permette di specificare idp per i diversi ambienti dell'applicazione.
92
-
93
- ```YAML
94
- # app/config/spid-rails/idp_import.yml
95
55
 
96
- shared: &shared
97
- local_test:
98
- metadata_url: 'https://localhost:8080'
99
- validate_cert: false
56
+ ### Helpers
57
+ La gemma fornirà una serie di helpers per la generazione dei paths:
100
58
 
101
- development:
102
- <<: *shared
103
- agid:
104
- metadata_url: 'https://idp.spid.gov.it:8080/assets/idp-metadata.xml'
105
- validate_cert: false
59
+ #### spid_login_path
60
+ `spid_login_path(idp_name: idp_entity_id, authn_context: Spid::L1, attribute_service_index: 0)`
106
61
 
107
- test:
108
- <<: *shared
109
- ```
110
-
111
-
112
- ### Nelle view
113
-
114
- Una volta installata la gemma, verranno creati una serie di helper utilizzabili nelle view e nei controller.
115
-
116
- ```spid_rails.metadata_path``` e ```spid_rails.metadata_url``` restituiscono il percorso al quale è reperibile il metadata del Service Provider.
117
- ```ruby
118
- # Esempio di link al metadata del ServiceProvider
119
- link_to "Metadata SP", spid_rails.metadata_path
120
- ```
121
-
122
-
123
- ```spid_rails.new_sso_path``` e ```spid_rails.new_sso_url``` restituiscono il percorso tramite il quale inizializzare una richiesa di autenticazione all'Identity Provider.
124
- È necessario fornire come parametro l'Idp cui indirizzare la richiesta, facoltativo il livello di autenticazione Spid (default: '1') e i bindings della richiesta all' Idp (default: ['redirect']).
125
- ```ruby
126
- # Esempio di link al login tramite l'Idp di test https:://idp.spid.gov.it
127
- link_to "Login con Spid", spid_rails.new_sso_path(sso: { idp: :agid_test, spid_level: 2 })
128
- ```
129
-
130
- Gli Identity Provider attualmente supportati sono:
131
- - 'aruba' : servizio Idp di Aruba Pec S.p.A.
132
- - 'infocert' : servizio Idp di Infocert S.p.A
133
- - 'namirial' : servizio Idp di Namirial S.p.A.
134
- - 'poste' : servizio Idp di Poste Italiane S.p.A.
135
- - 'spiditalia' : servizio Idp di REGISTER.IT S.p.A.
136
- - 'sielte' : servizio Idp di Sielte S.p.A.
137
- - 'tim' : servizio Idp di TI Trust Technologies S.r.l.
138
- - 'agid_test' : servizio idp di test di Agid
139
- - 'poste_test' : servizio Idp di test di Poste Italiane S.p.A.
140
-
141
-
142
- ```spid_rails.new_slo_path``` e ```spid_rails.new_slo_url``` infine restituiscono il percorso tramite il quale inizializzare una richiesa di logout all'Identity Provider che ha autenticato la sessione corrente.
143
- ```ruby
144
- # Esempio di link al logout
145
- link_to "Logout", spid_rails.new_slo_path
146
- ```
147
-
148
-
149
- ### Nei controller
150
-
151
- Dopo l'autenticazione e fino al logout vengono aggiunte alla sessione le seguenti variabili:
152
-
153
- ```session[:sso_params]``` che restituisce i parametri coi quali è stata effettuata l'ultima richiesta di autenticazione, in particolare l'idp
154
-
155
- ```session[:spid_index]``` che restituisce l'identificativo dell'attuale sessione Spid e viene utilizzato nella procedura di logout
156
-
157
- ```session[:spid_login_time]``` che restituisce il _time_ in cui è avvenuto il login
158
-
159
- È inoltre possibile settare la variabile ```session[:spid_relay_state]```, contenente l'indirizzo al quale si vuole essere reindirizzati in caso l'autenticazione abbia successo
160
-
161
- Un esempio rudimentale di verifica del login dell'utente all'interno di un'azione del controller potrebbe essere il seguente
162
- ```ruby
163
- # app/controllers/my_controller.rb
164
- class MyController < Application controller
165
- before_action :validate_spid_session
166
-
167
- ...
168
-
169
- private
170
-
171
- def validate_spid_session
172
- if session[:spid_index].blank?
173
- session[:spid_relay_state] = request.path
174
- redirect_to login_path
175
- end
176
- end
177
-
178
- end
179
- ```
62
+ che genera un url per iniziare il processo di autenticazione con un identity provider:
180
63
 
181
- dove _login_path_ indirizza alla pagina in cui è posizionato il pulsante Spid.
64
+ * idp_name: Obbligatorio, è l'entity_id dell'IdP con cui vogliamo instaurare l'autenticazione
65
+ * authn_context: E' il valore del tipo di autenticazione richiesta. Default: `https://www.spid.gov.id/L1`
66
+ * attribute_service_index: Nel caso in cui l'applicazione disponga di più `AttributeConsumingService`, l'indice del servizio che vogliamo utilizzare. Default: 0
182
67
 
68
+ #### spid_logout_path
69
+ `spid_logout_path(idp_name: idp_entity_id)`
70
+ Come sopra, crea un link per iniziare il processo di logout verso l'IdP
183
71
 
184
72
  ## License
185
73
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -1,26 +1,24 @@
1
- Spid::Rails.tap do |config|
2
- # Mount point di Spid sull'applicazione
3
- # default: 'spid'
4
- # config.mount_point = 'spid'
1
+ # frozen_string_literal: true
5
2
 
6
- # Url alla quale e' disponibile il metadata del provider
7
- # default: 'metadata'
8
- # config.metadata_path = 'metadata'
3
+ Spid.configure do |config|
4
+ config.hostname = ENV.fetch('HOST')
9
5
 
10
- # Url alla quale ricevere le risposte di autenticazione Saml
11
- # default: 'sso'
12
- # config.sso_path = 'sso'
6
+ config.idp_metadata_dir_path = Rails.root.join('config/idp_metadata')
7
+ config.private_key_pem = ENV.fetch('PRIVATE_KEY')
8
+ config.certificate_pem = ENV.fetch('CERTIFICATE')
13
9
 
14
- # Url alla quale ricevere le risposte di logout Saml
15
- # default: 'slo'
16
- # config.slo_path = 'slo'
10
+ config.metadata_path = '/spid/metadata'
11
+ config.login_path = '/spid/login'
12
+ config.logout_path = '/spid/logout'
13
+ config.acs_path = '/spid/sso'
14
+ config.slo_path = '/spid/slo'
15
+ config.default_relay_state_path = '/'
17
16
 
18
- # Percorso relativo alla root dell'app
19
- # al quale reperire la coppia chiave privata - certificato
20
- # default: 'lib/.keys'
21
- # config.keys_path = 'lib/.keys/'
22
-
23
- # Livello di crittografia SHA per la generazione delle signature
24
- # default: 256
25
- # config.sha = 256
17
+ config.digest_method = Spid::SHA512
18
+ config.signature_method = Spid::RSA_SHA512
19
+ config.acs_binding = Spid::BINDINGS_HTTP_POST
20
+ config.slo_binding = Spid::BINDINGS_HTTP_REDIRECT
21
+ config.attribute_services = [
22
+ { name: 'Service1', fields: ['email'] }
23
+ ]
26
24
  end
@@ -1,44 +1,10 @@
1
+ require 'spid'
2
+ require 'spid-rails/railtie'
1
3
  require 'spid-rails/engine'
4
+ require 'spid-rails/route_helper'
5
+ require 'spid-rails/version'
2
6
 
3
7
  module Spid
4
8
  module Rails
5
-
6
- # Mount point di Spid sull'applicazione
7
- mattr_accessor :mount_point
8
- @@mount_point = 'spid'
9
-
10
- # Url alla quale e' disponibile il metadata del provider
11
- mattr_accessor :metadata_path
12
- @@metadata_path = 'metadata'
13
-
14
- # Url alla quale ricevere le risposte di autenticazione Saml
15
- mattr_accessor :sso_path
16
- @@sso_path = 'sso'
17
-
18
- # Url alla quale ricevere le risposte di logout Saml
19
- mattr_accessor :slo_path
20
- @@slo_path = 'slo'
21
-
22
- # Percorso relativo alla root dell'app
23
- # al quale reperire la coppia chiave privata - certificato
24
- mattr_accessor :keys_path
25
- @@keys_path = 'lib/.keys/'
26
-
27
- # Livello di crittografia SHA per la generazione delle signature
28
- mattr_accessor :sha
29
- @@sha = 256
30
-
31
- def self.app_metadata_path
32
- "#{mount_point}/#{@@metadata_path}"
33
- end
34
-
35
- def self.app_sso_path
36
- "#{mount_point}/#{@@sso_path}"
37
- end
38
-
39
- def self.app_slo_path
40
- "#{mount_point}/#{@@slo_path}"
41
- end
42
-
43
9
  end
44
10
  end
@@ -1,15 +1,11 @@
1
1
  require 'onelogin/ruby-saml'
2
- require 'spid-rails/onelogin/rubysaml/authrequest'
3
2
 
4
3
  module Spid
5
4
  module Rails
6
5
 
7
6
  class Engine < ::Rails::Engine
8
- isolate_namespace Spid::Rails
9
-
10
- initializer 'spid-rails.load_custom_idp_list' do
11
- path_to_list = ::Rails.root.join('config', 'spid-rails', 'idp_import.yml')
12
- Spid::Idp.import(path_to_list) if File.exist?(path_to_list)
7
+ initializer 'spid_rails_engine' do |_app|
8
+ ActionView::Base.send :include, ::Spid::Rails::RouteHelper
13
9
  end
14
10
 
15
11
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spid
4
+ module Rails
5
+ class Railtie < ::Rails::Railtie # :nodoc:
6
+ rake_tasks do |_app|
7
+ require 'spid/tasks'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,52 @@
1
+ module Spid
2
+ module Rails
3
+ module RouteHelper
4
+ def metadata_path
5
+ Spid.configuration.metadata_path
6
+ end
7
+
8
+ def metadata_url
9
+ URI.join(
10
+ Spid.configuration.hostname,
11
+ metadata_path
12
+ ).to_s
13
+ end
14
+
15
+ def spid_login_path(
16
+ idp_name:,
17
+ authn_context: nil,
18
+ attribute_service_index: nil
19
+ )
20
+ options = { idp_name: idp_name }
21
+ options[:authn_context] = authn_context if authn_context.present?
22
+ options[:attribute_service_index] = attribute_service_index if attribute_service_index.present?
23
+ [
24
+ Spid.configuration.login_path,
25
+ options.to_param
26
+ ].join('?')
27
+ end
28
+
29
+ def spid_logout_path(idp_name:)
30
+ options = { idp_name: idp_name }
31
+ [
32
+ Spid.configuration.logout_path,
33
+ options.to_param
34
+ ].join('?')
35
+ end
36
+
37
+ def spid_login_url(options)
38
+ URI.join(
39
+ Spid.configuration.hostname,
40
+ spid_login_path(options)
41
+ ).to_s
42
+ end
43
+
44
+ def spid_logout_url(options)
45
+ URI.join(
46
+ Spid.configuration.hostname,
47
+ spid_logout_path(options)
48
+ ).to_s
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,7 +1,5 @@
1
1
  module Spid
2
2
  module Rails
3
-
4
- VERSION = '0.1.3'
5
-
3
+ VERSION = '0.2.0'
6
4
  end
7
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spid-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alessandro Descovi, Giacomo Bertoldi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-29 00:00:00.000000000 Z
11
+ date: 2019-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -64,6 +64,20 @@ dependencies:
64
64
  - - ">="
65
65
  - !ruby/object:Gem::Version
66
66
  version: 1.0.4
67
+ - !ruby/object:Gem::Dependency
68
+ name: spid
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: 0.18.0
74
+ type: :runtime
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 0.18.0
67
81
  - !ruby/object:Gem::Dependency
68
82
  name: bundler-audit
69
83
  requirement: !ruby/object:Gem::Requirement
@@ -79,7 +93,7 @@ dependencies:
79
93
  - !ruby/object:Gem::Version
80
94
  version: '0'
81
95
  - !ruby/object:Gem::Dependency
82
- name: rubocop
96
+ name: pry-byebug
83
97
  requirement: !ruby/object:Gem::Requirement
84
98
  requirements:
85
99
  - - ">="
@@ -92,6 +106,20 @@ dependencies:
92
106
  - - ">="
93
107
  - !ruby/object:Gem::Version
94
108
  version: '0'
109
+ - !ruby/object:Gem::Dependency
110
+ name: rubocop
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - '='
114
+ - !ruby/object:Gem::Version
115
+ version: 0.57.2
116
+ type: :development
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - '='
121
+ - !ruby/object:Gem::Version
122
+ version: 0.57.2
95
123
  - !ruby/object:Gem::Dependency
96
124
  name: simplecov
97
125
  requirement: !ruby/object:Gem::Requirement
@@ -135,36 +163,13 @@ files:
135
163
  - app/assets/javascripts/spid-rails/metadata.js
136
164
  - app/assets/stylesheets/spid-rails/application.css
137
165
  - app/assets/stylesheets/spid-rails/metadata.css
138
- - app/controllers/spid/rails/application_controller.rb
139
- - app/controllers/spid/rails/metadata_controller.rb
140
- - app/controllers/spid/rails/single_logout_operations_controller.rb
141
- - app/controllers/spid/rails/single_sign_ons_controller.rb
142
- - app/helpers/spid/rails/application_helper.rb
143
- - app/jobs/spid/rails/application_job.rb
144
- - app/mailers/spid/rails/application_mailer.rb
145
- - app/models/spid/certificate.rb
146
- - app/models/spid/idp.rb
147
- - app/models/spid/metadata.rb
148
- - app/models/spid/rails/application_record.rb
149
- - app/models/spid/settings.rb
150
- - app/models/spid/settings/metadata.rb
151
- - app/models/spid/settings/slo.rb
152
- - app/models/spid/settings/sso.rb
153
- - app/models/spid/slo_request.rb
154
- - app/models/spid/slo_response.rb
155
- - app/models/spid/sso_request.rb
156
- - app/models/spid/sso_response.rb
157
- - app/views/layouts/spid-rails/application.html.erb
158
- - config/routes.rb
159
166
  - config/spid-rails/idp_list.yml
160
167
  - lib/generators/spid/rails/config_generator.rb
161
- - lib/generators/spid/rails/idp_importer_generator.rb
162
- - lib/generators/spid/rails/keys_generator.rb
163
- - lib/generators/spid/rails/templates/idp_import.yml
164
168
  - lib/generators/spid/rails/templates/spid-rails.rb
165
169
  - lib/spid-rails.rb
166
170
  - lib/spid-rails/engine.rb
167
- - lib/spid-rails/onelogin/rubysaml/authrequest.rb
171
+ - lib/spid-rails/railtie.rb
172
+ - lib/spid-rails/route_helper.rb
168
173
  - lib/spid-rails/version.rb
169
174
  - lib/tasks/spid-rails_tasks.rake
170
175
  homepage: https://github.com/italia/spid-rails
@@ -187,7 +192,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
192
  version: '0'
188
193
  requirements: []
189
194
  rubyforge_project:
190
- rubygems_version: 2.5.2.1
195
+ rubygems_version: 2.7.7
191
196
  signing_key:
192
197
  specification_version: 4
193
198
  summary: SPID, il Sistema Pubblico di Identita' Digitale
@@ -1,9 +0,0 @@
1
- module Spid
2
- module Rails
3
-
4
- class ApplicationController < ActionController::Base
5
- protect_from_forgery with: :exception
6
- end
7
-
8
- end
9
- end
@@ -1,17 +0,0 @@
1
- require_dependency 'spid/rails/application_controller'
2
-
3
- # Metadata del Service Provider
4
- module Spid
5
- module Rails
6
-
7
- class MetadataController < ApplicationController
8
-
9
- def show
10
- metadata = Metadata.create(host: main_app.root_url)
11
- render xml: metadata.to_xml
12
- end
13
-
14
- end
15
-
16
- end
17
- end
@@ -1,45 +0,0 @@
1
- require_dependency 'spid/rails/application_controller'
2
-
3
- module Spid
4
- module Rails
5
-
6
- class SingleLogoutOperationsController < ApplicationController
7
- skip_before_action :verify_authenticity_token, only: :create
8
-
9
- def new
10
- logout_request = SloRequest.new(slo_params)
11
- redirect_to logout_request.to_saml
12
- session[:spid_slo_id] = logout_request.uuid
13
- end
14
-
15
- def create
16
- _logout_response = SloResponse.new(params[:SAMLResponse],
17
- session[:spid_slo_id],
18
- slo_params)
19
- # TODO: approfondire validazione logout
20
- destroy_spid_session
21
- redirect_to main_app.root_path, notice: 'Logout utente eseguito con successo'
22
- end
23
-
24
- private
25
-
26
- def slo_params
27
- {
28
- host: main_app.root_url,
29
- idp: session[:sso_params]['idp'],
30
- session_index: session[:spid_index]
31
- }
32
- end
33
-
34
- def destroy_spid_session
35
- session[:sso_params] = nil
36
- session[:spid_index] = nil
37
- session[:spid_slo_id] = nil
38
- session[:spid_relay_state] = nil
39
- session[:spid_login_time] = nil
40
- end
41
-
42
- end
43
-
44
- end
45
- end
@@ -1,38 +0,0 @@
1
- require_dependency 'spid/rails/application_controller'
2
-
3
- module Spid
4
- module Rails
5
-
6
- class SingleSignOnsController < ApplicationController
7
- skip_before_action :verify_authenticity_token, only: :create
8
-
9
- def new
10
- request = SsoRequest.new(sso_params)
11
- redirect_to request.to_saml
12
- session[:sso_params] = sso_params
13
- end
14
-
15
- def create
16
- response = SsoResponse.new(params[:SAMLResponse], session[:sso_params])
17
- if response.valid?
18
- session[:spid_index] = response.session_index
19
- session[:spid_login_time] = Time.now
20
- redirect_to session[:relay_state] || main_app.root_path, notice: 'Utente autenticato con successo'
21
- else
22
- redirect_to main_app.root_path, notice: 'Autenticazione fallita'
23
- end
24
- end
25
-
26
- private
27
-
28
- def sso_params
29
- sso_params = params.require(:sso).permit(:idp, :spid_level, bindings: [])
30
- sso_params[:host] = main_app.root_url
31
- sso_params[:relay_state] = session[:spid_relay_state] || main_app.root_url
32
- sso_params
33
- end
34
-
35
- end
36
-
37
- end
38
- end
@@ -1,8 +0,0 @@
1
- module Spid
2
- module Rails
3
-
4
- module ApplicationHelper
5
- end
6
-
7
- end
8
- end
@@ -1,8 +0,0 @@
1
- module Spid
2
- module Rails
3
-
4
- class ApplicationJob < ActiveJob::Base
5
- end
6
-
7
- end
8
- end
@@ -1,10 +0,0 @@
1
- module Spid
2
- module Rails
3
-
4
- class ApplicationMailer < ActionMailer::Base
5
- default from: 'from@example.com'
6
- layout 'mailer'
7
- end
8
-
9
- end
10
- end
@@ -1,45 +0,0 @@
1
- module Spid
2
-
3
- class Certificate
4
-
5
- def self.signature_algorithm sha
6
- case sha.to_s
7
- when '256'
8
- XMLSecurity::Document::RSA_SHA256
9
- when '384'
10
- XMLSecurity::Document::RSA_SHA384
11
- when '512'
12
- XMLSecurity::Document::RSA_SHA512
13
- end
14
- end
15
-
16
- def self.digest_algorithm sha
17
- case sha.to_s
18
- when '256'
19
- XMLSecurity::Document::SHA256
20
- when '384'
21
- XMLSecurity::Document::SHA384
22
- when '512'
23
- XMLSecurity::Document::SHA512
24
- end
25
- end
26
-
27
- def self.signature_algorithms
28
- [
29
- XMLSecurity::Document::RSA_SHA256,
30
- XMLSecurity::Document::RSA_SHA384,
31
- XMLSecurity::Document::RSA_SHA512,
32
- ]
33
- end
34
-
35
- def self.digest_algorithms
36
- [
37
- XMLSecurity::Document::SHA256,
38
- XMLSecurity::Document::SHA384,
39
- XMLSecurity::Document::SHA512,
40
- ]
41
- end
42
-
43
- end
44
-
45
- end
@@ -1,34 +0,0 @@
1
- module Spid
2
-
3
- class Idp
4
- @list = YAML.load_file(
5
- Spid::Rails::Engine.root.join('config', 'spid-rails', 'idp_list.yml')
6
- )
7
-
8
- attr_reader :metadata_url
9
-
10
- def self.find(name)
11
- raise 'Idp not found' unless @list.key?(name)
12
- idp_attributes = @list[name]
13
- new(idp_attributes.symbolize_keys)
14
- end
15
-
16
- def self.import(file_path)
17
- list = YAML.load_file(file_path)[::Rails.env]
18
- list.each do |name, params|
19
- @list[name] = params
20
- end
21
- end
22
-
23
- def initialize(metadata_url:, validate_cert: true)
24
- @metadata_url = metadata_url
25
- @validate_cert = validate_cert
26
- end
27
-
28
- def validate_cert?
29
- @validate_cert
30
- end
31
-
32
- end
33
-
34
- end
@@ -1,74 +0,0 @@
1
- module Spid
2
-
3
- class Metadata
4
- attr_accessor :settings
5
-
6
- def self.create **settings
7
- obj = self.new(**settings)
8
- obj.save if obj.valid?
9
- end
10
-
11
- def initialize spid_params
12
- spid_settings = Settings::Metadata.new(spid_params)
13
- @settings = spid_settings.to_hash
14
- end
15
-
16
- def valid?
17
- raise 'EntityID deve essere presente (impostare issuer)' if settings[:issuer].blank?
18
- raise 'Signature deve essere presente (impostare private_key)' if settings[:private_key].blank?
19
- raise 'Signature deve essere presente (impostare certificate)' if settings[:certificate].blank?
20
- validate_signature_encryption
21
- validate_digest_encryption
22
- validate_key_size
23
-
24
- true
25
- end
26
-
27
- def validate_signature_encryption
28
- signature_algorithms = Certificate.signature_algorithms
29
- if signature_algorithms.exclude?(settings[:security][:signature_method])
30
- raise 'Signature deve essere presente (impostare encryption sha a 256, 384, 512)'
31
- end
32
- end
33
-
34
- def validate_digest_encryption
35
- digest_algorithms = Certificate.digest_algorithms
36
- if digest_algorithms.exclude?(settings[:security][:digest_method])
37
- raise 'Signature deve essere presente (impostare encryption sha a 256, 384, 512)'
38
- end
39
- end
40
-
41
- def validate_key_size
42
- key = OpenSSL::PKey::RSA.new settings[:private_key]
43
- key_size = key.n.num_bytes * 8
44
- if key_size < 1024
45
- raise 'Signature deve essere presente (impostare una chiave di almeno a 1024 bit'
46
- end
47
- end
48
-
49
- def save
50
- valid?
51
- metadata = OneLogin::RubySaml::Metadata.new
52
- saml_settings = OneLogin::RubySaml::Settings.new @settings
53
- @to_xml = metadata.generate(saml_settings)
54
- self
55
- end
56
-
57
- def to_xml
58
- save and @to_xml
59
- end
60
-
61
- def self.xml_namespaces
62
- {
63
- saml: 'urn:oasis:names:tc:SAML:2.0:assertion',
64
- samlp: 'urn:oasis:names:tc:SAML:2.0:protocol',
65
- md: 'urn:oasis:names:tc:SAML:2.0:metadata',
66
- ds: 'http://www.w3.org/2000/09/xmldsig#',
67
- xenc: 'http://www.w3.org/2001/04/xmlenc#',
68
- xs: 'http://www.w3.org/2001/XMLSchema'
69
- }
70
- end
71
-
72
- end
73
-
74
- end
@@ -1,9 +0,0 @@
1
- module Spid
2
- module Rails
3
-
4
- class ApplicationRecord < ActiveRecord::Base
5
- self.abstract_class = true
6
- end
7
-
8
- end
9
- end
@@ -1,92 +0,0 @@
1
- module Spid
2
-
3
- class Settings
4
-
5
- attr_accessor :host
6
-
7
- attr_accessor :metadata_path
8
-
9
- attr_accessor :sso_path
10
-
11
- attr_accessor :slo_path
12
-
13
- attr_accessor :keys_path
14
-
15
- attr_accessor :sha
16
-
17
- attr_accessor :idp
18
-
19
- attr_accessor :bindings
20
-
21
- attr_accessor :spid_level
22
-
23
- attr_accessor :session_index
24
-
25
- attr_accessor :relay_state
26
-
27
- def initialize spid_params
28
- @metadata_path = Spid::Rails.app_metadata_path
29
- @sso_path = Spid::Rails.app_sso_path
30
- @slo_path = Spid::Rails.app_slo_path
31
- @keys_path = Spid::Rails.keys_path
32
- @sha = Spid::Rails.sha
33
- @bindings = [:redirect]
34
- @spid_level = 1
35
- spid_params.each do |k, v|
36
- send("#{k}=", v)
37
- end
38
- end
39
-
40
- def security_attributes
41
- dig_alg = Certificate.digest_algorithm(@sha)
42
- sig_alg = Certificate.signature_algorithm(@sha)
43
- {
44
- metadata_signed: true,
45
- digest_method: dig_alg,
46
- signature_method: sig_alg,
47
- authn_requests_signed: true,
48
- want_assertions_signed: true
49
- }
50
- end
51
-
52
- def sp_attributes
53
- {
54
- issuer: host,
55
- assertion_consumer_service_url: host + sso_path,
56
- single_logout_service_url: host + slo_path,
57
- private_key: File.read("#{::Rails.root}/#{keys_path}/private_key.pem"),
58
- certificate: File.read("#{::Rails.root}/#{keys_path}/certificate.pem"),
59
- security: security_attributes
60
- }
61
- end
62
-
63
- def idp_attributes
64
- idp = Spid::Idp.find(@idp.to_s)
65
- bindings = @bindings.map { |verb| self.class.saml_bindings[verb] }
66
- parser = OneLogin::RubySaml::IdpMetadataParser.new
67
- parser.parse_remote_to_hash idp.metadata_url,
68
- idp.validate_cert?,
69
- sso_binding: bindings
70
- end
71
-
72
- private
73
-
74
- def authn_context
75
- "https://www.spid.gov.it/SpidL#{@spid_level}"
76
- end
77
-
78
- def force_authn
79
- return true if @spid_level != 1
80
- end
81
-
82
- # TODO spostare in utils
83
- def self.saml_bindings
84
- {
85
- post: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
86
- redirect: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
87
- }
88
- end
89
-
90
- end
91
-
92
- end
@@ -1,11 +0,0 @@
1
- module Spid
2
-
3
- class Settings::Metadata < Settings
4
-
5
- def to_hash
6
- sp_attributes
7
- end
8
-
9
- end
10
-
11
- end
@@ -1,13 +0,0 @@
1
- module Spid
2
-
3
- class Settings::Slo < Settings
4
-
5
- def to_hash
6
- sso_attributes = sp_attributes.merge(idp_attributes)
7
- sso_attributes[:sessionindex] = @session_index
8
- sso_attributes
9
- end
10
-
11
- end
12
-
13
- end
@@ -1,17 +0,0 @@
1
- module Spid
2
-
3
- class Settings::Sso < Settings
4
-
5
- def to_hash
6
- sso_attributes = sp_attributes.merge(idp_attributes)
7
- sso_attributes[:authn_context] = authn_context
8
- sso_attributes[:authn_context_comparison] = 'minimum'
9
- sso_attributes[:force_authn] = force_authn
10
- sso_attributes[:protocol_binding] = self.class.saml_bindings[:post]
11
- sso_attributes[:relay_state] = relay_state
12
- sso_attributes
13
- end
14
-
15
- end
16
-
17
- end
@@ -1,22 +0,0 @@
1
- module Spid
2
-
3
- class SloRequest
4
-
5
- def initialize slo_params
6
- spid_settings = Settings::Slo.new(slo_params)
7
- @settings = spid_settings.to_hash
8
- @request = OneLogin::RubySaml::Logoutrequest.new
9
- end
10
-
11
- def uuid
12
- @request.uuid
13
- end
14
-
15
- def to_saml
16
- saml_settings = OneLogin::RubySaml::Settings.new(@settings)
17
- @request.create(saml_settings)
18
- end
19
-
20
- end
21
-
22
- end
@@ -1,27 +0,0 @@
1
- module Spid
2
-
3
- class SloResponse
4
-
5
- def initialize saml_response, slo_id, slo_params
6
- spid_settings = Settings::Slo.new(slo_params)
7
- settings = OneLogin::RubySaml::Settings.new(spid_settings.to_hash)
8
- @response = OneLogin::RubySaml::Logoutresponse.new(saml_response,
9
- settings,
10
- matches_request_id: slo_id)
11
- end
12
-
13
- def valid?
14
- @response.validate
15
- end
16
-
17
- def inspect
18
- @response.inspect
19
- end
20
-
21
- def errors
22
- @response.errors
23
- end
24
-
25
- end
26
-
27
- end
@@ -1,46 +0,0 @@
1
- module Spid
2
-
3
- class SsoRequest
4
-
5
- attr_accessor :settings
6
-
7
- def initialize spid_params
8
- spid_settings = Settings::Sso.new(spid_params)
9
- @settings = spid_settings.to_hash
10
- end
11
-
12
- def valid?
13
- if settings[:idp_sso_target_url].blank?
14
- raise 'Destination deve essere presente (impostare idp_sso_target_url)'
15
- end
16
- if settings[:authn_context].last != '1' && settings[:force_authn] != true
17
- raise 'ForceAuthn deve essere presente per livelli di aitenticazione diversi da SPIDL1 (impostare force_authn a true)'
18
- end
19
- if settings[:authn_context_comparison] != 'minimum'
20
- raise "AuthnContextComparison deve essere settato a 'minimum' (impostare authn_context_comparison a 'minimum')"
21
- end
22
- if settings[:protocol_binding] != Settings.saml_bindings[:post]
23
- raise "Issuer deve contenere l'attributo ProtocolBinding con binding POST (impostare protocl_binding a ':post')"
24
- end
25
- end
26
-
27
- def save
28
- valid?
29
- request = OneLogin::RubySaml::Authrequest.new
30
- saml_settings = OneLogin::RubySaml::Settings.new @settings
31
- @to_saml = request.create(saml_settings)
32
- self
33
- end
34
-
35
- def to_saml
36
- save and @to_saml
37
- end
38
-
39
- def self.create **settings
40
- obj = self.new(**settings)
41
- obj.save
42
- end
43
-
44
- end
45
-
46
- end
@@ -1,31 +0,0 @@
1
- module Spid
2
-
3
- class SsoResponse
4
-
5
- def initialize saml_response, sso_params
6
- response = OneLogin::RubySaml::Response.new(saml_response)
7
- settings = Settings::Sso.new(sso_params)
8
- saml_settings = OneLogin::RubySaml::Settings.new(settings.to_hash)
9
- response.settings = saml_settings
10
- @response = response
11
- end
12
-
13
- def valid?
14
- @response.is_valid?
15
- end
16
-
17
- def inspect
18
- @response.inspect
19
- end
20
-
21
- def session_index
22
- @response.sessionindex
23
- end
24
-
25
- def errors
26
- @response.errors
27
- end
28
-
29
- end
30
-
31
- end
@@ -1,14 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>Spid rails</title>
5
- <%= stylesheet_link_tag "spid-rails/application", media: "all" %>
6
- <%= javascript_include_tag "spid-rails/application" %>
7
- <%= csrf_meta_tags %>
8
- </head>
9
- <body>
10
-
11
- <%= yield %>
12
-
13
- </body>
14
- </html>
@@ -1,16 +0,0 @@
1
- Rails.application.routes.draw do
2
- mount Spid::Rails::Engine, at: Spid::Rails.mount_point
3
- end
4
-
5
- Spid::Rails::Engine.routes.draw do
6
- resource :metadata, only: :show,
7
- path: Spid::Rails.metadata_path
8
- resource :sso, only: [:new, :create],
9
- controller: :single_sign_ons,
10
- path: Spid::Rails.sso_path
11
- resource :slo, only: [:new, :create],
12
- controller: :single_logout_operations,
13
- path: Spid::Rails.slo_path do
14
- get '/', to: 'single_logout_operations#create'
15
- end
16
- end
@@ -1,21 +0,0 @@
1
- module Spid
2
- module Rails
3
-
4
- module Generators
5
-
6
- class IdpImporterGenerator < ::Rails::Generators::Base
7
-
8
- source_root File.expand_path('templates', __dir__)
9
-
10
- desc 'Crea il file di import custom degli Idp (config/spid-rails/idp_import.yml).'
11
-
12
- def create_import_file
13
- template 'idp_import.yml', './config/spid-rails/idp_import.yml'
14
- end
15
-
16
- end
17
-
18
- end
19
-
20
- end
21
- end
@@ -1,45 +0,0 @@
1
- module Spid
2
- module Rails
3
-
4
- module Generators
5
-
6
- class KeysGenerator < ::Rails::Generators::Base
7
- class_option :cn, type: :string, default: 'spid-rails-test', desc: 'Common name for the X509 certificate'
8
- class_option :size, type: :numeric, default: 1024, desc: 'RSA key bit size'
9
- class_option :digest, type: :string, default: 'SHA256', desc: 'Digest algorithm for signing the certificate'
10
- class_option :validity, type: :numeric, default: 1, desc: 'Certificate validity expressed in months'
11
-
12
- desc "Description:\n" +
13
- " Generate a RSA key and use it to generate a self-signed certificate in the keys path\n" +
14
- ' WARNING: this generator is ment to be used only for testing purpose.'
15
-
16
- def create_key
17
- @key = OpenSSL::PKey::RSA.new options[:size]
18
- end
19
-
20
- def create_certificate
21
- name = OpenSSL::X509::Name.parse "CN=#{options[:cn]}"
22
- sha_alg = OpenSSL::Digest.const_get(options[:digest]).new
23
- @cert = OpenSSL::X509::Certificate.new
24
- @cert.version = 2
25
- @cert.serial = 0
26
- @cert.not_before = Time.now
27
- @cert.not_after = @cert.not_before + options[:validity].months
28
- @cert.public_key = @key.public_key
29
- @cert.subject = name
30
- @cert.issuer = name
31
- @cert.sign @key, sha_alg
32
- end
33
-
34
- def write_keys
35
- path = './' + Spid::Rails.keys_path
36
- create_file path + 'private_key.pem', @key.to_pem
37
- create_file path + 'certificate.pem', @cert.to_pem
38
- end
39
-
40
- end
41
-
42
- end
43
-
44
- end
45
- end
@@ -1,11 +0,0 @@
1
- # Identity Providers are loaded on a per environment basis
2
-
3
- development:
4
- agid_test:
5
- metadata_url: https://idp.spid.gov.it:8080/assets/idp-metadata.xml
6
- validate_cert: false
7
-
8
- test:
9
- local_test:
10
- metadata_url: https://localhost:8080/assets/idp-metadata.xml
11
- validate_cert: false
@@ -1,79 +0,0 @@
1
- # Necessario override della classe originaria della libreria,
2
- # al fine di rendere conforme il nodo Issuer alle regole tecniche SPID,
3
- # (aggiunte righe 32 e 33)
4
-
5
- module OneLogin
6
- module RubySaml
7
- class Authrequest
8
-
9
- def create_xml_document(settings)
10
- time = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ')
11
-
12
- request_doc = XMLSecurity::Document.new
13
- request_doc.uuid = uuid
14
-
15
- root = request_doc.add_element 'samlp:AuthnRequest', { 'xmlns:samlp' => 'urn:oasis:names:tc:SAML:2.0:protocol', 'xmlns:saml' => 'urn:oasis:names:tc:SAML:2.0:assertion' }
16
- root.attributes['ID'] = uuid
17
- root.attributes['IssueInstant'] = time
18
- root.attributes['Version'] = '2.0'
19
- root.attributes['Destination'] = settings.idp_sso_target_url unless settings.idp_sso_target_url.nil?
20
- root.attributes['IsPassive'] = settings.passive unless settings.passive.nil?
21
- root.attributes['ProtocolBinding'] = settings.protocol_binding unless settings.protocol_binding.nil?
22
- root.attributes['AttributeConsumingServiceIndex'] = settings.attributes_index unless settings.attributes_index.nil?
23
- root.attributes['ForceAuthn'] = settings.force_authn unless settings.force_authn.nil?
24
-
25
- # Conditionally defined elements based on settings
26
- if settings.assertion_consumer_service_url != nil
27
- root.attributes['AssertionConsumerServiceURL'] = settings.assertion_consumer_service_url
28
- end
29
- # NameQualifier e Format da requisiti SPID
30
- if settings.issuer != nil
31
- issuer = root.add_element 'saml:Issuer', {
32
- 'NameQualifier' => settings.issuer,
33
- 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:entity'
34
- }
35
- issuer.text = settings.issuer
36
- end
37
- if settings.name_identifier_format != nil
38
- root.add_element 'samlp:NameIDPolicy', {
39
- # Might want to make AllowCreate a setting?
40
- 'AllowCreate' => 'true',
41
- 'Format' => settings.name_identifier_format
42
- }
43
- end
44
-
45
- if settings.authn_context || settings.authn_context_decl_ref
46
-
47
- if settings.authn_context_comparison != nil
48
- comparison = settings.authn_context_comparison
49
- else
50
- comparison = 'exact'
51
- end
52
-
53
- requested_context = root.add_element 'samlp:RequestedAuthnContext', {
54
- 'Comparison' => comparison,
55
- }
56
-
57
- if settings.authn_context != nil
58
- authn_contexts_class_ref = settings.authn_context.is_a?(Array) ? settings.authn_context : [settings.authn_context]
59
- authn_contexts_class_ref.each do |authn_context_class_ref|
60
- class_ref = requested_context.add_element 'saml:AuthnContextClassRef'
61
- class_ref.text = authn_context_class_ref
62
- end
63
- end
64
-
65
- if settings.authn_context_decl_ref != nil
66
- authn_contexts_decl_refs = settings.authn_context_decl_ref.is_a?(Array) ? settings.authn_context_decl_ref : [settings.authn_context_decl_ref]
67
- authn_contexts_decl_refs.each do |authn_context_decl_ref|
68
- decl_ref = requested_context.add_element 'saml:AuthnContextDeclRef'
69
- decl_ref.text = authn_context_decl_ref
70
- end
71
- end
72
- end
73
-
74
- request_doc
75
- end
76
-
77
- end
78
- end
79
- end