-
-
Notifications
You must be signed in to change notification settings - Fork 591
Expand file tree
/
Copy pathsettings.rb
More file actions
289 lines (250 loc) · 9.9 KB
/
settings.rb
File metadata and controls
289 lines (250 loc) · 9.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
require "xml_security"
require "onelogin/ruby-saml/attribute_service"
require "onelogin/ruby-saml/utils"
require "onelogin/ruby-saml/validation_error"
# Only supports SAML 2.0
module OneLogin
module RubySaml
# SAML2 Toolkit Settings
#
class Settings
def initialize(overrides = {}, keep_security_attributes = false)
if keep_security_attributes
security_attributes = overrides.delete(:security) || {}
config = DEFAULTS.merge(overrides)
config[:security] = DEFAULTS[:security].merge(security_attributes)
else
config = DEFAULTS.merge(overrides)
end
config.each do |k,v|
acc = "#{k.to_s}=".to_sym
if respond_to? acc
value = v.is_a?(Hash) ? v.dup : v
send(acc, value)
end
end
@attribute_consuming_service = AttributeService.new
end
# IdP Data
attr_accessor :idp_entity_id
attr_writer :idp_sso_service_url
attr_writer :idp_slo_service_url
attr_accessor :idp_slo_response_service_url
attr_accessor :idp_cert
attr_accessor :idp_cert_fingerprint
attr_accessor :idp_cert_fingerprint_algorithm
attr_accessor :idp_cert_multi
attr_accessor :idp_attribute_names
attr_accessor :idp_name_qualifier
attr_accessor :valid_until
# SP Data
attr_writer :sp_entity_id
attr_accessor :assertion_consumer_service_url
attr_reader :assertion_consumer_service_binding
attr_writer :single_logout_service_url
attr_accessor :sp_name_qualifier
attr_accessor :name_identifier_format
attr_accessor :name_identifier_value
attr_accessor :name_identifier_value_requested
attr_accessor :sessionindex
attr_accessor :compress_request
attr_accessor :compress_response
attr_accessor :double_quote_xml_attribute_values
attr_accessor :message_max_bytesize
attr_accessor :passive
attr_reader :protocol_binding
attr_accessor :attributes_index
attr_accessor :force_authn
attr_accessor :certificate
attr_accessor :certificate_new
attr_accessor :private_key
attr_accessor :authn_context
attr_accessor :authn_context_comparison
attr_accessor :authn_context_decl_ref
attr_reader :attribute_consuming_service
# Work-flow
attr_accessor :security
attr_accessor :soft
# Deprecated
attr_accessor :assertion_consumer_logout_service_url
attr_reader :assertion_consumer_logout_service_binding
attr_accessor :issuer
attr_accessor :idp_sso_target_url
attr_accessor :idp_slo_target_url
# @return [String] IdP Single Sign On Service URL
#
def idp_sso_service_url
@idp_sso_service_url || @idp_sso_target_url
end
# @return [String] IdP Single Logout Service URL
#
def idp_slo_service_url
@idp_slo_service_url || @idp_slo_target_url
end
# @return [String] IdP Single Sign On Service Binding
#
def idp_sso_service_binding
@idp_sso_service_binding || idp_binding_from_embed_sign
end
# Setter for IdP Single Sign On Service Binding
# @param value [String, Symbol].
#
def idp_sso_service_binding=(value)
@idp_sso_service_binding = get_binding(value)
end
# @return [String] IdP Single Logout Service Binding
#
def idp_slo_service_binding
@idp_slo_service_binding || idp_binding_from_embed_sign
end
# Setter for IdP Single Logout Service Binding
# @param value [String, Symbol].
#
def idp_slo_service_binding=(value)
@idp_slo_service_binding = get_binding(value)
end
# @return [String] SP Entity ID
#
def sp_entity_id
@sp_entity_id || @issuer
end
# Setter for SP Protocol Binding
# @param value [String, Symbol].
#
def protocol_binding=(value)
@protocol_binding = get_binding(value)
end
# Setter for SP Assertion Consumer Service Binding
# @param value [String, Symbol].
#
def assertion_consumer_service_binding=(value)
@assertion_consumer_service_binding = get_binding(value)
end
# @return [String] Single Logout Service URL.
#
def single_logout_service_url
@single_logout_service_url || @assertion_consumer_logout_service_url
end
# @return [String] Single Logout Service Binding.
#
def single_logout_service_binding
@single_logout_service_binding || @assertion_consumer_logout_service_binding
end
# Setter for Single Logout Service Binding.
#
# (Currently we only support "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect")
# @param value [String, Symbol]
#
def single_logout_service_binding=(value)
@single_logout_service_binding = get_binding(value)
end
# @deprecated Setter for legacy Single Logout Service Binding parameter.
#
# (Currently we only support "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect")
# @param value [String, Symbol]
#
def assertion_consumer_logout_service_binding=(value)
@assertion_consumer_logout_service_binding = get_binding(value)
end
# Calculates the fingerprint of the IdP x509 certificate.
# @return [String] The fingerprint
#
def get_fingerprint
idp_cert_fingerprint || begin
idp_cert = get_idp_cert
if idp_cert
fingerprint_alg = XMLSecurity::BaseDocument.new.algorithm(idp_cert_fingerprint_algorithm).new
fingerprint_alg.hexdigest(idp_cert.to_der).upcase.scan(/../).join(":")
end
end
end
# @return [OpenSSL::X509::Certificate|nil] Build the IdP certificate from the settings (previously format it)
#
def get_idp_cert
return nil if idp_cert.nil? || idp_cert.empty?
formatted_cert = OneLogin::RubySaml::Utils.format_cert(idp_cert)
OpenSSL::X509::Certificate.new(formatted_cert)
end
# @return [Hash with 2 arrays of OpenSSL::X509::Certificate] Build multiple IdP certificates from the settings.
#
def get_idp_cert_multi
return nil if idp_cert_multi.nil? || idp_cert_multi.empty?
raise ArgumentError.new("Invalid value for idp_cert_multi") if not idp_cert_multi.is_a?(Hash)
certs = {:signing => [], :encryption => [] }
if idp_cert_multi.key?(:signing) and not idp_cert_multi[:signing].empty?
idp_cert_multi[:signing].each do |idp_cert|
formatted_cert = OneLogin::RubySaml::Utils.format_cert(idp_cert)
certs[:signing].push(OpenSSL::X509::Certificate.new(formatted_cert))
end
end
if idp_cert_multi.key?(:encryption) and not idp_cert_multi[:encryption].empty?
idp_cert_multi[:encryption].each do |idp_cert|
formatted_cert = OneLogin::RubySaml::Utils.format_cert(idp_cert)
certs[:encryption].push(OpenSSL::X509::Certificate.new(formatted_cert))
end
end
certs
end
# @return [OpenSSL::X509::Certificate|nil] Build the SP certificate from the settings (previously format it)
#
def get_sp_cert
return nil if certificate.nil? || certificate.empty?
formatted_cert = OneLogin::RubySaml::Utils.format_cert(certificate)
cert = OpenSSL::X509::Certificate.new(formatted_cert)
if security[:check_sp_cert_expiration]
if OneLogin::RubySaml::Utils.is_cert_expired(cert)
raise OneLogin::RubySaml::ValidationError.new("The SP certificate expired.")
end
end
cert
end
# @return [OpenSSL::X509::Certificate|nil] Build the New SP certificate from the settings (previously format it)
#
def get_sp_cert_new
return nil if certificate_new.nil? || certificate_new.empty?
formatted_cert = OneLogin::RubySaml::Utils.format_cert(certificate_new)
OpenSSL::X509::Certificate.new(formatted_cert)
end
# @return [OpenSSL::PKey::RSA] Build the SP private from the settings (previously format it)
#
def get_sp_key
return nil if private_key.nil? || private_key.empty?
formatted_private_key = OneLogin::RubySaml::Utils.format_private_key(private_key)
OpenSSL::PKey::RSA.new(formatted_private_key)
end
private
def idp_binding_from_embed_sign
security[:embed_sign] ? Utils::BINDINGS[:post] : Utils::BINDINGS[:redirect]
end
def get_binding(value)
return unless value
Utils::BINDINGS[value.to_sym] || value
end
DEFAULTS = {
:assertion_consumer_service_binding => Utils::BINDINGS[:post],
:single_logout_service_binding => Utils::BINDINGS[:redirect],
:idp_cert_fingerprint_algorithm => XMLSecurity::Document::SHA1,
:compress_request => true,
:compress_response => true,
:message_max_bytesize => 250000,
:soft => true,
:double_quote_xml_attribute_values => false,
:security => {
:authn_requests_signed => false,
:logout_requests_signed => false,
:logout_responses_signed => false,
:want_assertions_signed => false,
:want_assertions_encrypted => false,
:want_name_id => false,
:metadata_signed => false,
:embed_sign => false, # Deprecated
:digest_method => XMLSecurity::Document::SHA1,
:signature_method => XMLSecurity::Document::RSA_SHA1,
:check_idp_cert_expiration => false,
:check_sp_cert_expiration => false,
:strict_audience_validation => false,
}.freeze
}.freeze
end
end
end