From 64db486562a967905d7361119d518181e1170ad2 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Sat, 16 Jan 2021 09:08:10 +0530 Subject: [PATCH] Add support to send custom parameters to introspection endpoint --- oauth2-ballerina/listener_oauth2_provider.bal | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/oauth2-ballerina/listener_oauth2_provider.bal b/oauth2-ballerina/listener_oauth2_provider.bal index 0eb74cb3..921795d5 100644 --- a/oauth2-ballerina/listener_oauth2_provider.bal +++ b/oauth2-ballerina/listener_oauth2_provider.bal @@ -23,12 +23,14 @@ import ballerina/time; # # + url - URL of the introspection server # + tokenTypeHint - A hint about the type of the token submitted for introspection +# + optionalParams - Map of optional parameters used for the introspection endpoint # + cacheConfig - Configurations for the cache used to store the OAuth2 token and other related information # + defaultTokenExpTimeInSeconds - Expiration time of the tokens if introspection response does not contain an `exp` field # + clientConfig - HTTP client configurations which calls the introspection server public type IntrospectionConfig record { string url; string tokenTypeHint?; + map optionalParams?; cache:CacheConfig cacheConfig?; int defaultTokenExpTimeInSeconds = 3600; ClientConfiguration clientConfig = {}; @@ -107,8 +109,9 @@ public class ListenerOAuth2Provider { # ``` # # + credential - OAuth2 token to be authenticated + # + optionalParams - Map of optional parameters use for the introspection endpoint # + return - `oauth2:IntrospectionResponse` if authentication is successful, or else an `oauth2:Error` if an error occurred - public isolated function authorize(string credential) returns IntrospectionResponse|Error { + public isolated function authorize(string credential, map? optionalParams = ()) returns IntrospectionResponse|Error { if (credential == "") { return prepareError("Credential cannot be empty."); } @@ -121,7 +124,7 @@ public class ListenerOAuth2Provider { } } - IntrospectionResponse|Error validationResult = validate(credential, self.introspectionConfig); + IntrospectionResponse|Error validationResult = validate(credential, self.introspectionConfig, optionalParams); if (validationResult is Error) { return prepareError("OAuth2 validation failed.", validationResult); } @@ -134,7 +137,8 @@ public class ListenerOAuth2Provider { } // Validates the provided OAuth2 token by calling the OAuth2 introspection endpoint. -isolated function validate(string token, IntrospectionConfig config) returns IntrospectionResponse|Error { +isolated function validate(string token, IntrospectionConfig config, map? optionalParams = ()) + returns IntrospectionResponse|Error { // Builds the request to be sent to the introspection endpoint. For more information, refer to the // [OAuth 2.0 Token Introspection RFC](https://tools.ietf.org/html/rfc7662#section-2.1) string textPayload = "token=" + token; @@ -142,6 +146,17 @@ isolated function validate(string token, IntrospectionConfig config) returns Int if (tokenTypeHint is string) { textPayload += "&token_type_hint=" + tokenTypeHint; } + map? configOptionalParams = config?.optionalParams; + if (configOptionalParams is map) { + foreach [string, string] [key, value] in configOptionalParams.entries() { + textPayload = textPayload + "&" + key.trim() + "=" + value.trim(); + } + } + if (optionalParams is map) { + foreach [string, string] [key, value] in optionalParams.entries() { + textPayload = textPayload + "&" + key.trim() + "=" + value.trim(); + } + } string|Error stringResponse = doHttpRequest(config.url, config.clientConfig, {}, textPayload); if (stringResponse is Error) { return prepareError("Failed to call introspection endpoint.", stringResponse);