better_auth-saml 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +9 -0
- data/README.md +34 -0
- data/lib/better_auth/plugins/saml.rb +5 -0
- data/lib/better_auth/saml/version.rb +7 -0
- data/lib/better_auth/saml.rb +16 -0
- data/lib/better_auth/sso/constants.rb +20 -0
- data/lib/better_auth/sso/plugin/saml_core.rb +54 -0
- data/lib/better_auth/sso/plugin/saml_metadata_and_logout.rb +378 -0
- data/lib/better_auth/sso/plugin/saml_response.rb +167 -0
- data/lib/better_auth/sso/plugin/saml_validation_and_state.rb +183 -0
- data/lib/better_auth/sso/routes/saml_pipeline.rb +19 -0
- data/lib/better_auth/sso/saml/algorithms.rb +96 -0
- data/lib/better_auth/sso/saml/assertions.rb +21 -0
- data/lib/better_auth/sso/saml/error_codes.rb +24 -0
- data/lib/better_auth/sso/saml/parser.rb +19 -0
- data/lib/better_auth/sso/saml/timestamp.rb +19 -0
- data/lib/better_auth/sso/saml.rb +173 -0
- data/lib/better_auth/sso/saml_hooks.rb +21 -0
- data/lib/better_auth/sso/saml_state.rb +30 -0
- metadata +195 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "base64"
|
|
4
|
+
require "logger"
|
|
5
|
+
require "onelogin/ruby-saml"
|
|
6
|
+
require "uri"
|
|
7
|
+
|
|
8
|
+
module BetterAuth
|
|
9
|
+
module SSO
|
|
10
|
+
module SAML
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
DEFAULT_ATTRIBUTE_MAP = {
|
|
14
|
+
email: %w[email mail emailAddress Email EmailAddress],
|
|
15
|
+
name: %w[name displayName cn Name DisplayName],
|
|
16
|
+
given_name: %w[givenName firstName FirstName],
|
|
17
|
+
family_name: %w[familyName lastName LastName]
|
|
18
|
+
}.freeze
|
|
19
|
+
|
|
20
|
+
def sso_options(**options)
|
|
21
|
+
{
|
|
22
|
+
saml: {
|
|
23
|
+
auth_request_url: auth_request_url(**options),
|
|
24
|
+
parse_response: response_parser(**options)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def validate_config_algorithms(config = {}, **options)
|
|
30
|
+
Algorithms.validate_config(config, **options)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def validate_saml_algorithms(xml, **options)
|
|
34
|
+
Algorithms.validate(xml, **options)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def validate_single_assertion(saml_response)
|
|
38
|
+
Assertions.validate_single_assertion!(saml_response)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def auth_request_url(settings: nil, request_options: {}, **_options)
|
|
42
|
+
lambda do |provider:, relay_state:, context:|
|
|
43
|
+
config = BetterAuth::Plugins.normalize_hash(provider["samlConfig"] || provider[:samlConfig] || {})
|
|
44
|
+
saml_settings = settings.respond_to?(:call) ? settings.call(provider: provider, context: context, saml_config: config) : build_settings(provider, context, config, settings)
|
|
45
|
+
OneLogin::RubySaml::Authrequest.new.create(saml_settings, {RelayState: relay_state}.merge(request_options))
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def response_parser(settings: nil, response_options: {}, attribute_map: DEFAULT_ATTRIBUTE_MAP, **_options)
|
|
50
|
+
lambda do |raw_response:, provider:, context:|
|
|
51
|
+
config = BetterAuth::Plugins.normalize_hash(provider["samlConfig"] || provider[:samlConfig] || {})
|
|
52
|
+
saml_settings = settings.respond_to?(:call) ? settings.call(provider: provider, context: context, saml_config: config) : build_settings(provider, context, config, settings)
|
|
53
|
+
validate_response_xml!(raw_response, config)
|
|
54
|
+
response = OneLogin::RubySaml::Response.new(raw_response, {settings: saml_settings}.merge(response_options))
|
|
55
|
+
unless response.is_valid?
|
|
56
|
+
raise BetterAuth::APIError.new("BAD_REQUEST", message: "Invalid SAML response")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
attributes = response.attributes
|
|
60
|
+
mapping = BetterAuth::Plugins.normalize_hash(config[:mapping] || {})
|
|
61
|
+
email = mapped_attribute(attributes, mapping[:email]) || first_attribute(attributes, attribute_map.fetch(:email)) || response.nameid
|
|
62
|
+
raise BetterAuth::APIError.new("BAD_REQUEST", message: "Invalid SAML response") if email.to_s.empty?
|
|
63
|
+
|
|
64
|
+
given_name = mapped_attribute(attributes, mapping[:first_name]) || first_attribute(attributes, attribute_map.fetch(:given_name))
|
|
65
|
+
family_name = mapped_attribute(attributes, mapping[:last_name]) || first_attribute(attributes, attribute_map.fetch(:family_name))
|
|
66
|
+
name = [given_name, family_name].compact.join(" ").strip
|
|
67
|
+
name = mapped_attribute(attributes, mapping[:name]) || first_attribute(attributes, attribute_map.fetch(:name)) if name.empty?
|
|
68
|
+
extra_fields = mapped_extra_fields(attributes, mapping)
|
|
69
|
+
email_verified = mapping[:email_verified] ? mapped_attribute(attributes, mapping[:email_verified]) : false
|
|
70
|
+
extra_fields.merge(
|
|
71
|
+
email: email.to_s.downcase,
|
|
72
|
+
name: name.to_s.empty? ? email.to_s : name.to_s,
|
|
73
|
+
id: mapped_attribute(attributes, mapping[:id]) || assertion_identifier(response, email),
|
|
74
|
+
name_id: response.nameid,
|
|
75
|
+
session_index: response.sessionindex,
|
|
76
|
+
email_verified: (email_verified == false) ? false : !email_verified.to_s.empty?
|
|
77
|
+
)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def build_settings(provider, context, config, overrides = nil)
|
|
82
|
+
settings = overrides || OneLogin::RubySaml::Settings.new
|
|
83
|
+
provider_id = provider.fetch("providerId")
|
|
84
|
+
base_url = context.context.base_url
|
|
85
|
+
idp_metadata = BetterAuth::Plugins.respond_to?(:sso_saml_idp_metadata) ? BetterAuth::Plugins.sso_saml_idp_metadata(config) : {}
|
|
86
|
+
sso_service = BetterAuth::Plugins.respond_to?(:sso_saml_preferred_service) ? BetterAuth::Plugins.sso_saml_preferred_service(idp_metadata[:single_sign_on_service]) : nil
|
|
87
|
+
sso_service = BetterAuth::Plugins.normalize_hash(sso_service || {})
|
|
88
|
+
settings.assertion_consumer_service_url = if BetterAuth::Plugins.respond_to?(:sso_saml_acs_url?) && BetterAuth::Plugins.sso_saml_acs_url?(config[:callback_url])
|
|
89
|
+
config[:callback_url]
|
|
90
|
+
else
|
|
91
|
+
"#{base_url}/sso/saml2/sp/acs/#{URI.encode_www_form_component(provider_id)}"
|
|
92
|
+
end
|
|
93
|
+
settings.sp_entity_id = config.dig(:sp_metadata, :entity_id) || config[:audience] || "#{base_url}/sso/saml2/sp/metadata?providerId=#{URI.encode_www_form_component(provider_id)}"
|
|
94
|
+
settings.idp_entity_id = idp_metadata[:entity_id] || provider["issuer"] || provider[:issuer]
|
|
95
|
+
settings.idp_sso_service_url = config[:entry_point] || sso_service[:location]
|
|
96
|
+
settings.idp_cert = config[:cert] || idp_metadata[:cert] unless (config[:cert] || idp_metadata[:cert]).to_s.empty?
|
|
97
|
+
settings.name_identifier_format = config[:identifier_format] unless config[:identifier_format].to_s.empty?
|
|
98
|
+
private_key = config.dig(:sp_metadata, :private_key) || config[:private_key] || config[:sp_private_key]
|
|
99
|
+
authn_requests_signed = config.fetch(:authn_requests_signed, config[:want_authn_requests_signed])
|
|
100
|
+
if authn_requests_signed && private_key.to_s.empty?
|
|
101
|
+
raise BetterAuth::APIError.new("BAD_REQUEST", message: "SAML authnRequestsSigned requires privateKey")
|
|
102
|
+
end
|
|
103
|
+
settings.private_key = private_key unless private_key.to_s.empty?
|
|
104
|
+
certificate = config.dig(:sp_metadata, :certificate) || config[:sp_certificate]
|
|
105
|
+
certificate ||= config[:certificate] if config[:certificate].is_a?(String)
|
|
106
|
+
settings.certificate = certificate unless certificate.to_s.empty?
|
|
107
|
+
settings.security[:want_assertions_signed] = config.fetch(:want_assertions_signed, true)
|
|
108
|
+
settings.security[:want_messages_signed] = config.fetch(:want_messages_signed, false)
|
|
109
|
+
settings.security[:want_assertions_encrypted] = config.fetch(:want_assertions_encrypted, false)
|
|
110
|
+
settings.security[:authn_requests_signed] = !!authn_requests_signed
|
|
111
|
+
settings.security[:strict_audience_validation] = true
|
|
112
|
+
settings.security[:digest_method] = config[:digest_algorithm] || XMLSecurity::Document::SHA256
|
|
113
|
+
settings.security[:signature_method] = if config[:signature_algorithm]
|
|
114
|
+
BetterAuth::Plugins.sso_normalize_saml_signature_algorithm(config[:signature_algorithm])
|
|
115
|
+
else
|
|
116
|
+
XMLSecurity::Document::RSA_SHA256
|
|
117
|
+
end
|
|
118
|
+
settings
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def validate_response_xml!(raw_response, config)
|
|
122
|
+
BetterAuth::Plugins.sso_validate_single_saml_assertion!(raw_response)
|
|
123
|
+
xml = Base64.decode64(raw_response.to_s)
|
|
124
|
+
BetterAuth::Plugins.sso_validate_saml_algorithms!(
|
|
125
|
+
xml,
|
|
126
|
+
on_deprecated: config.fetch(:on_deprecated_algorithm, "reject"),
|
|
127
|
+
allowed_signature_algorithms: config[:allowed_signature_algorithms],
|
|
128
|
+
allowed_digest_algorithms: config[:allowed_digest_algorithms],
|
|
129
|
+
allowed_key_encryption_algorithms: config[:allowed_key_encryption_algorithms],
|
|
130
|
+
allowed_data_encryption_algorithms: config[:allowed_data_encryption_algorithms]
|
|
131
|
+
)
|
|
132
|
+
rescue BetterAuth::APIError
|
|
133
|
+
raise BetterAuth::APIError.new("BAD_REQUEST", message: "Invalid SAML response")
|
|
134
|
+
rescue
|
|
135
|
+
raise BetterAuth::APIError.new("BAD_REQUEST", message: "Invalid SAML response")
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def first_attribute(attributes, names)
|
|
139
|
+
Array(names).each do |name|
|
|
140
|
+
value = attribute_value(attributes, name)
|
|
141
|
+
value = value.first if value.is_a?(Array)
|
|
142
|
+
return value unless value.to_s.empty?
|
|
143
|
+
end
|
|
144
|
+
nil
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def mapped_attribute(attributes, name)
|
|
148
|
+
return nil if name.to_s.empty?
|
|
149
|
+
|
|
150
|
+
value = attribute_value(attributes, name)
|
|
151
|
+
value = value.first if value.is_a?(Array)
|
|
152
|
+
value unless value.to_s.empty?
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def mapped_extra_fields(attributes, mapping)
|
|
156
|
+
BetterAuth::Plugins.normalize_hash(mapping[:extra_fields] || {}).each_with_object({}) do |(target, source), result|
|
|
157
|
+
result[target] = mapped_attribute(attributes, source)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def attribute_value(attributes, name)
|
|
162
|
+
[name, name.to_s, BetterAuth::Plugins.normalize_key(name)].each do |key|
|
|
163
|
+
return attributes[key] if attributes.respond_to?(:key?) && attributes.key?(key)
|
|
164
|
+
end
|
|
165
|
+
attributes[name] || attributes[name.to_s] || attributes[BetterAuth::Plugins.normalize_key(name)]
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def assertion_identifier(response, email)
|
|
169
|
+
response.assertion_id || response.nameid || response.sessionindex || email
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BetterAuth
|
|
4
|
+
module SSO
|
|
5
|
+
module SAMLHooks
|
|
6
|
+
module_function
|
|
7
|
+
|
|
8
|
+
def merge_options(sso_options = {}, saml_options = {})
|
|
9
|
+
sso_options = BetterAuth::Plugins.normalize_hash(sso_options || {})
|
|
10
|
+
saml_options = BetterAuth::Plugins.normalize_hash(saml_options || {})
|
|
11
|
+
sso_options.merge(saml_options) do |key, old_value, new_value|
|
|
12
|
+
if key == :saml
|
|
13
|
+
BetterAuth::Plugins.normalize_hash(old_value || {}).merge(BetterAuth::Plugins.normalize_hash(new_value || {}))
|
|
14
|
+
else
|
|
15
|
+
new_value
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BetterAuth
|
|
4
|
+
module SSO
|
|
5
|
+
module SAMLState
|
|
6
|
+
module_function
|
|
7
|
+
|
|
8
|
+
def generate_relay_state(ctx, link = nil, additional_data = {})
|
|
9
|
+
callback_url = BetterAuth::Plugins.sso_fetch(ctx.body, :callback_url)
|
|
10
|
+
raise BetterAuth::APIError.new("BAD_REQUEST", message: "callbackURL is required") if callback_url.to_s.empty?
|
|
11
|
+
|
|
12
|
+
extra = (additional_data == false) ? {} : (additional_data || {})
|
|
13
|
+
BetterAuth::Plugins.sso_generate_saml_relay_state(
|
|
14
|
+
ctx,
|
|
15
|
+
extra.merge(
|
|
16
|
+
callbackURL: callback_url,
|
|
17
|
+
errorURL: BetterAuth::Plugins.sso_fetch(ctx.body, :error_callback_url),
|
|
18
|
+
newUserURL: BetterAuth::Plugins.sso_fetch(ctx.body, :new_user_callback_url),
|
|
19
|
+
requestSignUp: BetterAuth::Plugins.sso_fetch(ctx.body, :request_sign_up),
|
|
20
|
+
link: link
|
|
21
|
+
)
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def parse_relay_state(ctx)
|
|
26
|
+
BetterAuth::Plugins.sso_parse_saml_relay_state(ctx, BetterAuth::Plugins.sso_fetch(ctx.body, :relay_state))
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: better_auth-saml
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.10.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Sebastian Sala
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: better_auth
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0.1'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0.1'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: base64
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0.2'
|
|
33
|
+
- - "<"
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '1.0'
|
|
36
|
+
type: :runtime
|
|
37
|
+
prerelease: false
|
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '0.2'
|
|
43
|
+
- - "<"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '1.0'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: logger
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
requirements:
|
|
50
|
+
- - ">="
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '1.6'
|
|
53
|
+
- - "<"
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: '2.0'
|
|
56
|
+
type: :runtime
|
|
57
|
+
prerelease: false
|
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - ">="
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '1.6'
|
|
63
|
+
- - "<"
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '2.0'
|
|
66
|
+
- !ruby/object:Gem::Dependency
|
|
67
|
+
name: ruby-saml
|
|
68
|
+
requirement: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - "~>"
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '1.18'
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 1.18.1
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '1.18'
|
|
83
|
+
- - ">="
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: 1.18.1
|
|
86
|
+
- !ruby/object:Gem::Dependency
|
|
87
|
+
name: bundler
|
|
88
|
+
requirement: !ruby/object:Gem::Requirement
|
|
89
|
+
requirements:
|
|
90
|
+
- - "~>"
|
|
91
|
+
- !ruby/object:Gem::Version
|
|
92
|
+
version: '2.5'
|
|
93
|
+
type: :development
|
|
94
|
+
prerelease: false
|
|
95
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
96
|
+
requirements:
|
|
97
|
+
- - "~>"
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: '2.5'
|
|
100
|
+
- !ruby/object:Gem::Dependency
|
|
101
|
+
name: minitest
|
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
|
103
|
+
requirements:
|
|
104
|
+
- - "~>"
|
|
105
|
+
- !ruby/object:Gem::Version
|
|
106
|
+
version: '5.25'
|
|
107
|
+
type: :development
|
|
108
|
+
prerelease: false
|
|
109
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
110
|
+
requirements:
|
|
111
|
+
- - "~>"
|
|
112
|
+
- !ruby/object:Gem::Version
|
|
113
|
+
version: '5.25'
|
|
114
|
+
- !ruby/object:Gem::Dependency
|
|
115
|
+
name: rake
|
|
116
|
+
requirement: !ruby/object:Gem::Requirement
|
|
117
|
+
requirements:
|
|
118
|
+
- - "~>"
|
|
119
|
+
- !ruby/object:Gem::Version
|
|
120
|
+
version: '13.2'
|
|
121
|
+
type: :development
|
|
122
|
+
prerelease: false
|
|
123
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
124
|
+
requirements:
|
|
125
|
+
- - "~>"
|
|
126
|
+
- !ruby/object:Gem::Version
|
|
127
|
+
version: '13.2'
|
|
128
|
+
- !ruby/object:Gem::Dependency
|
|
129
|
+
name: standardrb
|
|
130
|
+
requirement: !ruby/object:Gem::Requirement
|
|
131
|
+
requirements:
|
|
132
|
+
- - "~>"
|
|
133
|
+
- !ruby/object:Gem::Version
|
|
134
|
+
version: '1.0'
|
|
135
|
+
type: :development
|
|
136
|
+
prerelease: false
|
|
137
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
138
|
+
requirements:
|
|
139
|
+
- - "~>"
|
|
140
|
+
- !ruby/object:Gem::Version
|
|
141
|
+
version: '1.0'
|
|
142
|
+
description: SAML 2.0 service provider primitives and plugin extensions for Better
|
|
143
|
+
Auth Ruby enterprise SSO. Pair with better_auth-sso for provider management or require
|
|
144
|
+
directly for SAML-only integrations.
|
|
145
|
+
email:
|
|
146
|
+
- sebastian.sala.tech@gmail.com
|
|
147
|
+
executables: []
|
|
148
|
+
extensions: []
|
|
149
|
+
extra_rdoc_files: []
|
|
150
|
+
files:
|
|
151
|
+
- CHANGELOG.md
|
|
152
|
+
- README.md
|
|
153
|
+
- lib/better_auth/plugins/saml.rb
|
|
154
|
+
- lib/better_auth/saml.rb
|
|
155
|
+
- lib/better_auth/saml/version.rb
|
|
156
|
+
- lib/better_auth/sso/constants.rb
|
|
157
|
+
- lib/better_auth/sso/plugin/saml_core.rb
|
|
158
|
+
- lib/better_auth/sso/plugin/saml_metadata_and_logout.rb
|
|
159
|
+
- lib/better_auth/sso/plugin/saml_response.rb
|
|
160
|
+
- lib/better_auth/sso/plugin/saml_validation_and_state.rb
|
|
161
|
+
- lib/better_auth/sso/routes/saml_pipeline.rb
|
|
162
|
+
- lib/better_auth/sso/saml.rb
|
|
163
|
+
- lib/better_auth/sso/saml/algorithms.rb
|
|
164
|
+
- lib/better_auth/sso/saml/assertions.rb
|
|
165
|
+
- lib/better_auth/sso/saml/error_codes.rb
|
|
166
|
+
- lib/better_auth/sso/saml/parser.rb
|
|
167
|
+
- lib/better_auth/sso/saml/timestamp.rb
|
|
168
|
+
- lib/better_auth/sso/saml_hooks.rb
|
|
169
|
+
- lib/better_auth/sso/saml_state.rb
|
|
170
|
+
homepage: https://github.com/sebasxsala/better-auth-rb
|
|
171
|
+
licenses:
|
|
172
|
+
- MIT
|
|
173
|
+
metadata:
|
|
174
|
+
homepage_uri: https://github.com/sebasxsala/better-auth-rb
|
|
175
|
+
source_code_uri: https://github.com/sebasxsala/better-auth-rb
|
|
176
|
+
changelog_uri: https://github.com/sebasxsala/better-auth-rb/blob/main/packages/better_auth-saml/CHANGELOG.md
|
|
177
|
+
bug_tracker_uri: https://github.com/sebasxsala/better-auth-rb/issues
|
|
178
|
+
rdoc_options: []
|
|
179
|
+
require_paths:
|
|
180
|
+
- lib
|
|
181
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
182
|
+
requirements:
|
|
183
|
+
- - ">="
|
|
184
|
+
- !ruby/object:Gem::Version
|
|
185
|
+
version: 3.2.0
|
|
186
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
187
|
+
requirements:
|
|
188
|
+
- - ">="
|
|
189
|
+
- !ruby/object:Gem::Version
|
|
190
|
+
version: '0'
|
|
191
|
+
requirements: []
|
|
192
|
+
rubygems_version: 3.6.9
|
|
193
|
+
specification_version: 4
|
|
194
|
+
summary: SAML 2.0 SP support for Better Auth Ruby SSO
|
|
195
|
+
test_files: []
|