omniauth-entra_id_jwt 0.1.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 +5 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +252 -0
- data/Rakefile +12 -0
- data/coverage/.last_run.json +5 -0
- data/coverage/.resultset.json +155 -0
- data/coverage/.resultset.json.lock +0 -0
- data/coverage/assets/0.13.1/DataTables-1.10.20/images/sort_asc.png +0 -0
- data/coverage/assets/0.13.1/DataTables-1.10.20/images/sort_asc_disabled.png +0 -0
- data/coverage/assets/0.13.1/DataTables-1.10.20/images/sort_both.png +0 -0
- data/coverage/assets/0.13.1/DataTables-1.10.20/images/sort_desc.png +0 -0
- data/coverage/assets/0.13.1/DataTables-1.10.20/images/sort_desc_disabled.png +0 -0
- data/coverage/assets/0.13.1/application.css +1 -0
- data/coverage/assets/0.13.1/application.js +7 -0
- data/coverage/assets/0.13.1/colorbox/border.png +0 -0
- data/coverage/assets/0.13.1/colorbox/controls.png +0 -0
- data/coverage/assets/0.13.1/colorbox/loading.gif +0 -0
- data/coverage/assets/0.13.1/colorbox/loading_background.png +0 -0
- data/coverage/assets/0.13.1/favicon_green.png +0 -0
- data/coverage/assets/0.13.1/favicon_red.png +0 -0
- data/coverage/assets/0.13.1/favicon_yellow.png +0 -0
- data/coverage/assets/0.13.1/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/coverage/assets/0.13.1/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/coverage/assets/0.13.1/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/coverage/assets/0.13.1/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/coverage/assets/0.13.1/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/coverage/assets/0.13.1/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/coverage/assets/0.13.1/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/coverage/assets/0.13.1/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/coverage/assets/0.13.1/images/ui-icons_222222_256x240.png +0 -0
- data/coverage/assets/0.13.1/images/ui-icons_2e83ff_256x240.png +0 -0
- data/coverage/assets/0.13.1/images/ui-icons_454545_256x240.png +0 -0
- data/coverage/assets/0.13.1/images/ui-icons_888888_256x240.png +0 -0
- data/coverage/assets/0.13.1/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/coverage/assets/0.13.1/loading.gif +0 -0
- data/coverage/assets/0.13.1/magnify.png +0 -0
- data/coverage/index.html +1700 -0
- data/lib/omniauth/entra_id_jwt/version.rb +11 -0
- data/lib/omniauth/entra_id_jwt.rb +2 -0
- data/lib/omniauth/strategies/entra_id_jwt.rb +138 -0
- data/lib/omniauth-entra_id_jwt.rb +1 -0
- data/sig/omniauth/entra/id/jwt.rbs +10 -0
- metadata +157 -0
@@ -0,0 +1,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "omniauth-oauth2"
|
4
|
+
|
5
|
+
module OmniAuth
|
6
|
+
module Strategies
|
7
|
+
class EntraIdJWT < OmniAuth::Strategies::OAuth2
|
8
|
+
BASE_URL = "https://login.microsoftonline.com"
|
9
|
+
|
10
|
+
option :name, "entra_id_jwt"
|
11
|
+
option :tenant_provider, nil
|
12
|
+
|
13
|
+
DEFAULT_SCOPE = "openid profile email"
|
14
|
+
COMMON_TENANT_ID = "common"
|
15
|
+
|
16
|
+
# The tenant_provider must return client_id, client_secret and,
|
17
|
+
# optionally, tenant_id and base_url.
|
18
|
+
#
|
19
|
+
args [:tenant_provider]
|
20
|
+
|
21
|
+
def client
|
22
|
+
provider = options.tenant_provider ? options.tenant_provider.new(self) : options
|
23
|
+
options.client_id = provider.client_id
|
24
|
+
|
25
|
+
unless provider.respond_to?(:client_secret) && provider.client_secret
|
26
|
+
raise ArgumentError, "You must provide client_secret"
|
27
|
+
end
|
28
|
+
|
29
|
+
options.client_secret = provider.client_secret
|
30
|
+
|
31
|
+
tenant_id = provider.respond_to?(:tenant_id) ? provider.tenant_id : COMMON_TENANT_ID
|
32
|
+
base_url = provider.respond_to?(:base_url) ? provider.base_url : BASE_URL
|
33
|
+
|
34
|
+
options.authorize_params = provider.authorize_params if provider.respond_to?(:authorize_params)
|
35
|
+
options.token_params.scope = if defined?(request) && request.params["scope"]
|
36
|
+
request.params["scope"]
|
37
|
+
elsif provider.respond_to?(:scope) && provider.scope
|
38
|
+
provider.scope
|
39
|
+
else
|
40
|
+
DEFAULT_SCOPE
|
41
|
+
end
|
42
|
+
oauth2 = "oauth2/v2.0"
|
43
|
+
|
44
|
+
tenanted_endpoint_base_url = "#{base_url}/#{tenant_id}"
|
45
|
+
|
46
|
+
options.client_options.authorize_url = "#{tenanted_endpoint_base_url}/#{oauth2}/authorize"
|
47
|
+
options.client_options.token_url = "#{tenanted_endpoint_base_url}/#{oauth2}/token"
|
48
|
+
|
49
|
+
# On Behalf Of flow requires the default as the grant_type, so should only need to be configured
|
50
|
+
# in the provider (if at all).
|
51
|
+
options.token_params.grant_type = if provider.respond_to?(:grant_type) && provider.grant_type
|
52
|
+
provider.grant_type
|
53
|
+
else
|
54
|
+
grant_type
|
55
|
+
end
|
56
|
+
|
57
|
+
# On Behalf Of flow requires the default as the requested_token_use, so should only need to be configured
|
58
|
+
# in the provider (if at all).
|
59
|
+
options.token_params.requested_token_use = if provider.respond_to?(:requested_token_use) && provider.requested_token_use
|
60
|
+
provider.requested_token_use
|
61
|
+
else
|
62
|
+
requested_token_use
|
63
|
+
end
|
64
|
+
|
65
|
+
super
|
66
|
+
end
|
67
|
+
|
68
|
+
uid do
|
69
|
+
raw_info["userPrincipalName"]
|
70
|
+
end
|
71
|
+
|
72
|
+
# As per omniauth-microsoft_graph definition
|
73
|
+
# https://github.com/omniauth/omniauth/wiki/Auth-Hash-Schema
|
74
|
+
info do
|
75
|
+
{
|
76
|
+
"name" => [raw_info["givenName"], raw_info["surname"]].join(' '),
|
77
|
+
"email" => raw_info["mail"],
|
78
|
+
"first_name" => raw_info["givenName"],
|
79
|
+
"last_name" => raw_info["surname"],
|
80
|
+
"nickname" => raw_info["displayName"],
|
81
|
+
"phone" => raw_info["mobilePhone"]
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
# Although the only extra referred to in https://github.com/omniauth/omniauth/wiki/Auth-Hash-Schema
|
87
|
+
# is raw_info, include other useful information such as tenant identifier as other keys.
|
88
|
+
# Probably best not to merge them all into the raw_info key, so they remain different.
|
89
|
+
extra do
|
90
|
+
{
|
91
|
+
'raw_info' => raw_info,
|
92
|
+
'params' => access_token.params,
|
93
|
+
'aud' => options.client_id,
|
94
|
+
'tid' => @jwt_data["tid"]
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
def callback_url
|
99
|
+
raise NotImplementedError, "Callback URL is not supported in on behalf of flow"
|
100
|
+
end
|
101
|
+
|
102
|
+
def raw_info
|
103
|
+
@raw_info = access_token.request(:get, "https://graph.microsoft.com/v1.0/me").parsed if @raw_info.nil?
|
104
|
+
@raw_info
|
105
|
+
end
|
106
|
+
|
107
|
+
def callback_phase
|
108
|
+
options.provider_ignores_state = true
|
109
|
+
super
|
110
|
+
end
|
111
|
+
|
112
|
+
protected
|
113
|
+
|
114
|
+
def grant_type
|
115
|
+
"urn:ietf:params:oauth:grant-type:jwt-bearer"
|
116
|
+
end
|
117
|
+
|
118
|
+
def requested_token_use
|
119
|
+
"on_behalf_of"
|
120
|
+
end
|
121
|
+
|
122
|
+
# This requires examining the request body, as it is almost definitely delivered as
|
123
|
+
# ContentType application/json
|
124
|
+
def build_access_token
|
125
|
+
body = JSON.parse(request.body.read)
|
126
|
+
request.body.rewind
|
127
|
+
# Need to store the JWT token here, as otherwise the actual tenant (tid)
|
128
|
+
# is not found in the subsequent /me API call.
|
129
|
+
# Check for tid claim, as it will be useful.
|
130
|
+
@jwt_data = JWT.decode(body['code'], nil, false, { required_claims: "tid" })[0]
|
131
|
+
|
132
|
+
client.get_token({ assertion: body['code'] }.merge(token_params))
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
OmniAuth.config.add_camelization 'entra_id_jwt', 'EntraIdJWT'
|
@@ -0,0 +1 @@
|
|
1
|
+
require File.join("omniauth", "entra_id_jwt")
|
metadata
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: omniauth-entra_id_jwt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Benjamin Elias
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-06-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: omniauth-oauth2
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.8'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.8'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.13'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.13'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: simplecov
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.22'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.22'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: webmock
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.25'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.25'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: debug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.0'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- 12136262+collabital@users.noreply.github.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- CHANGELOG.md
|
91
|
+
- CODE_OF_CONDUCT.md
|
92
|
+
- LICENSE
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- coverage/.last_run.json
|
97
|
+
- coverage/.resultset.json
|
98
|
+
- coverage/.resultset.json.lock
|
99
|
+
- coverage/assets/0.13.1/DataTables-1.10.20/images/sort_asc.png
|
100
|
+
- coverage/assets/0.13.1/DataTables-1.10.20/images/sort_asc_disabled.png
|
101
|
+
- coverage/assets/0.13.1/DataTables-1.10.20/images/sort_both.png
|
102
|
+
- coverage/assets/0.13.1/DataTables-1.10.20/images/sort_desc.png
|
103
|
+
- coverage/assets/0.13.1/DataTables-1.10.20/images/sort_desc_disabled.png
|
104
|
+
- coverage/assets/0.13.1/application.css
|
105
|
+
- coverage/assets/0.13.1/application.js
|
106
|
+
- coverage/assets/0.13.1/colorbox/border.png
|
107
|
+
- coverage/assets/0.13.1/colorbox/controls.png
|
108
|
+
- coverage/assets/0.13.1/colorbox/loading.gif
|
109
|
+
- coverage/assets/0.13.1/colorbox/loading_background.png
|
110
|
+
- coverage/assets/0.13.1/favicon_green.png
|
111
|
+
- coverage/assets/0.13.1/favicon_red.png
|
112
|
+
- coverage/assets/0.13.1/favicon_yellow.png
|
113
|
+
- coverage/assets/0.13.1/images/ui-bg_flat_0_aaaaaa_40x100.png
|
114
|
+
- coverage/assets/0.13.1/images/ui-bg_flat_75_ffffff_40x100.png
|
115
|
+
- coverage/assets/0.13.1/images/ui-bg_glass_55_fbf9ee_1x400.png
|
116
|
+
- coverage/assets/0.13.1/images/ui-bg_glass_65_ffffff_1x400.png
|
117
|
+
- coverage/assets/0.13.1/images/ui-bg_glass_75_dadada_1x400.png
|
118
|
+
- coverage/assets/0.13.1/images/ui-bg_glass_75_e6e6e6_1x400.png
|
119
|
+
- coverage/assets/0.13.1/images/ui-bg_glass_95_fef1ec_1x400.png
|
120
|
+
- coverage/assets/0.13.1/images/ui-bg_highlight-soft_75_cccccc_1x100.png
|
121
|
+
- coverage/assets/0.13.1/images/ui-icons_222222_256x240.png
|
122
|
+
- coverage/assets/0.13.1/images/ui-icons_2e83ff_256x240.png
|
123
|
+
- coverage/assets/0.13.1/images/ui-icons_454545_256x240.png
|
124
|
+
- coverage/assets/0.13.1/images/ui-icons_888888_256x240.png
|
125
|
+
- coverage/assets/0.13.1/images/ui-icons_cd0a0a_256x240.png
|
126
|
+
- coverage/assets/0.13.1/loading.gif
|
127
|
+
- coverage/assets/0.13.1/magnify.png
|
128
|
+
- coverage/index.html
|
129
|
+
- lib/omniauth-entra_id_jwt.rb
|
130
|
+
- lib/omniauth/entra_id_jwt.rb
|
131
|
+
- lib/omniauth/entra_id_jwt/version.rb
|
132
|
+
- lib/omniauth/strategies/entra_id_jwt.rb
|
133
|
+
- sig/omniauth/entra/id/jwt.rbs
|
134
|
+
homepage: https://github.com/collabital/omniauth-entra_id_jwt
|
135
|
+
licenses:
|
136
|
+
- MIT
|
137
|
+
metadata: {}
|
138
|
+
post_install_message:
|
139
|
+
rdoc_options: []
|
140
|
+
require_paths:
|
141
|
+
- lib
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: 3.0.0
|
147
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
requirements: []
|
153
|
+
rubygems_version: 3.5.23
|
154
|
+
signing_key:
|
155
|
+
specification_version: 4
|
156
|
+
summary: OAuth 2 authentication with the Entra ID API using an On Behalf Of JWT token.
|
157
|
+
test_files: []
|