smart_app_launch_test_kit 0.5.1 → 0.6.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/config/presets/SMART_RunClientAgainstServer.json.erb +31 -0
- data/config/presets/SMART_RunServerAgainstClient.json.erb +42 -0
- data/config/presets/inferno_reference_server_preset.json +15 -86
- data/config/presets/inferno_reference_server_stu2_2_preset.json +20 -69
- data/config/presets/inferno_reference_server_stu2_preset.json +20 -69
- data/lib/smart_app_launch/app_redirect_test.rb +12 -44
- data/lib/smart_app_launch/app_redirect_test_stu2.rb +2 -17
- data/lib/smart_app_launch/backend_services_authorization_group.rb +33 -59
- data/lib/smart_app_launch/backend_services_authorization_request_builder.rb +22 -9
- data/lib/smart_app_launch/backend_services_authorization_request_success_test.rb +32 -24
- data/lib/smart_app_launch/backend_services_authorization_response_body_test.rb +23 -5
- data/lib/smart_app_launch/backend_services_invalid_client_assertion_test.rb +30 -25
- data/lib/smart_app_launch/backend_services_invalid_grant_type_test.rb +30 -24
- data/lib/smart_app_launch/backend_services_invalid_jwt_test.rb +31 -26
- data/lib/smart_app_launch/client_assertion_builder.rb +27 -12
- data/lib/smart_app_launch/client_stu2_2_suite.rb +79 -0
- data/lib/smart_app_launch/client_suite/client_access_group.rb +26 -0
- data/lib/smart_app_launch/client_suite/client_access_interaction_test.rb +64 -0
- data/lib/smart_app_launch/client_suite/client_registration_group.rb +15 -0
- data/lib/smart_app_launch/client_suite/client_registration_verification_test.rb +52 -0
- data/lib/smart_app_launch/client_suite/client_token_request_verification_test.rb +146 -0
- data/lib/smart_app_launch/client_suite/client_token_use_verification_test.rb +47 -0
- data/lib/smart_app_launch/cors_openid_fhir_user_claim_test.rb +2 -2
- data/lib/smart_app_launch/cors_token_exchange_test.rb +2 -2
- data/lib/smart_app_launch/discovery_stu1_group.rb +6 -2
- data/lib/smart_app_launch/docs/demo/FHIR Request.postman_collection.json +81 -0
- data/lib/smart_app_launch/docs/smart_stu2_2_client_suite_description.md +121 -0
- data/lib/smart_app_launch/ehr_launch_group.rb +41 -24
- data/lib/smart_app_launch/ehr_launch_group_stu2.rb +26 -10
- data/lib/smart_app_launch/ehr_launch_group_stu2_2.rb +0 -16
- data/lib/smart_app_launch/endpoints/echoing_fhir_responder.rb +52 -0
- data/lib/smart_app_launch/endpoints/mock_smart_server/token.rb +27 -0
- data/lib/smart_app_launch/endpoints/mock_smart_server.rb +217 -0
- data/lib/smart_app_launch/metadata.rb +2 -2
- data/lib/smart_app_launch/openid_fhir_user_claim_test.rb +5 -4
- data/lib/smart_app_launch/openid_token_payload_test.rb +6 -8
- data/lib/smart_app_launch/smart_stu1_suite.rb +32 -24
- data/lib/smart_app_launch/smart_stu2_2_suite.rb +57 -30
- data/lib/smart_app_launch/smart_stu2_suite.rb +57 -31
- data/lib/smart_app_launch/smart_tls_test.rb +14 -0
- data/lib/smart_app_launch/standalone_launch_group.rb +42 -25
- data/lib/smart_app_launch/standalone_launch_group_stu2.rb +26 -10
- data/lib/smart_app_launch/standalone_launch_group_stu2_2.rb +0 -16
- data/lib/smart_app_launch/tags.rb +7 -0
- data/lib/smart_app_launch/token_exchange_stu2_2_test.rb +5 -17
- data/lib/smart_app_launch/token_exchange_stu2_test.rb +8 -67
- data/lib/smart_app_launch/token_exchange_test.rb +18 -38
- data/lib/smart_app_launch/token_introspection_access_token_group.rb +12 -4
- data/lib/smart_app_launch/token_introspection_access_token_group_stu2_2.rb +9 -1
- data/lib/smart_app_launch/token_introspection_group.rb +2 -4
- data/lib/smart_app_launch/token_introspection_request_group.rb +2 -4
- data/lib/smart_app_launch/token_introspection_response_group.rb +64 -49
- data/lib/smart_app_launch/token_refresh_body_test.rb +9 -2
- data/lib/smart_app_launch/token_refresh_stu2_test.rb +10 -17
- data/lib/smart_app_launch/token_refresh_test.rb +19 -20
- data/lib/smart_app_launch/token_response_body_test.rb +14 -4
- data/lib/smart_app_launch/token_response_body_test_stu2_2.rb +3 -2
- data/lib/smart_app_launch/urls.rb +40 -0
- data/lib/smart_app_launch/version.rb +2 -2
- data/lib/smart_app_launch/well_known_endpoint_test.rb +11 -1
- data/lib/smart_app_launch_test_kit.rb +1 -0
- metadata +21 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2608337f4d0d2651ba2395ecda2f89263ebe14d039f3d730ae2f82df3fe49855
|
4
|
+
data.tar.gz: b7a480f55c94dec25865151faefd76045096d21b5333a9c5bf56cf73eb7310bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 853bd240f1fccdfd72ab79ff89b420b9b1edebd1d1fbd01e9dd3f1e206a29fae3f84f79371e0c7406dc9f3f5bde6ddf7ef51167cf2537f97b56bc36d245d7ef8
|
7
|
+
data.tar.gz: 5cf5840b0061bb6605e68e5d2ce4bf8e07c3039b4e53d8678b2d5cad19e27c352c751eadc8325dfd6ba3df02ddc28f9a7a8e5664eda85aa6cb77c93d1485b52a
|
@@ -0,0 +1,31 @@
|
|
1
|
+
{
|
2
|
+
"title": "Demo: Run Against the SMART Server Suite",
|
3
|
+
"id": "smart_run_client_against_server_v2_2",
|
4
|
+
"test_suite_id": "smart_client_stu2_2",
|
5
|
+
"inputs": [
|
6
|
+
{
|
7
|
+
"name": "smart_jwk_set",
|
8
|
+
"description": "The SMART client's JSON Web Key Set. May be provided as either a publicly accessible url containing the JWKS, or the raw JWKS.",
|
9
|
+
"optional": true,
|
10
|
+
"title": "SMART JSON Web Key Set (JWKS)",
|
11
|
+
"type": "textarea",
|
12
|
+
"value": "<%= Inferno::Application['base_url'] %>/custom/smart_stu2_2/.well-known/jwks.json"
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"name": "client_id",
|
16
|
+
"description": "If a particular client id is desired, put it here. Otherwise a default of the Inferno session id will be used.",
|
17
|
+
"optional": true,
|
18
|
+
"title": "Client Id",
|
19
|
+
"type": "text",
|
20
|
+
"value": "smart_client_test_demo"
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"name": "echoed_fhir_response",
|
24
|
+
"description": "JSON representation of a FHIR resource for Inferno to echo when a request is made to the simulated FHIR server. The provided content will be echoed back exactly and no check will be made that it is appropriate for the request made. If nothing is provided, an OperationOutcome will be returned.",
|
25
|
+
"optional": true,
|
26
|
+
"title": "FHIR Response to Echo",
|
27
|
+
"type": "textarea",
|
28
|
+
"value": "{\n \"resourceType\": \"Patient\",\n \"id\": \"example\",\n \"name\": [\n {\n \"family\": \"Chalmers\",\n \"given\": [\n \"Peter\",\n \"James\"\n ]\n }\n ],\n \"gender\": \"male\",\n \"birthDate\": \"1974-12-25\",\n \"address\": [\n {\n \"line\": [\n \"534 Erewhon St\"\n ],\n \"city\": \"Ann Arbor\",\n \"state\": \"MI\",\n \"postalCode\": \"48108\"\n }\n ]\n}"
|
29
|
+
}
|
30
|
+
]
|
31
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
{
|
2
|
+
"title": "Demo: Run Against the SMART Client Suite",
|
3
|
+
"id": "smart_run_server_against_client_v2_2",
|
4
|
+
"test_suite_id": "smart_stu2_2",
|
5
|
+
"inputs": [
|
6
|
+
{
|
7
|
+
"name": "url",
|
8
|
+
"description": "URL of the FHIR endpoint used by SMART applications",
|
9
|
+
"title": "FHIR Endpoint",
|
10
|
+
"type": "text",
|
11
|
+
"value": "<%= Inferno::Application['base_url'] %>/custom/smart_client_stu2_2/fhir"
|
12
|
+
},
|
13
|
+
{
|
14
|
+
"name": "backend_services_smart_auth_info",
|
15
|
+
"options": {
|
16
|
+
"mode": "auth",
|
17
|
+
"components": [
|
18
|
+
{
|
19
|
+
"name": "auth_type",
|
20
|
+
"default": "backend_services",
|
21
|
+
"locked": "true"
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"name": "use_discovery",
|
25
|
+
"locked": true
|
26
|
+
}
|
27
|
+
]
|
28
|
+
},
|
29
|
+
"title": "Backend Services Credentials",
|
30
|
+
"type": "auth_info",
|
31
|
+
"value": {
|
32
|
+
"encryption_algorithm": "ES384",
|
33
|
+
"auth_type": "backend_services",
|
34
|
+
"use_discovery": "true",
|
35
|
+
"token_url": "<%= Inferno::Application['base_url'] %>/custom/smart_client_stu2_2/auth/token",
|
36
|
+
"requested_scopes": "system/*.rs",
|
37
|
+
"client_id": "smart_client_test_demo"
|
38
|
+
},
|
39
|
+
"default": {}
|
40
|
+
}
|
41
|
+
]
|
42
|
+
}
|
@@ -9,95 +9,24 @@
|
|
9
9
|
"value": "https://inferno.healthit.gov/reference-server/r4"
|
10
10
|
},
|
11
11
|
{
|
12
|
-
"name": "
|
13
|
-
"type": "
|
14
|
-
"value":
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
"value": "launch/patient openid fhirUser offline_access patient/*.read"
|
20
|
-
},
|
21
|
-
{
|
22
|
-
"name": "use_pkce",
|
23
|
-
"type": "radio",
|
24
|
-
"title": "Proof Key for Code Exchange (PKCE)",
|
25
|
-
"options": {
|
26
|
-
"list_options": [
|
27
|
-
{
|
28
|
-
"label": "Enabled",
|
29
|
-
"value": "true"
|
30
|
-
},
|
31
|
-
{
|
32
|
-
"label": "Disabled",
|
33
|
-
"value": "false"
|
34
|
-
}
|
35
|
-
]
|
36
|
-
},
|
37
|
-
"value": "false"
|
38
|
-
},
|
39
|
-
{
|
40
|
-
"name": "pkce_code_challenge_method",
|
41
|
-
"type": "radio",
|
42
|
-
"optional": true,
|
43
|
-
"title": "PKCE Code Challenge Method",
|
44
|
-
"options": {
|
45
|
-
"list_options": [
|
46
|
-
{
|
47
|
-
"label": "S256",
|
48
|
-
"value": "S256"
|
49
|
-
},
|
50
|
-
{
|
51
|
-
"label": "plain",
|
52
|
-
"value": "plain"
|
53
|
-
}
|
54
|
-
]
|
55
|
-
},
|
56
|
-
"value": "S256"
|
57
|
-
},
|
58
|
-
{
|
59
|
-
"name": "client_auth_type",
|
60
|
-
"value": "public",
|
61
|
-
"_title": "Client Authentication Method",
|
62
|
-
"_type": "radio",
|
63
|
-
"_options": {
|
64
|
-
"list_options": [
|
65
|
-
{
|
66
|
-
"label": "Public",
|
67
|
-
"value": "public"
|
68
|
-
},
|
69
|
-
{
|
70
|
-
"label": "Confidential Symmetric",
|
71
|
-
"value": "confidential_symmetric"
|
72
|
-
},
|
73
|
-
{
|
74
|
-
"label": "Confidential Asymmetric",
|
75
|
-
"value": "confidential_asymmetric"
|
76
|
-
}
|
77
|
-
]
|
12
|
+
"name": "standalone_smart_auth_info",
|
13
|
+
"type": "auth_info",
|
14
|
+
"value": {
|
15
|
+
"auth_type": "public",
|
16
|
+
"requested_scopes": "launch/patient openid fhirUser offline_access patient/*.read",
|
17
|
+
"client_id": "SAMPLE_PUBLIC_CLIENT_ID",
|
18
|
+
"pkce_support": "disabled"
|
78
19
|
}
|
79
20
|
},
|
80
21
|
{
|
81
|
-
"name": "
|
82
|
-
"type": "
|
83
|
-
"
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
"value": "SAMPLE_PUBLIC_CLIENT_ID"
|
90
|
-
},
|
91
|
-
{
|
92
|
-
"name": "ehr_requested_scopes",
|
93
|
-
"type": "text",
|
94
|
-
"value": "launch openid fhirUser offline_access user/*.read"
|
95
|
-
},
|
96
|
-
{
|
97
|
-
"name": "ehr_client_secret",
|
98
|
-
"type": "text",
|
99
|
-
"optional": true,
|
100
|
-
"value": null
|
22
|
+
"name": "ehr_smart_auth_info",
|
23
|
+
"type": "auth_info",
|
24
|
+
"value": {
|
25
|
+
"auth_type": "public",
|
26
|
+
"requested_scopes": "launch openid fhirUser offline_access user/*.read",
|
27
|
+
"client_id": "SAMPLE_PUBLIC_CLIENT_ID",
|
28
|
+
"pkce_support": "disabled"
|
29
|
+
}
|
101
30
|
}
|
102
31
|
]
|
103
32
|
}
|
@@ -9,81 +9,32 @@
|
|
9
9
|
"value": "https://inferno.healthit.gov/reference-server/r4"
|
10
10
|
},
|
11
11
|
{
|
12
|
-
"name": "
|
13
|
-
"type": "
|
14
|
-
"value":
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
"type": "text",
|
19
|
-
"value": "launch/patient openid fhirUser offline_access patient/*.read"
|
20
|
-
},
|
21
|
-
{
|
22
|
-
"name": "standalone_client_secret",
|
23
|
-
"type": "text",
|
24
|
-
"optional": true,
|
25
|
-
"value": null
|
26
|
-
},
|
27
|
-
{
|
28
|
-
"name": "ehr_client_id",
|
29
|
-
"type": "text",
|
30
|
-
"value": "SAMPLE_PUBLIC_CLIENT_ID"
|
31
|
-
},
|
32
|
-
{
|
33
|
-
"name": "ehr_requested_scopes",
|
34
|
-
"type": "text",
|
35
|
-
"value": "launch openid fhirUser offline_access user/*.read"
|
36
|
-
},
|
37
|
-
{
|
38
|
-
"name": "ehr_client_secret",
|
39
|
-
"type": "text",
|
40
|
-
"optional": true,
|
41
|
-
"value": null
|
42
|
-
},
|
43
|
-
{
|
44
|
-
"name": "client_auth_encryption_method",
|
45
|
-
"value": "ES384",
|
46
|
-
"_title": "Encryption Method (Confidential Asymmetric Client Auth Only)",
|
47
|
-
"_type": "radio",
|
48
|
-
"_options": {
|
49
|
-
"list_options": [
|
50
|
-
{
|
51
|
-
"label": "ES384",
|
52
|
-
"value": "ES384"
|
53
|
-
},
|
54
|
-
{
|
55
|
-
"label": "RS384",
|
56
|
-
"value": "RS384"
|
57
|
-
}
|
58
|
-
]
|
12
|
+
"name": "standalone_smart_auth_info",
|
13
|
+
"type": "auth_info",
|
14
|
+
"value": {
|
15
|
+
"auth_type":"public",
|
16
|
+
"requested_scopes":"launch/patient openid fhirUser offline_access patient/*.rs",
|
17
|
+
"client_id":"SAMPLE_PUBLIC_CLIENT_ID"
|
59
18
|
}
|
60
19
|
},
|
61
20
|
{
|
62
|
-
"name": "
|
63
|
-
"
|
64
|
-
"
|
65
|
-
|
66
|
-
|
67
|
-
"
|
68
|
-
{
|
69
|
-
"label": "Public",
|
70
|
-
"value": "public"
|
71
|
-
},
|
72
|
-
{
|
73
|
-
"label": "Confidential Symmetric",
|
74
|
-
"value": "confidential_symmetric"
|
75
|
-
},
|
76
|
-
{
|
77
|
-
"label": "Confidential Asymmetric",
|
78
|
-
"value": "confidential_asymmetric"
|
79
|
-
}
|
80
|
-
]
|
21
|
+
"name": "ehr_smart_auth_info",
|
22
|
+
"type": "auth_info",
|
23
|
+
"value": {
|
24
|
+
"auth_type":"public",
|
25
|
+
"requested_scopes":"launch openid fhirUser offline_access user/*.rs",
|
26
|
+
"client_id":"SAMPLE_PUBLIC_CLIENT_ID"
|
81
27
|
}
|
82
28
|
},
|
83
29
|
{
|
84
|
-
"name": "
|
85
|
-
"type": "
|
86
|
-
"value":
|
30
|
+
"name": "backend_services_smart_auth_info",
|
31
|
+
"type": "auth_info",
|
32
|
+
"value": {
|
33
|
+
"auth_type":"backend_services",
|
34
|
+
"requested_scopes":"system/*.read",
|
35
|
+
"client_id":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InJlZ2lzdHJhdGlvbi10b2tlbiJ9.eyJqd2tzX3VybCI6Imh0dHA6Ly8xMC4xNS4yNTIuNzMvaW5mZXJuby8ud2VsbC1rbm93bi9qd2tzLmpzb24iLCJhY2Nlc3NUb2tlbnNFeHBpcmVJbiI6MTUsImlhdCI6MTU5NzQxMzE5NX0.q4v4Msc74kN506KTZ0q_minyapJw0gwlT6M_uiL73S4",
|
36
|
+
"encryption_algorithm":"ES384"
|
37
|
+
}
|
87
38
|
}
|
88
39
|
]
|
89
40
|
}
|
@@ -9,81 +9,32 @@
|
|
9
9
|
"value": "https://inferno.healthit.gov/reference-server/r4"
|
10
10
|
},
|
11
11
|
{
|
12
|
-
"name": "
|
13
|
-
"type": "
|
14
|
-
"value":
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
"type": "text",
|
19
|
-
"value": "launch/patient openid fhirUser offline_access patient/*.read"
|
20
|
-
},
|
21
|
-
{
|
22
|
-
"name": "standalone_client_secret",
|
23
|
-
"type": "text",
|
24
|
-
"optional": true,
|
25
|
-
"value": null
|
26
|
-
},
|
27
|
-
{
|
28
|
-
"name": "ehr_client_id",
|
29
|
-
"type": "text",
|
30
|
-
"value": "SAMPLE_PUBLIC_CLIENT_ID"
|
31
|
-
},
|
32
|
-
{
|
33
|
-
"name": "ehr_requested_scopes",
|
34
|
-
"type": "text",
|
35
|
-
"value": "launch openid fhirUser offline_access user/*.read"
|
36
|
-
},
|
37
|
-
{
|
38
|
-
"name": "ehr_client_secret",
|
39
|
-
"type": "text",
|
40
|
-
"optional": true,
|
41
|
-
"value": null
|
42
|
-
},
|
43
|
-
{
|
44
|
-
"name": "client_auth_encryption_method",
|
45
|
-
"value": "ES384",
|
46
|
-
"_title": "Encryption Method (Confidential Asymmetric Client Auth Only)",
|
47
|
-
"_type": "radio",
|
48
|
-
"_options": {
|
49
|
-
"list_options": [
|
50
|
-
{
|
51
|
-
"label": "ES384",
|
52
|
-
"value": "ES384"
|
53
|
-
},
|
54
|
-
{
|
55
|
-
"label": "RS384",
|
56
|
-
"value": "RS384"
|
57
|
-
}
|
58
|
-
]
|
12
|
+
"name": "standalone_smart_auth_info",
|
13
|
+
"type": "auth_info",
|
14
|
+
"value": {
|
15
|
+
"auth_type": "public",
|
16
|
+
"requested_scopes":"launch/patient openid fhirUser offline_access patient/*.rs",
|
17
|
+
"client_id":"SAMPLE_PUBLIC_CLIENT_ID"
|
59
18
|
}
|
60
19
|
},
|
61
20
|
{
|
62
|
-
"name": "
|
63
|
-
"
|
64
|
-
"
|
65
|
-
|
66
|
-
|
67
|
-
"
|
68
|
-
{
|
69
|
-
"label": "Public",
|
70
|
-
"value": "public"
|
71
|
-
},
|
72
|
-
{
|
73
|
-
"label": "Confidential Symmetric",
|
74
|
-
"value": "confidential_symmetric"
|
75
|
-
},
|
76
|
-
{
|
77
|
-
"label": "Confidential Asymmetric",
|
78
|
-
"value": "confidential_asymmetric"
|
79
|
-
}
|
80
|
-
]
|
21
|
+
"name": "ehr_smart_auth_info",
|
22
|
+
"type": "auth_info",
|
23
|
+
"value": {
|
24
|
+
"auth_type":"public",
|
25
|
+
"requested_scopes":"launch openid fhirUser offline_access user/*.rs",
|
26
|
+
"client_id":"SAMPLE_PUBLIC_CLIENT_ID"
|
81
27
|
}
|
82
28
|
},
|
83
29
|
{
|
84
|
-
"name": "
|
85
|
-
"type": "
|
86
|
-
"value":
|
30
|
+
"name": "backend_services_smart_auth_info",
|
31
|
+
"type": "auth_info",
|
32
|
+
"value": {
|
33
|
+
"auth_type":"backend_services",
|
34
|
+
"requested_scopes":"system/*.read",
|
35
|
+
"client_id":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InJlZ2lzdHJhdGlvbi10b2tlbiJ9.eyJqd2tzX3VybCI6Imh0dHA6Ly8xMC4xNS4yNTIuNzMvaW5mZXJuby8ud2VsbC1rbm93bi9qd2tzLmpzb24iLCJhY2Nlc3NUb2tlbnNFeHBpcmVJbiI6MTUsImlhdCI6MTU5NzQxMzE5NX0.q4v4Msc74kN506KTZ0q_minyapJw0gwlT6M_uiL73S4",
|
36
|
+
"encryption_algorithm":"ES384"
|
37
|
+
}
|
87
38
|
}
|
88
39
|
]
|
89
40
|
}
|
@@ -9,41 +9,8 @@ module SMARTAppLaunch
|
|
9
9
|
)
|
10
10
|
id :smart_app_redirect
|
11
11
|
|
12
|
-
input :
|
13
|
-
input :
|
14
|
-
title: 'Proof Key for Code Exchange (PKCE)',
|
15
|
-
type: 'radio',
|
16
|
-
default: 'false',
|
17
|
-
options: {
|
18
|
-
list_options: [
|
19
|
-
{
|
20
|
-
label: 'Enabled',
|
21
|
-
value: 'true'
|
22
|
-
},
|
23
|
-
{
|
24
|
-
label: 'Disabled',
|
25
|
-
value: 'false'
|
26
|
-
}
|
27
|
-
]
|
28
|
-
}
|
29
|
-
input :pkce_code_challenge_method,
|
30
|
-
optional: true,
|
31
|
-
title: 'PKCE Code Challenge Method',
|
32
|
-
type: 'radio',
|
33
|
-
default: 'S256',
|
34
|
-
options: {
|
35
|
-
list_options: [
|
36
|
-
{
|
37
|
-
label: 'S256',
|
38
|
-
value: 'S256'
|
39
|
-
},
|
40
|
-
{
|
41
|
-
label: 'plain',
|
42
|
-
value: 'plain'
|
43
|
-
}
|
44
|
-
]
|
45
|
-
}
|
46
|
-
|
12
|
+
input :url
|
13
|
+
input :smart_auth_info, type: :auth_info, options: { mode: 'auth' }
|
47
14
|
output :state, :pkce_code_challenge, :pkce_code_verifier
|
48
15
|
receives_request :redirect
|
49
16
|
|
@@ -91,17 +58,17 @@ module SMARTAppLaunch
|
|
91
58
|
|
92
59
|
run do
|
93
60
|
assert_valid_http_uri(
|
94
|
-
|
95
|
-
"OAuth2 Authorization Endpoint '#{
|
61
|
+
smart_auth_info.auth_url,
|
62
|
+
"OAuth2 Authorization Endpoint '#{smart_auth_info.auth_url}' is not a valid URI"
|
96
63
|
)
|
97
64
|
|
98
65
|
output state: SecureRandom.uuid
|
99
66
|
|
100
67
|
oauth2_params = {
|
101
68
|
'response_type' => 'code',
|
102
|
-
'client_id' => client_id,
|
69
|
+
'client_id' => smart_auth_info.client_id,
|
103
70
|
'redirect_uri' => redirect_uri,
|
104
|
-
'scope' => requested_scopes,
|
71
|
+
'scope' => smart_auth_info.requested_scopes,
|
105
72
|
'state' => state,
|
106
73
|
'aud' => aud
|
107
74
|
}
|
@@ -112,11 +79,11 @@ module SMARTAppLaunch
|
|
112
79
|
oauth2_params['launch'] = launch
|
113
80
|
end
|
114
81
|
|
115
|
-
if
|
82
|
+
if smart_auth_info.pkce_enabled?
|
116
83
|
# code verifier must be between 43 and 128 characters
|
117
|
-
code_verifier = SecureRandom.uuid
|
84
|
+
code_verifier = "#{SecureRandom.uuid}-#{SecureRandom.uuid}"
|
118
85
|
code_challenge =
|
119
|
-
if
|
86
|
+
if smart_auth_info.s256_code_challenge_method?
|
120
87
|
self.class.calculate_s256_challenge(code_verifier)
|
121
88
|
else
|
122
89
|
code_verifier
|
@@ -124,11 +91,12 @@ module SMARTAppLaunch
|
|
124
91
|
|
125
92
|
output pkce_code_verifier: code_verifier, pkce_code_challenge: code_challenge
|
126
93
|
|
127
|
-
oauth2_params.merge!('code_challenge' => code_challenge,
|
94
|
+
oauth2_params.merge!('code_challenge' => code_challenge,
|
95
|
+
'code_challenge_method' => smart_auth_info.pkce_code_challenge_method)
|
128
96
|
end
|
129
97
|
|
130
98
|
authorization_url = authorization_url_builder(
|
131
|
-
|
99
|
+
smart_auth_info.auth_url,
|
132
100
|
oauth2_params
|
133
101
|
)
|
134
102
|
|
@@ -15,22 +15,7 @@ module SMARTAppLaunch
|
|
15
15
|
Request](http://hl7.org/fhir/smart-app-launch/STU2/app-launch.html#request-4)
|
16
16
|
)
|
17
17
|
|
18
|
-
input :
|
19
|
-
title: 'Authorization Request Method',
|
20
|
-
type: 'radio',
|
21
|
-
default: 'get',
|
22
|
-
options: {
|
23
|
-
list_options: [
|
24
|
-
{
|
25
|
-
label: 'GET',
|
26
|
-
value: 'get'
|
27
|
-
},
|
28
|
-
{
|
29
|
-
label: 'POST',
|
30
|
-
value: 'post'
|
31
|
-
}
|
32
|
-
]
|
33
|
-
}
|
18
|
+
input :smart_auth_info, type: :auth_info, options: { mode: 'auth' }
|
34
19
|
|
35
20
|
def default_post_authorization_uri
|
36
21
|
"#{Inferno::Application['base_url']}/custom/smart_stu2/post_auth"
|
@@ -41,7 +26,7 @@ module SMARTAppLaunch
|
|
41
26
|
end
|
42
27
|
|
43
28
|
def authorization_url_builder(url, params)
|
44
|
-
return super if
|
29
|
+
return super if smart_auth_info.get_auth_request?
|
45
30
|
|
46
31
|
post_params = params.merge(auth_url: url)
|
47
32
|
|
@@ -13,67 +13,41 @@ module SMARTAppLaunch
|
|
13
13
|
|
14
14
|
id :backend_services_authorization
|
15
15
|
|
16
|
-
input :
|
17
|
-
title: 'Backend Services
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
description: <<~DESCRIPTION,
|
33
|
-
The server is required to suport either ES384 or RS384 encryption methods for JWT signature verification.
|
34
|
-
Select which method to use.
|
35
|
-
DESCRIPTION
|
36
|
-
type: 'radio',
|
37
|
-
default: 'ES384',
|
38
|
-
options: {
|
39
|
-
list_options: [
|
40
|
-
{
|
41
|
-
label: 'ES384',
|
42
|
-
value: 'ES384'
|
43
|
-
},
|
44
|
-
{
|
45
|
-
label: 'RS384',
|
46
|
-
value: 'RS384'
|
16
|
+
input :smart_auth_info,
|
17
|
+
title: 'Backend Services Credentials',
|
18
|
+
type: :auth_info,
|
19
|
+
options: {
|
20
|
+
mode: 'auth',
|
21
|
+
components: [
|
22
|
+
{
|
23
|
+
name: :auth_type,
|
24
|
+
default: 'backend_services',
|
25
|
+
locked: 'true'
|
26
|
+
},
|
27
|
+
{
|
28
|
+
name: :use_discovery,
|
29
|
+
locked: true
|
30
|
+
}
|
31
|
+
]
|
47
32
|
}
|
48
|
-
]
|
49
|
-
}
|
50
|
-
input :backend_services_jwks_kid,
|
51
|
-
title: 'Backend Services JWKS kid',
|
52
|
-
description: <<~DESCRIPTION,
|
53
|
-
The key ID of the JWKS private key to use for signing the client assertion when fetching an auth token.
|
54
|
-
Defaults to the first JWK in the list if no kid is supplied.
|
55
|
-
DESCRIPTION
|
56
|
-
optional: true
|
57
|
-
|
58
|
-
output :bearer_token
|
59
|
-
|
60
|
-
test from: :tls_version_test do
|
61
|
-
title 'Authorization service token endpoint secured by transport layer security'
|
62
|
-
description <<~DESCRIPTION
|
63
|
-
The [SMART App Launch 2.0.0 IG specification for Backend Services](https://hl7.org/fhir/smart-app-launch/STU2/backend-services.html#request-1)
|
64
|
-
states "the client SHALL use the Transport Layer Security (TLS) Protocol Version 1.2 (RFC5246)
|
65
|
-
or a more recent version of TLS to authenticate the identity of the FHIR authorization server and to
|
66
|
-
establish an encrypted, integrity-protected link for securing all exchanges between the client and the
|
67
|
-
FHIR authorization server’s token endpoint. All exchanges described herein between the client and the
|
68
|
-
FHIR server SHALL be secured using TLS V1.2 or a more recent version of TLS."
|
69
|
-
DESCRIPTION
|
70
|
-
id :smart_backend_services_token_tls_version
|
71
33
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
34
|
+
test from: :smart_tls,
|
35
|
+
id: :smart_backend_services_token_tls_version,
|
36
|
+
title: 'Authorization service token endpoint secured by transport layer security',
|
37
|
+
description: <<~DESCRIPTION,
|
38
|
+
The [SMART App Launch 2.0.0 IG specification for Backend Services](https://hl7.org/fhir/smart-app-launch/STU2/backend-services.html#request-1)
|
39
|
+
states "the client SHALL use the Transport Layer Security (TLS) Protocol Version 1.2 (RFC5246)
|
40
|
+
or a more recent version of TLS to authenticate the identity of the FHIR authorization server and to
|
41
|
+
establish an encrypted, integrity-protected link for securing all exchanges between the client and the
|
42
|
+
FHIR authorization server’s token endpoint. All exchanges described herein between the client and the
|
43
|
+
FHIR server SHALL be secured using TLS V1.2 or a more recent version of TLS."
|
44
|
+
DESCRIPTION
|
45
|
+
config: {
|
46
|
+
options: {
|
47
|
+
minimum_allowed_version: OpenSSL::SSL::TLS1_2_VERSION,
|
48
|
+
smart_endpoint_key: :token_url
|
49
|
+
}
|
50
|
+
}
|
77
51
|
|
78
52
|
test from: :smart_backend_services_invalid_grant_type
|
79
53
|
|