onc_certification_g10_test_kit 7.2.8 → 7.2.9
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/onc_certification_g10_test_kit/bulk_data_authorization.rb +101 -171
- data/lib/onc_certification_g10_test_kit/bulk_data_jwks_helper.rb +19 -0
- data/lib/onc_certification_g10_test_kit/g10_certification_suite.rb +2 -7
- data/lib/onc_certification_g10_test_kit/g10_certification_suite_short_id_map.yml +10 -10
- data/lib/onc_certification_g10_test_kit/requirements/generated/g10_certification_requirements_coverage.csv +8 -8
- data/lib/onc_certification_g10_test_kit/smart_invalid_token_refresh_test.rb +13 -0
- data/lib/onc_certification_g10_test_kit/version.rb +2 -2
- metadata +5 -5
- data/lib/onc_certification_g10_test_kit/authorization_request_builder.rb +0 -88
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a519770018d63590e33677acbce9ae4a7c98d64c17ff977fc0b08513211c66b5
|
|
4
|
+
data.tar.gz: 255002f2ebe5cc624962e5842f188892f3060db5d24a568523e0953201b88583
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 577ba0110ad39c56e9611941bdb5be784bc2b88b0a01ac139be8cef10f9548b1d33ea24c9bf25f9a7556f2cde02b789e43141eab43882149de7f167f0cd5a318
|
|
7
|
+
data.tar.gz: 5d540c0c65dd6d4bdb3236ca5b1cb67212694d8bb6e9ea52f7ffc1984a7306731ad9b4a01e4384e342e7bd5555a923d9460500af71c4cbf4553bcc929b649d99
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require_relative '
|
|
1
|
+
require_relative 'bulk_data_jwks_helper'
|
|
2
2
|
|
|
3
3
|
module ONCCertificationG10TestKit
|
|
4
4
|
class BulkDataAuthorization < Inferno::TestGroup
|
|
@@ -29,6 +29,7 @@ module ONCCertificationG10TestKit
|
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
name: :jwks,
|
|
32
|
+
default: BulkDataJWKSHelper.jwks_json,
|
|
32
33
|
locked: true
|
|
33
34
|
}
|
|
34
35
|
]
|
|
@@ -53,178 +54,107 @@ module ONCCertificationG10TestKit
|
|
|
53
54
|
end
|
|
54
55
|
|
|
55
56
|
config(
|
|
56
|
-
options: {
|
|
57
|
+
options: { minimum_allowed_version: OpenSSL::SSL::TLS1_2_VERSION }
|
|
57
58
|
)
|
|
58
59
|
end
|
|
59
60
|
|
|
60
|
-
test
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
scope: bulk_smart_auth_info.requested_scopes,
|
|
159
|
-
iss: 'not_a_valid_iss',
|
|
160
|
-
sub: bulk_smart_auth_info.client_id,
|
|
161
|
-
aud: bulk_smart_auth_info.token_url
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
post(bulk_smart_auth_info.token_url, **post_request_content)
|
|
165
|
-
|
|
166
|
-
assert_response_status([400, 401])
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
test do
|
|
171
|
-
title 'Authorization request succeeds when supplied correct information'
|
|
172
|
-
description <<~DESCRIPTION
|
|
173
|
-
If the access token request is valid and authorized, the authorization server SHALL issue an access token in response.
|
|
174
|
-
DESCRIPTION
|
|
175
|
-
# link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/authorization/index.html#issuing-access-tokens'
|
|
176
|
-
|
|
177
|
-
makes_request :bulk_authentication
|
|
178
|
-
|
|
179
|
-
run do
|
|
180
|
-
post_request_content =
|
|
181
|
-
AuthorizationRequestBuilder.build(
|
|
182
|
-
encryption_method: bulk_smart_auth_info.encryption_algorithm,
|
|
183
|
-
scope: bulk_smart_auth_info.requested_scopes,
|
|
184
|
-
iss: bulk_smart_auth_info.client_id,
|
|
185
|
-
sub: bulk_smart_auth_info.client_id,
|
|
186
|
-
aud: bulk_smart_auth_info.token_url
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
post(bulk_smart_auth_info.token_url, **post_request_content, name: :bulk_authentication)
|
|
190
|
-
|
|
191
|
-
assert_response_status([200, 201])
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
test do
|
|
196
|
-
title 'Authorization request response body contains required information encoded in JSON'
|
|
197
|
-
description <<~DESCRIPTION
|
|
198
|
-
The access token response SHALL be a JSON object with the following properties:
|
|
199
|
-
|
|
200
|
-
| Token Property | Required? | Description |
|
|
201
|
-
| --- | --- | --- |
|
|
202
|
-
| access_token | required | The access token issued by the authorization server. |
|
|
203
|
-
| token_type | required | Fixed value: bearer. |
|
|
204
|
-
| expires_in | required | The lifetime in seconds of the access token. The recommended value is 300, for a five-minute token lifetime. |
|
|
205
|
-
| scope | required | Scope of access authorized. Note that this can be different from the scopes requested by the app. |
|
|
206
|
-
DESCRIPTION
|
|
207
|
-
# link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/authorization/index.html#issuing-access-tokens'
|
|
208
|
-
|
|
209
|
-
uses_request :bulk_authentication
|
|
210
|
-
output :bulk_smart_auth_info
|
|
211
|
-
|
|
212
|
-
run do
|
|
213
|
-
assert_valid_json(request.response_body)
|
|
214
|
-
response_body = JSON.parse(request.response_body)
|
|
215
|
-
|
|
216
|
-
access_token = response_body['access_token']
|
|
217
|
-
assert access_token.present?, 'Token response did not contain access_token as required'
|
|
218
|
-
|
|
219
|
-
bulk_smart_auth_info.update_from_response_body(request)
|
|
220
|
-
output bulk_smart_auth_info: bulk_smart_auth_info
|
|
221
|
-
|
|
222
|
-
required_keys = ['token_type', 'expires_in', 'scope']
|
|
223
|
-
|
|
224
|
-
required_keys.each do |key|
|
|
225
|
-
assert response_body[key].present?, "Token response did not contain #{key} as required"
|
|
226
|
-
end
|
|
227
|
-
end
|
|
228
|
-
end
|
|
61
|
+
test from: :smart_backend_services_invalid_grant_type,
|
|
62
|
+
title: 'Authorization request fails when client supplies invalid grant_type',
|
|
63
|
+
description: <<~DESCRIPTION,
|
|
64
|
+
The Backend Service Authorization specification defines the required fields for the
|
|
65
|
+
authorization request, made via HTTP POST to authorization token endpoint.
|
|
66
|
+
This includes the `grant_type` parameter, where the value must be `client_credentials`.
|
|
67
|
+
|
|
68
|
+
The OAuth 2.0 Authorization Framework describes the proper response for an
|
|
69
|
+
invalid request in the client credentials grant flow:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
If the request failed client authentication or is invalid, the authorization server returns an
|
|
73
|
+
error response as described in [Section 5.2](https://tools.ietf.org/html/rfc6749#section-5.2).
|
|
74
|
+
```
|
|
75
|
+
DESCRIPTION
|
|
76
|
+
config: {
|
|
77
|
+
inputs: { smart_auth_info: { name: :bulk_smart_auth_info } }
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
test from: :smart_backend_services_invalid_client_assertion,
|
|
81
|
+
title: 'Authorization request fails when supplied invalid client_assertion_type',
|
|
82
|
+
description: <<~DESCRIPTION,
|
|
83
|
+
The Backend Service Authorization specification defines the required fields for the
|
|
84
|
+
authorization request, made via HTTP POST to authorization token endpoint.
|
|
85
|
+
This includes the `client_assertion_type` parameter, where the value must be `urn:ietf:params:oauth:client-assertion-type:jwt-bearer`.
|
|
86
|
+
|
|
87
|
+
The OAuth 2.0 Authorization Framework describes the proper response for an
|
|
88
|
+
invalid request in the client credentials grant flow:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
If the request failed client authentication or is invalid, the authorization server returns an
|
|
92
|
+
error response as described in [Section 5.2](https://tools.ietf.org/html/rfc6749#section-5.2).
|
|
93
|
+
```
|
|
94
|
+
DESCRIPTION
|
|
95
|
+
config: {
|
|
96
|
+
inputs: { smart_auth_info: { name: :bulk_smart_auth_info } }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
test from: :smart_backend_services_invalid_jwt,
|
|
100
|
+
title: 'Authorization request fails when client supplies invalid JWT token',
|
|
101
|
+
description: <<~DESCRIPTION,
|
|
102
|
+
The Backend Service Authorization specification defines the required fields for the
|
|
103
|
+
authorization request, made via HTTP POST to authorization token endpoint.
|
|
104
|
+
This includes the `client_assertion` parameter, where the value must be
|
|
105
|
+
a valid JWT. The JWT SHALL include the following claims, and SHALL be signed with the client’s private key.
|
|
106
|
+
|
|
107
|
+
| JWT Claim | Required? | Description |
|
|
108
|
+
| --- | --- | --- |
|
|
109
|
+
| iss | required | Issuer of the JWT -- the client's client_id, as determined during registration with the FHIR authorization server (note that this is the same as the value for the sub claim) |
|
|
110
|
+
| sub | required | The service's client_id, as determined during registration with the FHIR authorization server (note that this is the same as the value for the iss claim) |
|
|
111
|
+
| aud | required | The FHIR authorization server's "token URL" (the same URL to which this authentication JWT will be posted) |
|
|
112
|
+
| exp | required | Expiration time integer for this authentication JWT, expressed in seconds since the "Epoch" (1970-01-01T00:00:00Z UTC). This time SHALL be no more than five minutes in the future. |
|
|
113
|
+
| jti | required | A nonce string value that uniquely identifies this authentication JWT. |
|
|
114
|
+
|
|
115
|
+
The OAuth 2.0 Authorization Framework describes the proper response for an
|
|
116
|
+
invalid request in the client credentials grant flow:
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
If the request failed client authentication or is invalid, the authorization server returns an
|
|
120
|
+
error response as described in [Section 5.2](https://tools.ietf.org/html/rfc6749#section-5.2).
|
|
121
|
+
```
|
|
122
|
+
DESCRIPTION
|
|
123
|
+
config: {
|
|
124
|
+
inputs: { smart_auth_info: { name: :bulk_smart_auth_info } }
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
test from: :smart_backend_services_auth_request_success,
|
|
128
|
+
title: 'Authorization request succeeds when supplied correct information',
|
|
129
|
+
description: <<~DESCRIPTION,
|
|
130
|
+
If the access token request is valid and authorized, the authorization server SHALL issue an access token in response.
|
|
131
|
+
DESCRIPTION
|
|
132
|
+
config: {
|
|
133
|
+
inputs: { smart_auth_info: { name: :bulk_smart_auth_info } },
|
|
134
|
+
outputs: {
|
|
135
|
+
smart_auth_info: { name: :bulk_smart_auth_info },
|
|
136
|
+
authentication_response: { name: :bulk_authentication }
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
test from: :smart_backend_services_auth_response_body,
|
|
141
|
+
title: 'Authorization request response body contains required information encoded in JSON',
|
|
142
|
+
description: <<~DESCRIPTION,
|
|
143
|
+
The access token response SHALL be a JSON object with the following properties:
|
|
144
|
+
|
|
145
|
+
| Token Property | Required? | Description |
|
|
146
|
+
| --- | --- | --- |
|
|
147
|
+
| access_token | required | The access token issued by the authorization server. |
|
|
148
|
+
| token_type | required | Fixed value: bearer. |
|
|
149
|
+
| expires_in | required | The lifetime in seconds of the access token. The recommended value is 300, for a five-minute token lifetime. |
|
|
150
|
+
| scope | required | Scope of access authorized. Note that this can be different from the scopes requested by the app. |
|
|
151
|
+
DESCRIPTION
|
|
152
|
+
config: {
|
|
153
|
+
inputs: {
|
|
154
|
+
smart_auth_info: { name: :bulk_smart_auth_info },
|
|
155
|
+
authentication_response: { name: :bulk_authentication }
|
|
156
|
+
},
|
|
157
|
+
outputs: { smart_auth_info: { name: :bulk_smart_auth_info } }
|
|
158
|
+
}
|
|
229
159
|
end
|
|
230
160
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
module ONCCertificationG10TestKit
|
|
4
|
+
module BulkDataJWKSHelper
|
|
5
|
+
def self.jwks_json
|
|
6
|
+
@jwks_json ||= File.read(ENV.fetch('G10_BULK_DATA_JWKS', File.join(__dir__, 'bulk_data_jwks.json')))
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.public_jwks_json
|
|
10
|
+
@public_jwks_json ||=
|
|
11
|
+
begin
|
|
12
|
+
jwks = JSON.parse(jwks_json)
|
|
13
|
+
JSON.pretty_generate(
|
|
14
|
+
{ keys: jwks['keys'].select { |key| key['key_ops']&.include?('verify') } }
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -6,6 +6,7 @@ require_relative 'feature'
|
|
|
6
6
|
require_relative 'g10_options'
|
|
7
7
|
require_relative 'multi_patient_api_stu1'
|
|
8
8
|
require_relative 'multi_patient_api_stu2'
|
|
9
|
+
require_relative 'bulk_data_jwks_helper'
|
|
9
10
|
require_relative 'single_patient_api_group'
|
|
10
11
|
require_relative 'single_patient_us_core_4_api_group'
|
|
11
12
|
require_relative 'single_patient_us_core_5_api_group'
|
|
@@ -239,13 +240,7 @@ module ONCCertificationG10TestKit
|
|
|
239
240
|
end
|
|
240
241
|
|
|
241
242
|
def self.jwks_json
|
|
242
|
-
|
|
243
|
-
JSON.parse(
|
|
244
|
-
File.read(ENV.fetch('G10_BULK_DATA_JWKS', File.join(__dir__, 'bulk_data_jwks.json')))
|
|
245
|
-
)
|
|
246
|
-
@jwks_json ||= JSON.pretty_generate(
|
|
247
|
-
{ keys: bulk_data_jwks['keys'].select { |key| key['key_ops']&.include?('verify') } }
|
|
248
|
-
)
|
|
243
|
+
BulkDataJWKSHelper.public_jwks_json
|
|
249
244
|
end
|
|
250
245
|
|
|
251
246
|
def self.well_known_route_handler
|
|
@@ -2608,11 +2608,11 @@ g10_certification-g10_single_patient_us_core_7_api-g10_incorrectly_permitted_tls
|
|
|
2608
2608
|
g10_certification-multi_patient_api: '7'
|
|
2609
2609
|
g10_certification-multi_patient_api-bulk_data_authorization: '7.1'
|
|
2610
2610
|
g10_certification-multi_patient_api-bulk_data_authorization-g10_bulk_token_tls_version: 7.1.01
|
|
2611
|
-
g10_certification-multi_patient_api-bulk_data_authorization-
|
|
2612
|
-
g10_certification-multi_patient_api-bulk_data_authorization-
|
|
2613
|
-
g10_certification-multi_patient_api-bulk_data_authorization-
|
|
2614
|
-
g10_certification-multi_patient_api-bulk_data_authorization-
|
|
2615
|
-
g10_certification-multi_patient_api-bulk_data_authorization-
|
|
2611
|
+
g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_invalid_grant_type: 7.1.02
|
|
2612
|
+
g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_invalid_client_assertion: 7.1.03
|
|
2613
|
+
g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_invalid_jwt: 7.1.04
|
|
2614
|
+
g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_auth_request_success: 7.1.05
|
|
2615
|
+
g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_auth_response_body: 7.1.06
|
|
2616
2616
|
g10_certification-multi_patient_api-g10_bulk_auth_tls_messages_setup: '7.01'
|
|
2617
2617
|
g10_certification-multi_patient_api-bulk_data_group_export: '7.2'
|
|
2618
2618
|
g10_certification-multi_patient_api-bulk_data_group_export-g10_bulk_data_server_tls_version: 7.2.01
|
|
@@ -2674,11 +2674,11 @@ g10_certification-multi_patient_api-g10_bulk_data_export_cancel_stu1-g10_bulk_ex
|
|
|
2674
2674
|
g10_certification-multi_patient_api_stu2: '8'
|
|
2675
2675
|
g10_certification-multi_patient_api_stu2-bulk_data_authorization: '8.1'
|
|
2676
2676
|
g10_certification-multi_patient_api_stu2-bulk_data_authorization-g10_bulk_token_tls_version: 8.1.01
|
|
2677
|
-
g10_certification-multi_patient_api_stu2-bulk_data_authorization-
|
|
2678
|
-
g10_certification-multi_patient_api_stu2-bulk_data_authorization-
|
|
2679
|
-
g10_certification-multi_patient_api_stu2-bulk_data_authorization-
|
|
2680
|
-
g10_certification-multi_patient_api_stu2-bulk_data_authorization-
|
|
2681
|
-
g10_certification-multi_patient_api_stu2-bulk_data_authorization-
|
|
2677
|
+
g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_invalid_grant_type: 8.1.02
|
|
2678
|
+
g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_invalid_client_assertion: 8.1.03
|
|
2679
|
+
g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_invalid_jwt: 8.1.04
|
|
2680
|
+
g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_auth_request_success: 8.1.05
|
|
2681
|
+
g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_auth_response_body: 8.1.06
|
|
2682
2682
|
g10_certification-multi_patient_api_stu2-g10_bulk_auth_tls_messages_setup: '8.01'
|
|
2683
2683
|
g10_certification-multi_patient_api_stu2-bulk_data_group_export_stu2: '8.2'
|
|
2684
2684
|
g10_certification-multi_patient_api_stu2-bulk_data_group_export_stu2-g10_bulk_data_server_tls_version: 8.2.01
|
|
@@ -191,14 +191,14 @@ application with revoked access to receive patient EHI.",SHALL,Server,false,,,"9
|
|
|
191
191
|
170.315(g)(10)-test-procedure,AUT-SYS-1,https://www.healthit.gov/test-method/standardized-api-patient-and-population-services#test_procedure,"The health IT developer demonstrates the ability of the Health IT
|
|
192
192
|
Module to support OAuth 2.0 client credentials grant flow in
|
|
193
193
|
accordance with an implementation specification adopted in §
|
|
194
|
-
170.215(d).",SHALL,Server,false,,,"7.1.02, 7.1.03, 7.1.04, 7.1.05, 7.1.06, 8.1.02, 8.1.03, 8.1.04, 8.1.05, 8.1.06","g10_certification-multi_patient_api-bulk_data_authorization-
|
|
194
|
+
170.215(d).",SHALL,Server,false,,,"7.1.02, 7.1.03, 7.1.04, 7.1.05, 7.1.06, 8.1.02, 8.1.03, 8.1.04, 8.1.05, 8.1.06","g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_invalid_grant_type, g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_invalid_client_assertion, g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_invalid_jwt, g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_auth_request_success, g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_auth_response_body, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_invalid_grant_type, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_invalid_client_assertion, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_invalid_jwt, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_auth_request_success, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_auth_response_body"
|
|
195
195
|
170.315(g)(10)-test-procedure,AUT-SYS-2,https://www.healthit.gov/test-method/standardized-api-patient-and-population-services#test_procedure,"The health IT developer demonstrates the ability of the Health IT
|
|
196
196
|
Module to support the following parameters according to an
|
|
197
197
|
implementation specification adopted in § 170.215(d):
|
|
198
198
|
* “scope”;
|
|
199
199
|
* “grant_type”;
|
|
200
200
|
* “client_assertion_type”; and
|
|
201
|
-
* “client_assertion”.",SHALL,Server,false,,,"7.1.05, 8.1.05","g10_certification-multi_patient_api-bulk_data_authorization-
|
|
201
|
+
* “client_assertion”.",SHALL,Server,false,,,"7.1.05, 8.1.05","g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_auth_request_success, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_auth_request_success"
|
|
202
202
|
170.315(g)(10)-test-procedure,AUT-SYS-3,https://www.healthit.gov/test-method/standardized-api-patient-and-population-services#test_procedure,"The health IT developer demonstrates the ability of the Health IT
|
|
203
203
|
Module to support the following JSON Web Token (JWT) Headers and
|
|
204
204
|
Claims according to an implementation specification adopted in §
|
|
@@ -210,22 +210,22 @@ Claims according to an implementation specification adopted in §
|
|
|
210
210
|
* “sub” claim;
|
|
211
211
|
* “aud” claim;
|
|
212
212
|
* “exp” claim; and
|
|
213
|
-
* “jti” claim.",SHALL,Server,false,,,"7.1.05, 8.1.05","g10_certification-multi_patient_api-bulk_data_authorization-
|
|
213
|
+
* “jti” claim.",SHALL,Server,false,,,"7.1.05, 8.1.05","g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_auth_request_success, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_auth_request_success"
|
|
214
214
|
170.315(g)(10)-test-procedure,AUT-SYS-4,https://www.healthit.gov/test-method/standardized-api-patient-and-population-services#test_procedure,"The health IT developer demonstrates the ability of the Health IT
|
|
215
215
|
Module to receive and process the JSON Web Key (JWK) Set via a
|
|
216
216
|
TLS-protected URL to support authorization for system scopes in §
|
|
217
|
-
170.315(g)(10)(v)(B).",SHALL,Server,false,,,"7.1.05, 8.1.05","g10_certification-multi_patient_api-bulk_data_authorization-
|
|
217
|
+
170.315(g)(10)(v)(B).",SHALL,Server,false,,,"7.1.05, 8.1.05","g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_auth_request_success, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_auth_request_success"
|
|
218
218
|
170.315(g)(10)-test-procedure,AUT-SYS-5,https://www.healthit.gov/test-method/standardized-api-patient-and-population-services#test_procedure,"The health IT developer demonstrates that the Health IT Module does
|
|
219
219
|
not cache a JWK Set received via a TLS-protected URL for longer than
|
|
220
220
|
the “cache-control” header sent by an application indicates.",SHALL,Server,false,,,11.10,g10_certification-g10_visual_inspection_and_attestations-Test10
|
|
221
221
|
170.315(g)(10)-test-procedure,AUT-SYS-6,https://www.healthit.gov/test-method/standardized-api-patient-and-population-services#test_procedure,"The health IT developer demonstrates the ability of the Health IT
|
|
222
222
|
Module to validate an application’s JWT, including its JSON Web
|
|
223
223
|
Signatures, according to an implementation specification adopted in §
|
|
224
|
-
170.215(d).",SHALL,Server,false,,,"7.1.05, 8.1.05","g10_certification-multi_patient_api-bulk_data_authorization-
|
|
224
|
+
170.215(d).",SHALL,Server,false,,,"7.1.05, 8.1.05","g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_auth_request_success, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_auth_request_success"
|
|
225
225
|
170.315(g)(10)-test-procedure,AUT-SYS-7,https://www.healthit.gov/test-method/standardized-api-patient-and-population-services#test_procedure,"The health IT developer demonstrates the ability of the Health IT
|
|
226
226
|
Module to respond with an “invalid_client” error for errors
|
|
227
227
|
encountered during the authentication process according to an
|
|
228
|
-
implementation specification adopted in § 170.215(d).",SHALL,Server,false,,,"7.1.02, 7.1.03, 7.1.04, 8.1.02, 8.1.03, 8.1.04","g10_certification-multi_patient_api-bulk_data_authorization-
|
|
228
|
+
implementation specification adopted in § 170.215(d).",SHALL,Server,false,,,"7.1.02, 7.1.03, 7.1.04, 8.1.02, 8.1.03, 8.1.04","g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_invalid_grant_type, g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_invalid_client_assertion, g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_invalid_jwt, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_invalid_grant_type, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_invalid_client_assertion, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_invalid_jwt"
|
|
229
229
|
170.315(g)(10)-test-procedure,AUT-SYS-8,https://www.healthit.gov/test-method/standardized-api-patient-and-population-services#test_procedure,"The health IT developer demonstrates the ability of the Health IT
|
|
230
230
|
Module to assure the scope granted based on the scope requested by an
|
|
231
231
|
application is no greater than the pre-authorized scope for multiple
|
|
@@ -238,10 +238,10 @@ accordance with an implementation specification adopted in §
|
|
|
238
238
|
* “access_token”;
|
|
239
239
|
* “token_type”;
|
|
240
240
|
* “expires_in”; and
|
|
241
|
-
* “scope”.",SHALL,Server,false,,,"7.1.06, 8.1.06","g10_certification-multi_patient_api-bulk_data_authorization-
|
|
241
|
+
* “scope”.",SHALL,Server,false,,,"7.1.06, 8.1.06","g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_auth_response_body, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_auth_response_body"
|
|
242
242
|
170.315(g)(10)-test-procedure,AUT-SYS-10,https://www.healthit.gov/test-method/standardized-api-patient-and-population-services#test_procedure,"The health IT developer demonstrates the ability of the Health IT
|
|
243
243
|
Module to respond to errors using the appropriate error messages as
|
|
244
|
-
specified in an implementation specification adopted in § 170.215(d).",SHALL,Server,false,,,"7.1.02, 7.1.03, 7.1.04, 7.2.03, 8.1.02, 8.1.03, 8.1.04, 8.2.03","g10_certification-multi_patient_api-bulk_data_authorization-
|
|
244
|
+
specified in an implementation specification adopted in § 170.215(d).",SHALL,Server,false,,,"7.1.02, 7.1.03, 7.1.04, 7.2.03, 8.1.02, 8.1.03, 8.1.04, 8.2.03","g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_invalid_grant_type, g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_invalid_client_assertion, g10_certification-multi_patient_api-bulk_data_authorization-smart_backend_services_invalid_jwt, g10_certification-multi_patient_api-bulk_data_group_export-Test03, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_invalid_grant_type, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_invalid_client_assertion, g10_certification-multi_patient_api_stu2-bulk_data_authorization-smart_backend_services_invalid_jwt, g10_certification-multi_patient_api_stu2-bulk_data_group_export_stu2-Test03"
|
|
245
245
|
170.315(g)(10)-test-procedure,TOK-INTRO-1,https://www.healthit.gov/test-method/standardized-api-patient-and-population-services#test_procedure,"The health IT developer demonstrates the ability of the Health IT
|
|
246
246
|
Module to receive and validate a token it has issued in accordance
|
|
247
247
|
with an implementation specification in § 170.215(c).",SHALL,Server,false,,,"9.11.2.01, 9.11.2.02, 9.11.3.01, 9.11.3.02, 9.20.2.01, 9.20.2.02, 9.20.3.01, 9.20.3.02, 11.06","g10_certification-Group06-g10_token_introspection-smart_token_introspection_request_group-Test01, g10_certification-Group06-g10_token_introspection-smart_token_introspection_request_group-Test02, g10_certification-Group06-g10_token_introspection-smart_token_introspection_response_group-Test01, g10_certification-Group06-g10_token_introspection-smart_token_introspection_response_group-Test02, g10_certification-Group06-g10_token_introspection_stu2_2-smart_token_introspection_request_group-Test01, g10_certification-Group06-g10_token_introspection_stu2_2-smart_token_introspection_request_group-Test02, g10_certification-Group06-g10_token_introspection_stu2_2-smart_token_introspection_response_group-Test01, g10_certification-Group06-g10_token_introspection_stu2_2-smart_token_introspection_response_group-Test02, g10_certification-g10_visual_inspection_and_attestations-Test06"
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
module ONCCertificationG10TestKit
|
|
2
|
+
require 'smart_app_launch/client_assertion_builder'
|
|
3
|
+
|
|
2
4
|
class SMARTInvalidTokenRefreshTest < Inferno::Test
|
|
3
5
|
id :g10_invalid_token_refresh
|
|
4
6
|
title 'Refresh token exchange fails when supplied an invalid refresh token'
|
|
@@ -26,6 +28,17 @@ module ONCCertificationG10TestKit
|
|
|
26
28
|
if smart_auth_info.symmetric_auth?
|
|
27
29
|
credentials = Base64.strict_encode64("#{smart_auth_info.client_id}:#{smart_auth_info.client_secret}")
|
|
28
30
|
oauth2_headers['Authorization'] = "Basic #{credentials}"
|
|
31
|
+
elsif smart_auth_info.asymmetric_auth?
|
|
32
|
+
oauth2_params.merge!(
|
|
33
|
+
client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
|
|
34
|
+
client_assertion: SMARTAppLaunch::ClientAssertionBuilder.build(
|
|
35
|
+
iss: smart_auth_info.client_id,
|
|
36
|
+
sub: smart_auth_info.client_id,
|
|
37
|
+
aud: smart_auth_info.token_url,
|
|
38
|
+
client_auth_encryption_method: smart_auth_info.encryption_algorithm,
|
|
39
|
+
custom_jwks: smart_auth_info.jwks
|
|
40
|
+
)
|
|
41
|
+
)
|
|
29
42
|
else
|
|
30
43
|
oauth2_params['client_id'] = smart_auth_info.client_id
|
|
31
44
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: onc_certification_g10_test_kit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 7.2.
|
|
4
|
+
version: 7.2.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stephen MacVicar
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-02-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bloomer
|
|
@@ -47,7 +47,7 @@ dependencies:
|
|
|
47
47
|
version: '1.0'
|
|
48
48
|
- - ">="
|
|
49
49
|
- !ruby/object:Gem::Version
|
|
50
|
-
version: 1.0.
|
|
50
|
+
version: 1.0.8
|
|
51
51
|
type: :runtime
|
|
52
52
|
prerelease: false
|
|
53
53
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -57,7 +57,7 @@ dependencies:
|
|
|
57
57
|
version: '1.0'
|
|
58
58
|
- - ">="
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: 1.0.
|
|
60
|
+
version: 1.0.8
|
|
61
61
|
- !ruby/object:Gem::Dependency
|
|
62
62
|
name: json-jwt
|
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -198,7 +198,6 @@ files:
|
|
|
198
198
|
- lib/inferno/terminology/value_set.rb
|
|
199
199
|
- lib/onc_certification_g10_test_kit.rb
|
|
200
200
|
- lib/onc_certification_g10_test_kit/all_resources.rb
|
|
201
|
-
- lib/onc_certification_g10_test_kit/authorization_request_builder.rb
|
|
202
201
|
- lib/onc_certification_g10_test_kit/base_token_refresh_group.rb
|
|
203
202
|
- lib/onc_certification_g10_test_kit/base_token_refresh_stu2_group.rb
|
|
204
203
|
- lib/onc_certification_g10_test_kit/bulk_data_authorization.rb
|
|
@@ -209,6 +208,7 @@ files:
|
|
|
209
208
|
- lib/onc_certification_g10_test_kit/bulk_data_group_export_stu2.rb
|
|
210
209
|
- lib/onc_certification_g10_test_kit/bulk_data_group_export_validation.rb
|
|
211
210
|
- lib/onc_certification_g10_test_kit/bulk_data_jwks.json
|
|
211
|
+
- lib/onc_certification_g10_test_kit/bulk_data_jwks_helper.rb
|
|
212
212
|
- lib/onc_certification_g10_test_kit/bulk_export_validation_tester.rb
|
|
213
213
|
- lib/onc_certification_g10_test_kit/configuration_checker.rb
|
|
214
214
|
- lib/onc_certification_g10_test_kit/encounter_context_test.rb
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
require 'json/jwt'
|
|
2
|
-
|
|
3
|
-
module ONCCertificationG10TestKit
|
|
4
|
-
class AuthorizationRequestBuilder
|
|
5
|
-
def self.build(...)
|
|
6
|
-
new(...).authorization_request
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def self.bulk_data_jwks
|
|
10
|
-
@bulk_data_jwks ||= JSON.parse(File.read(ENV.fetch('G10_BULK_DATA_JWKS',
|
|
11
|
-
File.join(__dir__, 'bulk_data_jwks.json'))))
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
attr_reader :encryption_method, :scope, :iss, :sub, :aud, :content_type, :grant_type, :client_assertion_type, :exp,
|
|
15
|
-
:jti
|
|
16
|
-
|
|
17
|
-
def initialize(
|
|
18
|
-
encryption_method:,
|
|
19
|
-
scope:,
|
|
20
|
-
iss:,
|
|
21
|
-
sub:,
|
|
22
|
-
aud:,
|
|
23
|
-
content_type: 'application/x-www-form-urlencoded',
|
|
24
|
-
grant_type: 'client_credentials',
|
|
25
|
-
client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
|
|
26
|
-
exp: 5.minutes.from_now,
|
|
27
|
-
jti: SecureRandom.hex(32)
|
|
28
|
-
)
|
|
29
|
-
@encryption_method = encryption_method
|
|
30
|
-
@scope = scope
|
|
31
|
-
@iss = iss
|
|
32
|
-
@sub = sub
|
|
33
|
-
@aud = aud
|
|
34
|
-
@content_type = content_type
|
|
35
|
-
@grant_type = grant_type
|
|
36
|
-
@client_assertion_type = client_assertion_type
|
|
37
|
-
@exp = exp
|
|
38
|
-
@jti = jti
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def bulk_private_key
|
|
42
|
-
@bulk_private_key ||=
|
|
43
|
-
self.class.bulk_data_jwks['keys']
|
|
44
|
-
.select { |key| key['key_ops']&.include?('sign') }
|
|
45
|
-
.find { |key| key['alg'] == encryption_method }
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def jwt_token
|
|
49
|
-
@jwt_token ||= JSON::JWT.new(iss:, sub:, aud:, exp:, jti:).compact
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def jwk
|
|
53
|
-
@jwk ||= JSON::JWK.new(bulk_private_key)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def authorization_request_headers
|
|
57
|
-
{
|
|
58
|
-
content_type:,
|
|
59
|
-
accept: 'application/json'
|
|
60
|
-
}.compact
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def authorization_request_query_values
|
|
64
|
-
{
|
|
65
|
-
'scope' => scope,
|
|
66
|
-
'grant_type' => grant_type,
|
|
67
|
-
'client_assertion_type' => client_assertion_type,
|
|
68
|
-
'client_assertion' => client_assertion.to_s
|
|
69
|
-
}.compact
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def client_assertion
|
|
73
|
-
@client_assertion ||=
|
|
74
|
-
begin
|
|
75
|
-
jwt_token.kid = jwk['kid']
|
|
76
|
-
jwk_private_key = jwk.to_key
|
|
77
|
-
jwt_token.sign(jwk_private_key, bulk_private_key['alg'])
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def authorization_request
|
|
82
|
-
uri = Addressable::URI.new
|
|
83
|
-
uri.query_values = authorization_request_query_values
|
|
84
|
-
|
|
85
|
-
{ body: uri.query, headers: authorization_request_headers }
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|