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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 19c27ecbd57d5babdc8c9914923c0242e23f153c74f5401f365d532619deee73
4
- data.tar.gz: 4f8be4e8e78f707378f1b40c09cf8890db0bb314b9ad4c78e4869f5dac872b40
3
+ metadata.gz: 841706ede941c8a57b2654acc70c97ea042b7e7b855959da3a812f4586146dd0
4
+ data.tar.gz: e8a77c8088c29a29bd459def08741e9f470eb33c1ba4e0a347c7f618f702625a
5
5
  SHA512:
6
- metadata.gz: 508bb03ae1ec63d48d724889d51120895adca15f32d4b696ea42bec2eea965c5f267266b57c42b0eedfbcb2dea64ae07ac646c1bc42e91a211a76a2b72574dfd
7
- data.tar.gz: 9be502336071893f07dbe41e97c5780347999a2b3761fe05eb639e22e811c317dadf301e70805b1a50f3a201c0ca44f4847b5833a7b22d5bad365faa3728b89f
6
+ metadata.gz: a151db60427400377296ea9bd4decfad1aa8720453723e3f6618a8396b3b49cb929952bfed81fb6050c4af6af9610322b4c0e4462314d476dfdca306c9111b4f
7
+ data.tar.gz: 799601ab9d40b53c7698bbd264d8f7ba96cbbac00dc88f7bad45b98f2ba9a2c6b887a80d6bca272bd344bb5b8d0e8970acc2314409e73251e75c1d5bad59011f
@@ -1,3 +1,3 @@
1
1
  module OmniauthStrongAuthOidc
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -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 = File.exist?("README.md") ? File.read("README.md") : spec.summary
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.0
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
- # OmniAuth Strong Auth OIDC
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: []