omniauth-ldap 2.3.1 → 2.3.3
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +48 -1
- data/CONTRIBUTING.md +6 -3
- data/FUNDING.md +7 -10
- data/LICENSE.txt +1 -0
- data/README.md +217 -17
- data/lib/omniauth/strategies/ldap.rb +223 -29
- data/lib/omniauth-ldap/adaptor.rb +210 -16
- data/lib/omniauth-ldap/version.rb +10 -1
- data/lib/omniauth-ldap.rb +8 -0
- data/sig/omniauth/ldap/adaptor.rbs +24 -6
- data/sig/omniauth/strategies/ldap.rbs +6 -3
- data/sig/omniauth-ldap.rbs +5 -0
- data/sig/rbs/net-ldap.rbs +17 -1
- data/sig/rbs/net-ntlm.rbs +2 -1
- data.tar.gz.sig +0 -0
- metadata +6 -34
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8bcc01a9129d0db019b5530a9bf5f7b5241f9eacba974d5c5585b4620a8d140b
|
|
4
|
+
data.tar.gz: 5eb2878ad0b0d471d60dfb4596baddb077cde9c26499ad1d2c3f661a96f1b242
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f3d489556fa774b9865a3138dcce9f9eef4d2afedbeff2d0bdb5ce239a3b18dd430bcdf2438b77135434e511750a50236fb0e6902ad00ce16e60d1021058fb41
|
|
7
|
+
data.tar.gz: 4d544ca2868b9c0eb8d283dbc996b305bd1ca3d8070c9b5d342dc3de6d8d98206f197926da1bfd9f9b57e03728f8d96932a824b540fce3f4c66efd7e8ae08630
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -32,6 +32,49 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
32
32
|
|
|
33
33
|
### Security
|
|
34
34
|
|
|
35
|
+
## [2.3.3] - 2025-11-10
|
|
36
|
+
|
|
37
|
+
- TAG: [v2.3.3][2.3.3t]
|
|
38
|
+
- COVERAGE: 97.61% -- 286/293 lines in 4 files
|
|
39
|
+
- BRANCH COVERAGE: 79.69% -- 102/128 branches in 4 files
|
|
40
|
+
- 94.44% documented
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
|
|
44
|
+
- Documentation cleanup & updates
|
|
45
|
+
- YARD documentation covering 94% of the code
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
- kettle-dev v1.1.54
|
|
50
|
+
|
|
51
|
+
## [2.3.2] - 2025-11-06
|
|
52
|
+
|
|
53
|
+
- TAG: [v2.3.2][2.3.2t]
|
|
54
|
+
- COVERAGE: 97.64% -- 290/297 lines in 4 files
|
|
55
|
+
- BRANCH COVERAGE: 79.69% -- 102/128 branches in 4 files
|
|
56
|
+
- 44.12% documented
|
|
57
|
+
|
|
58
|
+
### Added
|
|
59
|
+
|
|
60
|
+
- Support for SCRIPT_NAME for proper URL generation
|
|
61
|
+
- behind certain proxies/load balancers, or
|
|
62
|
+
- under a subdirectory
|
|
63
|
+
- Password Policy for LDAP Directories
|
|
64
|
+
- password_policy: true|false (default: false)
|
|
65
|
+
- on authentication failure, if the server returns password policy controls, the info will be included in the failure message
|
|
66
|
+
- https://datatracker.ietf.org/doc/html/draft-behera-ldap-password-policy-11
|
|
67
|
+
- Support for JSON bodies
|
|
68
|
+
- Support custom LDAP attributes mapping
|
|
69
|
+
- Documentation of TLS verification options
|
|
70
|
+
|
|
71
|
+
### Changed
|
|
72
|
+
|
|
73
|
+
- Make support for OmniAuth v1.2+ explicit
|
|
74
|
+
- Versions < 1.2 do not support SCRIPT_NAME properly, and may cause other issues
|
|
75
|
+
- Raise a distinct error when LDAP server is unreachable
|
|
76
|
+
- Previously raised an invalid credentials authentication failure error, which is technically incorrect
|
|
77
|
+
|
|
35
78
|
## [2.3.1] - 2025-11-05
|
|
36
79
|
|
|
37
80
|
- TAG: [v2.3.1][2.3.1t]
|
|
@@ -197,6 +240,10 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
197
240
|
[1.0.0]: https://github.com/omniauth/omniauth-ldap/compare/5656da80d4193e0d0584f44bac493a87695e580f...v1.0.0
|
|
198
241
|
[1.0.0t]: https://github.com/omniauth/omniauth-ldap/releases/tag/v1.0.0
|
|
199
242
|
|
|
200
|
-
[Unreleased]: https://github.com/omniauth/omniauth-ldap/compare/v2.3.
|
|
243
|
+
[Unreleased]: https://github.com/omniauth/omniauth-ldap/compare/v2.3.3...HEAD
|
|
244
|
+
[2.3.3]: https://github.com/omniauth/omniauth-ldap/compare/v2.3.2...v2.3.3
|
|
245
|
+
[2.3.3t]: https://github.com/omniauth/omniauth-ldap/releases/tag/v2.3.3
|
|
246
|
+
[2.3.2]: https://github.com/omniauth/omniauth-ldap/compare/v2.3.1...v2.3.2
|
|
247
|
+
[2.3.2t]: https://github.com/omniauth/omniauth-ldap/releases/tag/v2.3.2
|
|
201
248
|
[2.3.1]: https://github.com/omniauth/omniauth-ldap/compare/v2.0.0...v2.3.1
|
|
202
249
|
[2.3.1t]: https://github.com/omniauth/omniauth-ldap/releases/tag/v2.3.1
|
data/CONTRIBUTING.md
CHANGED
|
@@ -24,13 +24,13 @@ Follow these instructions:
|
|
|
24
24
|
|
|
25
25
|
## Executables vs Rake tasks
|
|
26
26
|
|
|
27
|
-
Executables shipped by dependencies, such as
|
|
27
|
+
Executables shipped by dependencies, such as kettle-dev, and stone_checksums, are available
|
|
28
28
|
after running `bin/setup`. These include:
|
|
29
29
|
|
|
30
30
|
- gem_checksums
|
|
31
31
|
- kettle-changelog
|
|
32
32
|
- kettle-commit-msg
|
|
33
|
-
-
|
|
33
|
+
- kettle-dev-setup
|
|
34
34
|
- kettle-dvcs
|
|
35
35
|
- kettle-pre-release
|
|
36
36
|
- kettle-readme-backers
|
|
@@ -68,7 +68,9 @@ GitHub API and CI helpers
|
|
|
68
68
|
Releasing and signing
|
|
69
69
|
- SKIP_GEM_SIGNING: If set, skip gem signing during build/release
|
|
70
70
|
- GEM_CERT_USER: Username for selecting your public cert in `certs/<USER>.pem` (defaults to $USER)
|
|
71
|
-
- SOURCE_DATE_EPOCH: Reproducible build timestamp.
|
|
71
|
+
- SOURCE_DATE_EPOCH: Reproducible build timestamp.
|
|
72
|
+
- `kettle-release` will set this automatically for the session.
|
|
73
|
+
- Not needed on bundler >= 2.7.0, as reproducible builds have become the default.
|
|
72
74
|
|
|
73
75
|
Git hooks and commit message helpers (exe/kettle-commit-msg)
|
|
74
76
|
- GIT_HOOK_BRANCH_VALIDATE: Branch name validation mode (e.g., `jira`) or `false` to disable
|
|
@@ -166,6 +168,7 @@ NOTE: To build without signing the gem set `SKIP_GEM_SIGNING` to any value in th
|
|
|
166
168
|
1. Update version.rb to contain the correct version-to-be-released.
|
|
167
169
|
2. Run `bundle exec kettle-changelog`.
|
|
168
170
|
3. Run `bundle exec kettle-release`.
|
|
171
|
+
4. Stay awake and monitor the release process for any errors, and answer any prompts.
|
|
169
172
|
|
|
170
173
|
#### Manual process
|
|
171
174
|
|
data/FUNDING.md
CHANGED
|
@@ -6,7 +6,7 @@ Many paths lead to being a sponsor or a backer of this project. Are you on such
|
|
|
6
6
|
|
|
7
7
|
[![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal]
|
|
8
8
|
|
|
9
|
-
[![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS
|
|
9
|
+
[![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS efforts using Patreon][🖇patreon-img]][🖇patreon]
|
|
10
10
|
|
|
11
11
|
[⛳liberapay-img]: https://img.shields.io/liberapay/goal/pboling.svg?logo=liberapay&color=a51611&style=flat
|
|
12
12
|
[⛳liberapay]: https://liberapay.com/pboling/donate
|
|
@@ -27,11 +27,11 @@ Many paths lead to being a sponsor or a backer of this project. Are you on such
|
|
|
27
27
|
|
|
28
28
|
<!-- RELEASE-NOTES-FOOTER-END -->
|
|
29
29
|
|
|
30
|
-
# 🤑
|
|
30
|
+
# 🤑 A request for help
|
|
31
31
|
|
|
32
32
|
Maintainers have teeth and need to pay their dentists.
|
|
33
|
-
After getting laid off in an RIF in March and
|
|
34
|
-
I
|
|
33
|
+
After getting laid off in an RIF in March, and encountering difficulty finding a new one,
|
|
34
|
+
I began spending most of my time building open source tools.
|
|
35
35
|
I'm hoping to be able to pay for my kids' health insurance this month,
|
|
36
36
|
so if you value the work I am doing, I need your support.
|
|
37
37
|
Please consider sponsoring me or the project.
|
|
@@ -40,16 +40,13 @@ To join the community or get help 👇️ Join the Discord.
|
|
|
40
40
|
|
|
41
41
|
[![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite]
|
|
42
42
|
|
|
43
|
-
To say "thanks
|
|
43
|
+
To say "thanks!" ☝️ Join the Discord or 👇️ send money.
|
|
44
44
|
|
|
45
|
-
[![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay
|
|
45
|
+
[![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal]
|
|
46
46
|
|
|
47
47
|
# Another Way to Support Open Source Software
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
>—Anne Frank
|
|
51
|
-
|
|
52
|
-
I’m driven by a passion to foster a thriving open-source community – a space where people can tackle complex problems, no matter how small. Revitalizing libraries that have fallen into disrepair, and building new libraries focused on solving real-world challenges, are my passions — totaling 79 hours of FLOSS coding over just the past seven days, a pretty regular week for me. I was recently affected by layoffs, and the tech jobs market is unwelcoming. I’m reaching out here because your support would significantly aid my efforts to provide for my family, and my farm (11 🐔 chickens, 2 🐶 dogs, 3 🐰 rabbits, 8 🐈 cats).
|
|
49
|
+
I’m driven by a passion to foster a thriving open-source community – a space where people can tackle complex problems, no matter how small. Revitalizing libraries that have fallen into disrepair, and building new libraries focused on solving real-world challenges, are my passions. I was recently affected by layoffs, and the tech jobs market is unwelcoming. I’m reaching out here because your support would significantly aid my efforts to provide for my family, and my farm (11 🐔 chickens, 2 🐶 dogs, 3 🐰 rabbits, 8 🐈 cats).
|
|
53
50
|
|
|
54
51
|
If you work at a company that uses my work, please encourage them to support me as a corporate sponsor. My work on gems you use might show up in `bundle fund`.
|
|
55
52
|
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
# 📁 OmniAuth LDAP
|
|
40
40
|
|
|
41
|
-
[![Version][👽versioni]][👽version] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] [![License: MIT][📄license-img]][📄license-ref] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![Open Source Helpers][👽oss-helpi]][👽oss-help] [![CodeCov Test Coverage][🏀codecovi]][🏀codecov] [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls] [![
|
|
41
|
+
[![Version][👽versioni]][👽version] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] [![License: MIT][📄license-img]][📄license-ref] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![Open Source Helpers][👽oss-helpi]][👽oss-help] [![CodeCov Test Coverage][🏀codecovi]][🏀codecov] [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Runtime Dependencies @ HEAD][🚎12-crh-wfi]][🚎12-crh-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![CI Truffle Ruby][🚎9-t-wfi]][🚎9-t-wf] [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf] [![Deps Locked][🚎13-🔒️-wfi]][🚎13-🔒️-wf] [![Deps Unlocked][🚎14-🔓️-wfi]][🚎14-🔓️-wf] [![CI Supported][🚎6-s-wfi]][🚎6-s-wf] [![CI Legacy][🚎4-lg-wfi]][🚎4-lg-wf] [![CI Unsupported][🚎7-us-wfi]][🚎7-us-wf] [![CI Ancient][🚎1-an-wfi]][🚎1-an-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Apache SkyWalking Eyes License Compatibility Check][🚎15-🪪-wfi]][🚎15-🪪-wf]
|
|
42
42
|
|
|
43
43
|
`if ci_badges.map(&:color).detect { it != "green"}` ☝️ [let me know][🖼️galtzo-discord], as I may have missed the [discord notification][🖼️galtzo-discord].
|
|
44
44
|
|
|
@@ -63,9 +63,17 @@ use OmniAuth::Strategies::LDAP,
|
|
|
63
63
|
name_proc: proc { |name| name.gsub(/@.*$/, "") },
|
|
64
64
|
bind_dn: "default_bind_dn",
|
|
65
65
|
password: "password",
|
|
66
|
+
# Optional timeouts (seconds)
|
|
67
|
+
connect_timeout: 3,
|
|
68
|
+
read_timeout: 7,
|
|
66
69
|
tls_options: {
|
|
67
70
|
ssl_version: "TLSv1_2",
|
|
68
71
|
ciphers: ["AES-128-CBC", "AES-128-CBC-HMAC-SHA1", "AES-128-CBC-HMAC-SHA256"],
|
|
72
|
+
},
|
|
73
|
+
mapping: {
|
|
74
|
+
"name" => "cn;lang-en",
|
|
75
|
+
"email" => ["preferredEmail", "mail"],
|
|
76
|
+
"nickname" => ["uid", "userid", "sAMAccountName"],
|
|
69
77
|
}
|
|
70
78
|
# Or, alternatively:
|
|
71
79
|
# use OmniAuth::Strategies::LDAP, filter: '(&(uid=%{username})(memberOf=cn=myapp-users,ou=groups,dc=example,dc=com))'
|
|
@@ -73,6 +81,50 @@ use OmniAuth::Strategies::LDAP,
|
|
|
73
81
|
|
|
74
82
|
All of the listed options are required, with the exception of `:title`, `:name_proc`, `:bind_dn`, and `:password`.
|
|
75
83
|
|
|
84
|
+
### TLS certificate verification
|
|
85
|
+
|
|
86
|
+
This gem enables TLS certificate verification by default when you use `encryption: "ssl"` (LDAPS / simple TLS) or `encryption: "tls"` (STARTTLS). We always pass `tls_options` to Net::LDAP based on `OpenSSL::SSL::SSLContext::DEFAULT_PARAMS`, which includes `verify_mode: OpenSSL::SSL::VERIFY_PEER` and sane defaults.
|
|
87
|
+
|
|
88
|
+
- Secure by default: you do not need to set anything extra to verify the LDAP server certificate.
|
|
89
|
+
- To customize trust or ciphers, supply your own `tls_options`, which are merged over the safe defaults.
|
|
90
|
+
- If you truly need to skip verification (not recommended), set `disable_verify_certificates: true`.
|
|
91
|
+
|
|
92
|
+
Examples:
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
# Verify server certs (default behavior)
|
|
96
|
+
use OmniAuth::Strategies::LDAP,
|
|
97
|
+
host: ENV["LDAP_HOST"],
|
|
98
|
+
port: 636,
|
|
99
|
+
encryption: "ssl", # or "tls"
|
|
100
|
+
base: "dc=example,dc=com",
|
|
101
|
+
uid: "uid"
|
|
102
|
+
|
|
103
|
+
# Use a private CA bundle and restrict protocol/ciphers
|
|
104
|
+
use OmniAuth::Strategies::LDAP,
|
|
105
|
+
host: ENV["LDAP_HOST"],
|
|
106
|
+
port: 636,
|
|
107
|
+
encryption: "ssl",
|
|
108
|
+
base: "dc=example,dc=com",
|
|
109
|
+
uid: "uid",
|
|
110
|
+
tls_options: {
|
|
111
|
+
ca_file: "/etc/ssl/private/my_org_ca.pem",
|
|
112
|
+
ssl_version: "TLSv1_2",
|
|
113
|
+
ciphers: ["TLS_AES_256_GCM_SHA384", "TLS_CHACHA20_POLY1305_SHA256"],
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
# Opt out of verification (NOT recommended – use only in trusted test/dev scenarios)
|
|
117
|
+
use OmniAuth::Strategies::LDAP,
|
|
118
|
+
host: ENV["LDAP_HOST"],
|
|
119
|
+
port: 636,
|
|
120
|
+
encryption: "ssl",
|
|
121
|
+
base: "dc=example,dc=com",
|
|
122
|
+
uid: "uid",
|
|
123
|
+
disable_verify_certificates: true
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Note: Net::LDAP historically defaulted to no certificate validation when `tls_options` were not provided. This library mitigates that by always providing secure `tls_options` unless you explicitly disable verification.
|
|
127
|
+
|
|
76
128
|
## 💡 Info you can shake a stick at
|
|
77
129
|
|
|
78
130
|
| Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] |
|
|
@@ -101,7 +153,7 @@ Compatible with MRI Ruby 2.0+, and concordant releases of JRuby, and TruffleRuby
|
|
|
101
153
|
|
|
102
154
|
Available as part of the Tidelift Subscription.
|
|
103
155
|
|
|
104
|
-
<details>
|
|
156
|
+
<details markdown="1">
|
|
105
157
|
<summary>Need enterprise-level guarantees?</summary>
|
|
106
158
|
|
|
107
159
|
The maintainers of this and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use.
|
|
@@ -136,7 +188,7 @@ gem install omniauth-ldap
|
|
|
136
188
|
|
|
137
189
|
### 🔒 Secure Installation
|
|
138
190
|
|
|
139
|
-
<details>
|
|
191
|
+
<details markdown="1">
|
|
140
192
|
<summary>For Medium or High Security Installations</summary>
|
|
141
193
|
|
|
142
194
|
This gem is cryptographically signed, and has verifiable [SHA-256 and SHA-512][💎SHA_checksums] checksums by
|
|
@@ -191,6 +243,28 @@ The following options are available for configuring the OmniAuth LDAP strategy:
|
|
|
191
243
|
- `:sasl_mechanisms` - Array of SASL mechanisms to use (e.g., ["DIGEST-MD5", "GSS-SPNEGO"]).
|
|
192
244
|
- `:allow_anonymous` - Whether to allow anonymous binding (default: false).
|
|
193
245
|
- `:logger` - A logger instance for debugging (optional, for internal use).
|
|
246
|
+
- `:password_policy` - When true, the strategy will request the LDAP Password Policy response control (OID `1.3.6.1.4.1.42.2.27.8.5.1`) during the user bind. If the server supports it, the adaptor exposes:
|
|
247
|
+
- `adaptor.last_operation_result` — the last Net::LDAP operation result object.
|
|
248
|
+
- `adaptor.last_password_policy_response` — the matching password policy response control (implementation-specific object). This can indicate conditions such as password expired, account locked, reset required, or grace logins remaining (per the draft RFC).
|
|
249
|
+
- `:connect_timeout` - Maximum time in seconds to wait when establishing the TCP connection to the LDAP server. Forwarded to `Net::LDAP`.
|
|
250
|
+
- `:read_timeout` - Maximum time in seconds to wait for reads during LDAP operations (search/bind). Forwarded to `Net::LDAP`.
|
|
251
|
+
- `:mapping` - Customize how LDAP attributes map to the returned `auth.info` hash. A sensible default mapping is built into the strategy and will be merged with your overrides. See `lib/omniauth/strategies/ldap.rb` for the default keys and behavior; values can be a String (single attribute), an Array (first present attribute wins), or a Hash (string pattern with placeholders like `%0` combined from multiple attributes).
|
|
252
|
+
|
|
253
|
+
Example enabling password policy:
|
|
254
|
+
|
|
255
|
+
```ruby
|
|
256
|
+
use OmniAuth::Builder do
|
|
257
|
+
provider :ldap,
|
|
258
|
+
host: "ldap.example.com",
|
|
259
|
+
base: "dc=example,dc=com",
|
|
260
|
+
uid: "uid",
|
|
261
|
+
bind_dn: "cn=search,dc=example,dc=com",
|
|
262
|
+
password: ENV["LDAP_SEARCH_PASSWORD"],
|
|
263
|
+
password_policy: true
|
|
264
|
+
end
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Note: This is best-effort and compatible with a range of net-ldap versions. If your server supports the control, you can inspect the response via the `adaptor` instance during/after authentication (for example in a failure handler) to tailor error messages.
|
|
194
268
|
|
|
195
269
|
### Auth Hash UID vs LDAP :uid (search attribute)
|
|
196
270
|
|
|
@@ -299,6 +373,58 @@ end
|
|
|
299
373
|
|
|
300
374
|
Then link users to `/auth/ldap` in your app (for example, in a Devise sign-in page).
|
|
301
375
|
|
|
376
|
+
### Use JSON Body
|
|
377
|
+
|
|
378
|
+
This gem is compatible with JSON-encoded POST bodies as well as traditional form-encoded.
|
|
379
|
+
|
|
380
|
+
- Set header `Content-Type` to `application/json`.
|
|
381
|
+
- Send a JSON object containing `username` and `password`.
|
|
382
|
+
- Rails automatically exposes parsed JSON params via `env["action_dispatch.request.request_parameters"]`, which this strategy reads first. In non-Rails Rack apps, ensure you use a JSON parser middleware if you post raw JSON.
|
|
383
|
+
|
|
384
|
+
Examples
|
|
385
|
+
|
|
386
|
+
- curl (JSON):
|
|
387
|
+
|
|
388
|
+
```bash
|
|
389
|
+
curl -i \
|
|
390
|
+
-X POST \
|
|
391
|
+
-H 'Content-Type: application/json' \
|
|
392
|
+
-d '{"username":"alice","password":"secret"}' \
|
|
393
|
+
http://localhost:3000/auth/ldap
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
The request phase will redirect to `/auth/ldap/callback` when both fields are present.
|
|
397
|
+
|
|
398
|
+
- curl (form-encoded, still supported):
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
curl -i \
|
|
402
|
+
-X POST \
|
|
403
|
+
-H 'Content-Type: application/x-www-form-urlencoded' \
|
|
404
|
+
--data-urlencode 'username=alice' \
|
|
405
|
+
--data-urlencode 'password=secret' \
|
|
406
|
+
http://localhost:3000/auth/ldap
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
- Browser (JavaScript fetch):
|
|
410
|
+
|
|
411
|
+
```js
|
|
412
|
+
fetch('/auth/ldap', {
|
|
413
|
+
method: 'POST',
|
|
414
|
+
headers: { 'Content-Type': 'application/json' },
|
|
415
|
+
body: JSON.stringify({ username: 'alice', password: 'secret' })
|
|
416
|
+
}).then(res => {
|
|
417
|
+
if (res.redirected) {
|
|
418
|
+
window.location = res.url; // typically /auth/ldap/callback
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
Notes
|
|
424
|
+
|
|
425
|
+
- You can still initiate authentication by visiting `GET /auth/ldap` to render the HTML form and then submitting it (form-encoded). JSON is an additional option, not a replacement.
|
|
426
|
+
- In the callback phase (`POST /auth/ldap/callback`), the strategy reads JSON credentials the same way; Rails exposes them via `action_dispatch.request.request_parameters` and non-Rails apps should use a JSON parser middleware.
|
|
427
|
+
|
|
302
428
|
### Using a custom filter
|
|
303
429
|
|
|
304
430
|
If you need to restrict authentication to a group or use a more complex lookup, pass `:filter`. Use `%{username}` — it will be replaced with the processed username (after `:name_proc`).
|
|
@@ -401,6 +527,84 @@ provider :ldap,
|
|
|
401
527
|
|
|
402
528
|
This trims `alice@example.com` to `alice` before searching.
|
|
403
529
|
|
|
530
|
+
### Mounted under a subdirectory (SCRIPT_NAME)
|
|
531
|
+
|
|
532
|
+
If your app is served from a path prefix (for example, behind a reverse proxy at `/myapp`, or mounted via Rack::URLMap, or Rails `relative_url_root`), the OmniAuth callback must include that subdirectory. This strategy uses `callback_url` for the form action and redirects, so it automatically includes any `SCRIPT_NAME` set by Rack/Rails. In other words, you typically do not need any special configuration beyond ensuring `SCRIPT_NAME` is correct in the request environment.
|
|
533
|
+
|
|
534
|
+
- Works out-of-the-box when:
|
|
535
|
+
- You mount the app at a path using Rack’s `map`/`URLMap`.
|
|
536
|
+
- You set Rails’ `config.relative_url_root` (or `RAILS_RELATIVE_URL_ROOT`) or deploy under a prefix with a reverse proxy that sets `SCRIPT_NAME`.
|
|
537
|
+
|
|
538
|
+
Rack example (mounted at /myapp):
|
|
539
|
+
|
|
540
|
+
```ruby
|
|
541
|
+
# config.ru
|
|
542
|
+
require "rack"
|
|
543
|
+
require "omniauth-ldap"
|
|
544
|
+
|
|
545
|
+
app = Rack::Builder.new do
|
|
546
|
+
use(Rack::Session::Cookie, secret: "change_me")
|
|
547
|
+
use(OmniAuth::Builder) do
|
|
548
|
+
provider(
|
|
549
|
+
:ldap,
|
|
550
|
+
host: "ldap.example.com",
|
|
551
|
+
base: "dc=example,dc=com",
|
|
552
|
+
uid: "uid",
|
|
553
|
+
title: "Example LDAP",
|
|
554
|
+
)
|
|
555
|
+
end
|
|
556
|
+
|
|
557
|
+
run(->(env) { [404, {"Content-Type" => "text/plain"}, [env.key?("omniauth.auth").to_s]] })
|
|
558
|
+
end
|
|
559
|
+
|
|
560
|
+
run Rack::URLMap.new(
|
|
561
|
+
"/myapp" => app,
|
|
562
|
+
)
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
- Visiting `POST /myapp/auth/ldap` renders the login form with `action='http://host/myapp/auth/ldap/callback'`.
|
|
566
|
+
- Any redirects (including header-based SSO fast path) will also point to `http://host/myapp/auth/ldap/callback`.
|
|
567
|
+
|
|
568
|
+
Rails example (relative_url_root):
|
|
569
|
+
|
|
570
|
+
```ruby
|
|
571
|
+
# config/environments/production.rb (or an initializer)
|
|
572
|
+
Rails.application.configure do
|
|
573
|
+
config.relative_url_root = "/myapp" # or set ENV["RAILS_RELATIVE_URL_ROOT"]
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
# config/initializers/omniauth.rb
|
|
577
|
+
Rails.application.config.middleware.use(OmniAuth::Builder) do
|
|
578
|
+
provider :ldap,
|
|
579
|
+
title: "Acme LDAP",
|
|
580
|
+
host: "ldap.acme.internal",
|
|
581
|
+
base: "dc=acme,dc=corp",
|
|
582
|
+
uid: "uid",
|
|
583
|
+
bind_dn: "cn=search,dc=acme,dc=corp",
|
|
584
|
+
password: ENV["LDAP_SEARCH_PASSWORD"],
|
|
585
|
+
name_proc: proc { |n| n.split("@").first }
|
|
586
|
+
end
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
- With `relative_url_root` set, Rails/Rack provide `SCRIPT_NAME=/myapp`, and this strategy will issue a form with `action='.../myapp/auth/ldap/callback'` and redirect accordingly.
|
|
590
|
+
|
|
591
|
+
Behind proxies with unusual host/proto handling (optional):
|
|
592
|
+
|
|
593
|
+
OmniAuth usually derives the correct scheme/host/prefix from Rack (and standard `X-Forwarded-*` headers). If your environment produces incorrect absolute URLs, you can override the computed host and prefix by setting `OmniAuth.config.full_host`:
|
|
594
|
+
|
|
595
|
+
```ruby
|
|
596
|
+
OmniAuth.config.full_host = lambda do |env|
|
|
597
|
+
scheme = (env["HTTP_X_FORWARDED_PROTO"] || env["rack.url_scheme"]).to_s.split(",").first
|
|
598
|
+
host = env["HTTP_X_FORWARDED_HOST"] || env["HTTP_HOST"] || [env["SERVER_NAME"], env["SERVER_PORT"]].compact.join(":")
|
|
599
|
+
script = env["SCRIPT_NAME"].to_s
|
|
600
|
+
"#{scheme}://#{host}#{script}"
|
|
601
|
+
end
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
Note: You generally do not need this override. Prefer configuring your proxy to pass standard `X-Forwarded-Proto` and `X-Forwarded-Host` headers and let Rack/OmniAuth compute the full URL.
|
|
605
|
+
|
|
606
|
+
- Header-based SSO (`header_auth: true`) also respects `SCRIPT_NAME`; when a trusted header is present on `POST /myapp/auth/ldap`, the strategy redirects to `http://host/myapp/auth/ldap/callback`.
|
|
607
|
+
|
|
404
608
|
### Trusted header SSO (REMOTE_USER and friends)
|
|
405
609
|
|
|
406
610
|
Some deployments terminate SSO at a reverse proxy or portal and forward the already-authenticated user identity via an HTTP header such as `REMOTE_USER`.
|
|
@@ -464,7 +668,7 @@ Security checklist:
|
|
|
464
668
|
|
|
465
669
|
## 🦷 FLOSS Funding
|
|
466
670
|
|
|
467
|
-
While
|
|
671
|
+
While omniauth tools are free software and will always be, the project would benefit immensely from some funding.
|
|
468
672
|
Raising a monthly budget of... "dollars" would make the project more sustainable.
|
|
469
673
|
|
|
470
674
|
We welcome both individual and corporate sponsors! We also offer a
|
|
@@ -474,7 +678,7 @@ Currently, [GitHub Sponsors][🖇sponsor], and [Liberapay][⛳liberapay] are our
|
|
|
474
678
|
**If you're working in a company that's making significant use of omniauth tools we'd
|
|
475
679
|
appreciate it if you suggest to your company to become a omniauth sponsor.**
|
|
476
680
|
|
|
477
|
-
You can support
|
|
681
|
+
You can support the development of omniauth tools via
|
|
478
682
|
[GitHub Sponsors][🖇sponsor],
|
|
479
683
|
[Liberapay][⛳liberapay],
|
|
480
684
|
[PayPal][🖇paypal],
|
|
@@ -494,7 +698,7 @@ I’m developing a new library, [floss_funding][🖇floss-funding-gem], designed
|
|
|
494
698
|
|
|
495
699
|
**[Floss-Funding.dev][🖇floss-funding.dev]: 👉️ No network calls. 👉️ No tracking. 👉️ No oversight. 👉️ Minimal crypto hashing. 💡 Easily disabled nags**
|
|
496
700
|
|
|
497
|
-
[![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS
|
|
701
|
+
[![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS efforts using Patreon][🖇patreon-img]][🖇patreon]
|
|
498
702
|
|
|
499
703
|
## 🔐 Security
|
|
500
704
|
|
|
@@ -520,8 +724,6 @@ See [CONTRIBUTING.md][🤝contributing].
|
|
|
520
724
|
|
|
521
725
|
[![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls]
|
|
522
726
|
|
|
523
|
-
[![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov]
|
|
524
|
-
|
|
525
727
|
### 🪇 Code of Conduct
|
|
526
728
|
|
|
527
729
|
Everyone interacting with this project's codebases, issue trackers,
|
|
@@ -568,12 +770,11 @@ For example:
|
|
|
568
770
|
spec.add_dependency("omniauth-ldap", "~> 1.0")
|
|
569
771
|
```
|
|
570
772
|
|
|
571
|
-
<details>
|
|
773
|
+
<details markdown="1">
|
|
572
774
|
<summary>📌 Is "Platform Support" part of the public API? More details inside.</summary>
|
|
573
775
|
|
|
574
776
|
SemVer should, IMO, but doesn't explicitly, say that dropping support for specific Platforms
|
|
575
|
-
is a *breaking change* to an API.
|
|
576
|
-
It is obvious to many, but not all, and since the spec is silent, the bike shedding is endless.
|
|
777
|
+
is a *breaking change* to an API, and for that reason the bike shedding is endless.
|
|
577
778
|
|
|
578
779
|
To get a better understanding of how SemVer is intended to work over a project's lifetime,
|
|
579
780
|
read this article from the creator of SemVer:
|
|
@@ -602,6 +803,9 @@ See [LICENSE.txt][📄license] for the official [Copyright Notice][📄copyright
|
|
|
602
803
|
</picture>
|
|
603
804
|
</a>, and omniauth-ldap contributors.
|
|
604
805
|
</li>
|
|
806
|
+
<li>
|
|
807
|
+
Copyright (c) 2014 David Benko
|
|
808
|
+
</li>
|
|
605
809
|
<li>
|
|
606
810
|
Copyright (c) 2011 by Ping Yu and Intridea, Inc.
|
|
607
811
|
</li>
|
|
@@ -622,7 +826,7 @@ To join the community or get help 👇️ Join the Discord.
|
|
|
622
826
|
|
|
623
827
|
To say "thanks!" ☝️ Join the Discord or 👇️ send money.
|
|
624
828
|
|
|
625
|
-
[![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay
|
|
829
|
+
[![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal]
|
|
626
830
|
|
|
627
831
|
### Please give the project a star ⭐ ♥.
|
|
628
832
|
|
|
@@ -705,10 +909,6 @@ Thanks for RTFM. ☺️
|
|
|
705
909
|
[👽oss-helpi]: https://www.codetriage.com/omniauth/omniauth-ldap/badges/users.svg
|
|
706
910
|
[👽version]: https://bestgems.org/gems/omniauth-ldap
|
|
707
911
|
[👽versioni]: https://img.shields.io/gem/v/omniauth-ldap.svg
|
|
708
|
-
[🏀qlty-mnt]: https://qlty.sh/gh/omniauth/projects/omniauth-ldap
|
|
709
|
-
[🏀qlty-mnti]: https://qlty.sh/gh/omniauth/projects/omniauth-ldap/maintainability.svg
|
|
710
|
-
[🏀qlty-cov]: https://qlty.sh/gh/omniauth/projects/omniauth-ldap/metrics/code?sort=coverageRating
|
|
711
|
-
[🏀qlty-covi]: https://qlty.sh/gh/omniauth/projects/omniauth-ldap/coverage.svg
|
|
712
912
|
[🏀codecov]: https://codecov.io/gh/omniauth/omniauth-ldap
|
|
713
913
|
[🏀codecovi]: https://codecov.io/gh/omniauth/omniauth-ldap/graph/badge.svg
|
|
714
914
|
[🏀coveralls]: https://coveralls.io/github/omniauth/omniauth-ldap?branch=main
|
|
@@ -790,7 +990,7 @@ Thanks for RTFM. ☺️
|
|
|
790
990
|
[📌gitmoji]: https://gitmoji.dev
|
|
791
991
|
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
792
992
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
793
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.
|
|
993
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.293-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
794
994
|
[🔐security]: SECURITY.md
|
|
795
995
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
796
996
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|