omniauth_strong_auth_oidc 0.1.0 → 0.1.1
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
- data/lib/omniauth_strong_auth_oidc/version.rb +1 -1
- data/omniauth_strong_auth_oidc.gemspec +1 -1
- metadata +3 -315
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 841706ede941c8a57b2654acc70c97ea042b7e7b855959da3a812f4586146dd0
|
|
4
|
+
data.tar.gz: e8a77c8088c29a29bd459def08741e9f470eb33c1ba4e0a347c7f618f702625a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a151db60427400377296ea9bd4decfad1aa8720453723e3f6618a8396b3b49cb929952bfed81fb6050c4af6af9610322b4c0e4462314d476dfdca306c9111b4f
|
|
7
|
+
data.tar.gz: 799601ab9d40b53c7698bbd264d8f7ba96cbbac00dc88f7bad45b98f2ba9a2c6b887a80d6bca272bd344bb5b8d0e8970acc2314409e73251e75c1d5bad59011f
|
|
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
|
9
9
|
spec.email = ["dmitry@kiskolabs.com"]
|
|
10
10
|
|
|
11
11
|
spec.summary = %q{OmniAuth strategy for Strong Auth OIDC}
|
|
12
|
-
spec.description =
|
|
12
|
+
spec.description = "OmniAuth strategy for implementing strong authentication with Finnish Identification Broker Services via OpenID Connect (OIDC)."
|
|
13
13
|
spec.homepage = "https://github.com/kiskolabs/omniauth_strong_auth_oidc"
|
|
14
14
|
spec.license = "MIT"
|
|
15
15
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: omniauth_strong_auth_oidc
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kisko Labs
|
|
@@ -122,320 +122,8 @@ dependencies:
|
|
|
122
122
|
- - "~>"
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
124
|
version: '7.0'
|
|
125
|
-
description:
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
An OmniAuth strategy for implementing strong authentication with Finnish Identification Broker Services via OpenID Connect (OIDC).
|
|
129
|
-
|
|
130
|
-
## Overview
|
|
131
|
-
|
|
132
|
-
This gem provides an OmniAuth strategy that implements the OpenID Connect Federation protocol for strong authentication with Finnish identification providers. It supports:
|
|
133
|
-
|
|
134
|
-
- **Private Key JWT authentication** for client authentication
|
|
135
|
-
- **JWE (JSON Web Encryption)** for encrypted ID tokens
|
|
136
|
-
- **Entity Statements** for federation metadata discovery
|
|
137
|
-
- **Key rotation** with multiple storage backends
|
|
138
|
-
- **Signed authorization requests** using JWT
|
|
139
|
-
|
|
140
|
-
## Installation
|
|
141
|
-
|
|
142
|
-
Add this line to your application's Gemfile:
|
|
143
|
-
|
|
144
|
-
```ruby
|
|
145
|
-
gem 'omniauth_strong_auth_oidc'
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
And then execute:
|
|
149
|
-
|
|
150
|
-
```bash
|
|
151
|
-
bundle install
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
## Configuration
|
|
155
|
-
|
|
156
|
-
### Environment Variables
|
|
157
|
-
|
|
158
|
-
Configure the following environment variables:
|
|
159
|
-
|
|
160
|
-
```bash
|
|
161
|
-
# Required
|
|
162
|
-
OIDC_CLIENT_ID=your_client_id
|
|
163
|
-
OIDC_ACR_VALUES="your_acr_value1 your_acr_value2"
|
|
164
|
-
|
|
165
|
-
# Optional - For production with static keys
|
|
166
|
-
OIDC_SIGNING_KEY_BASE64=base64_encoded_signing_key
|
|
167
|
-
OIDC_ENCRYPTION_KEY_BASE64=base64_encoded_encryption_key
|
|
168
|
-
|
|
169
|
-
# Optional - For key rotation
|
|
170
|
-
OIDC_KEY_ROTATION_ENABLED=true
|
|
171
|
-
|
|
172
|
-
# Optional - Federation metadata URL
|
|
173
|
-
OAUTH_ISSUER_URL=https://your-issuer-url.com
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
## Usage with Devise
|
|
177
|
-
|
|
178
|
-
### Enable OmniAuth in User Model
|
|
179
|
-
|
|
180
|
-
Add the OmniAuth provider to your User model:
|
|
181
|
-
|
|
182
|
-
```ruby
|
|
183
|
-
class User < ApplicationRecord
|
|
184
|
-
devise :database_authenticatable, :registerable,
|
|
185
|
-
:recoverable, :rememberable, :validatable,
|
|
186
|
-
:omniauthable, omniauth_providers: [:strong_auth_oidc]
|
|
187
|
-
end
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### Add Required Fields to User
|
|
191
|
-
|
|
192
|
-
Generate a migration to add OmniAuth fields:
|
|
193
|
-
|
|
194
|
-
```bash
|
|
195
|
-
rails generate migration AddOmniauthToUsers provider:string uid:string identity_number:string
|
|
196
|
-
rails db:migrate
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
### Configure Devise Initializer
|
|
200
|
-
|
|
201
|
-
In `config/initializers/devise.rb`, configure the OmniAuth provider:
|
|
202
|
-
|
|
203
|
-
```ruby
|
|
204
|
-
Devise.setup do |config|
|
|
205
|
-
# ... other Devise configuration ...
|
|
206
|
-
|
|
207
|
-
# Configure entity statement fetcher
|
|
208
|
-
provider_entity_statement_fetcher = OmniauthStrongAuthOidc::EntityStatementFetcher::FileFetcher.new(
|
|
209
|
-
path_to_file: Rails.root.join("config", "oidc_test_entity_statement").to_s
|
|
210
|
-
)
|
|
211
|
-
|
|
212
|
-
if ENV["OAUTH_ISSUER_URL"].present?
|
|
213
|
-
provider_entity_statement_fetcher = OmniauthStrongAuthOidc::EntityStatementFetcher::FederationUrlFetcher.new(
|
|
214
|
-
issuer_url: ENV.fetch("OAUTH_ISSUER_URL")
|
|
215
|
-
)
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
# Configure JWKS storage
|
|
219
|
-
if ENV['OIDC_SIGNING_KEY_BASE64'].present? && ENV['OIDC_ENCRYPTION_KEY_BASE64'].present?
|
|
220
|
-
relying_party_jwks_storage = OmniauthStrongAuthOidc::RelyingPartyJwksStorage::EnvStorage.new
|
|
221
|
-
elsif ENV['OIDC_KEY_ROTATION_ENABLED'] == 'true'
|
|
222
|
-
cache_store = Rails.cache
|
|
223
|
-
# Use in-memory store in non-production environments if cache is NullStore
|
|
224
|
-
# this is useful for development and testing
|
|
225
|
-
# Use a more robust cache store in production (e.g., Memcached, Redis)
|
|
226
|
-
if Rails.cache.is_a?(ActiveSupport::Cache::NullStore) && !Rails.env.production?
|
|
227
|
-
cache_store = ActiveSupport::Cache::MemoryStore.new
|
|
228
|
-
end
|
|
229
|
-
relying_party_jwks_storage = OmniauthStrongAuthOidc::RelyingPartyJwksStorage::CacheStorage.new(
|
|
230
|
-
cache_store: cache_store
|
|
231
|
-
)
|
|
232
|
-
else
|
|
233
|
-
raise "OIDC signing and encryption keys are not configured. Please set OIDC_SIGNING_KEY_BASE64 and OIDC_ENCRYPTION_KEY_BASE64 environment variables, or enable key rotation with OIDC_KEY_ROTATION_ENABLED."
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
OmniauthStrongAuthOidc::RelyingPartyJwksStorage::Base.instance ||= relying_party_jwks_storage
|
|
237
|
-
|
|
238
|
-
provider_jwks_fetcher = OmniauthStrongAuthOidc::JwksFetcher.new(
|
|
239
|
-
entity_statement_fetcher: provider_entity_statement_fetcher
|
|
240
|
-
)
|
|
241
|
-
|
|
242
|
-
config.omniauth :strong_auth_oidc,
|
|
243
|
-
client_id: ENV.fetch("OIDC_CLIENT_ID"),
|
|
244
|
-
relying_party_jwks_storage: relying_party_jwks_storage,
|
|
245
|
-
provider_jwks_loader: OmniauthStrongAuthOidc::JwksCache.new(provider_jwks_fetcher),
|
|
246
|
-
provider_entity_statement_fetcher: provider_entity_statement_fetcher,
|
|
247
|
-
authorize_params: {
|
|
248
|
-
acr_values: ENV.fetch("OIDC_ACR_VALUES").split(' '),
|
|
249
|
-
response_type: 'code',
|
|
250
|
-
scope: 'openid'
|
|
251
|
-
},
|
|
252
|
-
client_options: {
|
|
253
|
-
auth_scheme: :private_key_jwt
|
|
254
|
-
}
|
|
255
|
-
end
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
### Create OmniAuth Callbacks Controller
|
|
259
|
-
|
|
260
|
-
```ruby
|
|
261
|
-
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|
262
|
-
def strong_auth_oidc
|
|
263
|
-
@user = User.from_omniauth(request.env['omniauth.auth'])
|
|
264
|
-
|
|
265
|
-
if @user.persisted?
|
|
266
|
-
sign_in_and_redirect @user, event: :authentication
|
|
267
|
-
set_flash_message(:notice, :success, kind: 'Strong Auth') if is_navigational_format?
|
|
268
|
-
else
|
|
269
|
-
session['devise.strong_auth_oidc_data'] = request.env['omniauth.auth'].except(:extra)
|
|
270
|
-
redirect_to new_user_registration_url
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
def failure
|
|
275
|
-
redirect_to root_path, alert: "Authentication failed: #{failure_message}"
|
|
276
|
-
end
|
|
277
|
-
end
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
### Add Class Method to User Model
|
|
281
|
-
|
|
282
|
-
```ruby
|
|
283
|
-
class User < ApplicationRecord
|
|
284
|
-
# ... devise configuration ...
|
|
285
|
-
|
|
286
|
-
def self.from_omniauth(auth)
|
|
287
|
-
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
|
|
288
|
-
user.email = "#{auth.uid}@strong-auth.local" # or handle email differently
|
|
289
|
-
user.password = Devise.friendly_token[0, 20]
|
|
290
|
-
user.identity_number = auth.info.identity_number
|
|
291
|
-
# user.first_name = auth.info.first_name
|
|
292
|
-
# user.last_name = auth.info.last_name
|
|
293
|
-
end
|
|
294
|
-
end
|
|
295
|
-
end
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
### Configure Routes
|
|
299
|
-
|
|
300
|
-
```ruby
|
|
301
|
-
Rails.application.routes.draw do
|
|
302
|
-
devise_for :users, controllers: {
|
|
303
|
-
omniauth_callbacks: 'users/omniauth_callbacks'
|
|
304
|
-
}
|
|
305
|
-
end
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
### Add Login Link to View
|
|
309
|
-
|
|
310
|
-
```erb
|
|
311
|
-
<%= link_to "Sign in with Finnish Strong Authentication", user_strong_auth_oidc_omniauth_authorize_path %>
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
## Federation Endpoints Controller
|
|
315
|
-
|
|
316
|
-
To expose the required OIDC federation endpoints (entity statement, JWKS), use the Rails generator:
|
|
317
|
-
|
|
318
|
-
```bash
|
|
319
|
-
rails generate omniauth_strong_auth_oidc:install \
|
|
320
|
-
--redirect_uris="https://example.com/users/auth/strong_auth_oidc/callback" \
|
|
321
|
-
--org_name="Your Organization Name" \
|
|
322
|
-
--iss="https://example.com"
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
**Generator options:**
|
|
326
|
-
|
|
327
|
-
| Option | Required | Description |
|
|
328
|
-
|--------|----------|-------------|
|
|
329
|
-
| `--redirect_uris` | Yes | Comma-separated list of OAuth callback URLs |
|
|
330
|
-
| `--org_name` | Yes | Your organization name for the entity statement |
|
|
331
|
-
| `--iss` | Yes | Issuer URL (your application's base URL) |
|
|
332
|
-
|
|
333
|
-
**Example with multiple redirect URIs:**
|
|
334
|
-
|
|
335
|
-
```bash
|
|
336
|
-
rails generate omniauth_strong_auth_oidc:install \
|
|
337
|
-
--redirect_uris="https://example.com/users/auth/strong_auth_oidc/callback,https://staging.example.com/users/auth/strong_auth_oidc/callback" \
|
|
338
|
-
--org_name="Acme Corporation" \
|
|
339
|
-
--iss="https://example.com"
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
This will:
|
|
343
|
-
1. Create `app/controllers/relying_party_entity_statement_controller.rb`
|
|
344
|
-
2. Add the following routes to `config/routes.rb`:
|
|
345
|
-
|
|
346
|
-
```ruby
|
|
347
|
-
# OIDC Federation endpoints
|
|
348
|
-
get '/.well-known/openid-federation', to: 'relying_party_entity_statement#entity_statement', as: :openid_federation
|
|
349
|
-
get '/.well-known/jwks.json', to: 'relying_party_entity_statement#jwks', as: :jwks
|
|
350
|
-
get '/.well-known/signed-jwks.jwt', to: 'relying_party_entity_statement#signed_jwks', as: :signed_jwks
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
The generated controller provides the following endpoints:
|
|
354
|
-
|
|
355
|
-
| Endpoint | Content-Type | Description |
|
|
356
|
-
|----------|--------------|-------------|
|
|
357
|
-
| `/.well-known/openid-federation` | `application/entity-statement+jwt` | Signed entity statement JWT |
|
|
358
|
-
| `/.well-known/jwks.json` | `application/json` | Public JWKS for token encryption |
|
|
359
|
-
| `/.well-known/signed-jwks.jwt` | `application/jwks+jwt` | Signed JWKS JWT |
|
|
360
|
-
|
|
361
|
-
**Additional environment variable required:**
|
|
362
|
-
|
|
363
|
-
```bash
|
|
364
|
-
OIDC_CONFIGURATION_SIGNING_KEY_BASE64=base64_encoded_configuration_signing_key
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
This key is used to sign the entity statement and JWKS. It should be a separate RSA key pair from the signing/encryption keys used for tokens.
|
|
368
|
-
|
|
369
|
-
## Key Storage Options
|
|
370
|
-
|
|
371
|
-
### Environment Storage (EnvStorage)
|
|
372
|
-
|
|
373
|
-
Store static keys in environment variables:
|
|
374
|
-
|
|
375
|
-
```bash
|
|
376
|
-
OIDC_SIGNING_KEY_BASE64=<base64_encoded_private_key>
|
|
377
|
-
OIDC_ENCRYPTION_KEY_BASE64=<base64_encoded_private_key>
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
### Cache Storage (CacheStorage)
|
|
381
|
-
|
|
382
|
-
Enable automatic key rotation using Rails cache:
|
|
383
|
-
|
|
384
|
-
```bash
|
|
385
|
-
OIDC_KEY_ROTATION_ENABLED=true
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
Keys are automatically generated and rotated based on cache TTL.
|
|
389
|
-
|
|
390
|
-
## Entity Statement Fetchers
|
|
391
|
-
|
|
392
|
-
### File Fetcher
|
|
393
|
-
|
|
394
|
-
For testing and development, load entity statements from a local file:
|
|
395
|
-
|
|
396
|
-
```ruby
|
|
397
|
-
OmniauthStrongAuthOidc::EntityStatementFetcher::FileFetcher.new(
|
|
398
|
-
path_to_file: Rails.root.join("config", "oidc_entity_statement.json").to_s
|
|
399
|
-
)
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
### Federation URL Fetcher
|
|
403
|
-
|
|
404
|
-
For production, fetch entity statements from the federation URL:
|
|
405
|
-
|
|
406
|
-
```ruby
|
|
407
|
-
OmniauthStrongAuthOidc::EntityStatementFetcher::FederationUrlFetcher.new(
|
|
408
|
-
issuer_url: ENV.fetch("OAUTH_ISSUER_URL")
|
|
409
|
-
)
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
## User Attributes
|
|
413
|
-
|
|
414
|
-
The strategy returns the following user attributes:
|
|
415
|
-
|
|
416
|
-
- `uid`: Unique identifier (subject)
|
|
417
|
-
- `identity_number`: Finnish personal identity code (urn:oid:1.2.246.21)
|
|
418
|
-
- `first_name`: Given name (urn:oid:1.2.246.575.1.14)
|
|
419
|
-
- `last_name`: Family name (urn:oid:2.5.4.4)
|
|
420
|
-
|
|
421
|
-
Raw claims are available in `auth['extra']['raw_info']`.
|
|
422
|
-
|
|
423
|
-
## Development
|
|
424
|
-
|
|
425
|
-
After checking out the repo, run:
|
|
426
|
-
|
|
427
|
-
```bash
|
|
428
|
-
bundle install
|
|
429
|
-
bundle exec rspec
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
## Contributing
|
|
433
|
-
|
|
434
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/kiskolabs/omniauth_strong_auth_oidc.
|
|
435
|
-
|
|
436
|
-
## License
|
|
437
|
-
|
|
438
|
-
The gem is available as open source under the terms of the [MIT License](LICENSE).
|
|
125
|
+
description: OmniAuth strategy for implementing strong authentication with Finnish
|
|
126
|
+
Identification Broker Services via OpenID Connect (OIDC).
|
|
439
127
|
email:
|
|
440
128
|
- dmitry@kiskolabs.com
|
|
441
129
|
executables: []
|