Skip to content

Commit

Permalink
FI-3018: Allow multi-line custom headers in token introspection reque…
Browse files Browse the repository at this point in the history
…st (#77)
  • Loading branch information
emichaud998 authored Oct 10, 2024
1 parent c72e577 commit 621866b
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 38 deletions.
3 changes: 1 addition & 2 deletions lib/smart_app_launch/token_introspection_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,12 @@ class SMARTTokenIntrospectionGroup < Inferno::TestGroup
If the introspection endpoint is protected, testers must enter their own HTTP Authorization header for the introspection request. See
[RFC 7616 The 'Basic' HTTP Authentication Scheme](https://datatracker.ietf.org/doc/html/rfc7617) for the most common
approach that uses client credentials. Testers may also provide any additional parameters needed for their authorization
approach that uses client credentials. Testers may also provide any additional parameters needed for their authorization
server to complete the introspection request.
**Note:** For both the Authorization header and request parameters, user-input
values will be sent exactly as entered and therefore the tester must
URI-encode any appropriate values.
)

end
end
72 changes: 36 additions & 36 deletions lib/smart_app_launch/token_introspection_request_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,112 +11,112 @@ class SMARTTokenIntrospectionRequestGroup < Inferno::TestGroup
id :smart_token_introspection_request_group
description %(
This group of tests executes the token introspection requests and ensures the correct HTTP response is returned
but does not validate the contents of the token introspection response.
but does not validate the contents of the token introspection response.
If Inferno cannot reasonably be configured to be authorized to access the token introspection endpoint, these tests
If Inferno cannot reasonably be configured to be authorized to access the token introspection endpoint, these tests
can be skipped. Instead, an out-of-band token introspection request must be completed and the response body
manually provided as input for the Validate Introspection Response test group.
)

input_instructions %(
If the Request New Access Token group was executed, the access token input will auto-populate with that token.
Otherwise an active access token needs to be obtained out-of-band and input.
Per [RFC-7662](https://datatracker.ietf.org/doc/html/rfc7662#section-2), "the definition of an active token is
currently dependent upon the authorization server, but this is commonly a token that has been issued by this
authorization server, is not expired, has not been revoked, and is valid for use at the protected resource making
If the Request New Access Token group was executed, the access token input will auto-populate with that token.
Otherwise an active access token needs to be obtained out-of-band and input.
Per [RFC-7662](https://datatracker.ietf.org/doc/html/rfc7662#section-2), "the definition of an active token is
currently dependent upon the authorization server, but this is commonly a token that has been issued by this
authorization server, is not expired, has not been revoked, and is valid for use at the protected resource making
the introspection call."
If the introspection endpoint is protected, testers must enter their own HTTP Authorization header for the introspection request. See
[RFC 7616 The 'Basic' HTTP Authentication Scheme](https://datatracker.ietf.org/doc/html/rfc7617) for the most common
approach that uses client credentials. Testers may also provide any additional parameters needed for their authorization
approach that uses client credentials. Testers may also provide any additional parameters needed for their authorization
server to complete the introspection request.
**Note:** For both the Authorization header and request parameters, user-input
values will be sent exactly as entered and therefore the tester must URI-encode any appropriate values.
)

input :well_known_introspection_url,
title: 'Token Introspection Endpoint URL',
input :well_known_introspection_url,
title: 'Token Introspection Endpoint URL',
description: 'The complete URL of the token introspection endpoint.'

input :custom_authorization_header,
title: 'HTTP Authorization Header for Introspection Request',
title: 'Custom HTTP Headers for Introspection Request',
type: 'textarea',
optional: true,
description: %(
Include header name, auth scheme, and auth parameters.
Ex: 'Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW'
Add custom headers for the introspection request by adding each header's name and value with a new line
between each header.
Ex:
<Header 1 Name>: <Value 1>
)

input :optional_introspection_request_params,
title: 'Additional Introspection Request Parameters',
type: 'textarea',
optional: true,
description: %(
Any additional parameters to append to the request body, separated by &. Example: 'param1=abc&param2=def'
Any additional parameters to append to the request body, separated by &. Example: 'param1=abc&param2=def'
)

test do
title 'Token introspection endpoint returns a response when provided an active token'
description %(
This test will execute a token introspection request for an active token and ensure a 200 status and valid JSON
body are returned in the response.
body are returned in the response.
)

input :standalone_access_token,
input :standalone_access_token,
title: 'Access Token',
description: 'The access token to be introspected. MUST be active.'


output :active_token_introspection_response_body

run do

# If this is being chained from an earlier test, it might be blank if not present in the well-known endpoint
skip_if well_known_introspection_url.nil?, 'No introspection URL present in SMART well-known endpoint.'

headers = {'Accept' => 'application/json', 'Content-Type' => 'application/x-www-form-urlencoded'}
headers = { 'Accept' => 'application/json', 'Content-Type' => 'application/x-www-form-urlencoded' }
body = "token=#{standalone_access_token}"

if custom_authorization_header.present?
parsed_header = custom_authorization_header.split(':', 2)
assert parsed_header.length == 2, "Incorrect custom HTTP header format input, expected: '<header name>: <header value>'"
headers[parsed_header[0]] = parsed_header[1].strip
custom_headers = custom_authorization_header.split("\n")
custom_headers.each do |custom_header|
parsed_header = custom_header.split(':', 2)
assert parsed_header.length == 2,
'Incorrect custom HTTP header format input, expected: "<header name>: <header value>"'
headers[parsed_header[0]] = parsed_header[1].strip
end
end

if optional_introspection_request_params.present?
body += "&#{optional_introspection_request_params}"
end
body += "&#{optional_introspection_request_params}" if optional_introspection_request_params.present?

post(well_known_introspection_url, body: body, headers: headers)
post(well_known_introspection_url, body:, headers:)

assert_response_status(200)
output active_token_introspection_response_body: request.response_body
end

end

test do
test do
title 'Token introspection endpoint returns a response when provided an invalid token'
description %(
This test will execute a token introspection request for an invalid token and ensure a 200 status and valid JSON
body are returned in response.
body are returned in response.
)

output :invalid_token_introspection_response_body
run do

# If this is being chained from an earlier test, it might be blank if not present in the well-known endpoint
skip_if well_known_introspection_url.nil?, 'No introspection URL present in SMART well-known endpoint.'

headers = {'Accept' => 'application/json', 'Content-Type' => 'application/x-www-form-urlencoded'}
body = "token=invalid_token_value"
post(well_known_introspection_url, body: body, headers: headers)
headers = { 'Accept' => 'application/json', 'Content-Type' => 'application/x-www-form-urlencoded' }
body = 'token=invalid_token_value'
post(well_known_introspection_url, body:, headers:)

assert_response_status(200)
output invalid_token_introspection_response_body: request.response_body
end
end
end
end
end

0 comments on commit 621866b

Please # to comment.