Skip to content

Instantly share code, notes, and snippets.

@surajsau
Created April 8, 2022 10:47
Show Gist options
  • Save surajsau/6668456223ac599538c91049c835f0f9 to your computer and use it in GitHub Desktop.
Save surajsau/6668456223ac599538c91049c835f0f9 to your computer and use it in GitHub Desktop.
HERE Platform Request OAuth 2.0 Token API's HeaderInterceptor
/*
Reference link: https://developer.here.com/documentation/identity-access-management/dev_guide/topics/sdk.html
*/
class OAuthInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val timeStampInMillis = System.currentTimeMillis()
val request = chain.request()
val headerMapping = mapOf(
"grant_type" to "client_credentials",
"oauth_consumer_key" to "$HERE_PLATFORM_KEY",
"oauth_nonce" to "$timeStampInMillis", // any unique value per request
"oauth_signature_method" to "HMAC-SHA256",
"oauth_timestamp" to "${timeStampInMillis/1000}",
"oauth_version" to "1.0"
)
/*
parameters: grant_type=client_credentials
&scope=hrn:here:authorization::myrealm:project/myproject (optional)
&oauth_consumer_key=access-key-id-1234
&oauth_nonce=LIIpk4 (unique value per req.)
&oauth_signature_method=HMAC-SHA256
&oauth_timestamp=1456945283 (in seconds)
&oauth_version=1.0
Signature Base String format: POST
&{{book.accountApiURL}}/oauth2/token
&<URL encoded parameter string>
*/
val signatureBaseString = listOf(
"POST",
"${OAUTH_BASE_URL}token".urlEncode(),
headerMapping.map { (key, value) -> "$key=$value" }.joinToString("&").urlEncode()
)
.joinToString("&")
val signature = createSignature(
key = "${HERE_PLATFORM_SECRET.urlEncode()}&",
data = signatureBaseString
).urlEncode()
/*
"Authorization: OAuth
oauth_consumer_key=\"<access-key-id-1234>\",
oauth_signature_method=\"HMAC-SHA256\",
oauth_timestamp=\"<timestamp-in-seconds>\",
oauth_nonce=\"<unique-value-per-request>\",
oauth_version=\"1.0\",
oauth_signature=\"RFylHbbKERcJf1QTYPF0POg1lVsXm2TmLxsGOKxHPmA%3D\"
*/
val oAuthHeader = headerMapping.minus("grant_type")
.plus(Pair("oauth_signature", signature))
.map { (key, value) -> "$key=\"$value\"" }
.joinToString(",")
val headers = request.headers.newBuilder()
.add("Authorization", "OAuth $oAuthHeader")
.build()
val newRequest = request.newBuilder()
.headers(headers)
.build()
return chain.proceed(newRequest)
}
/*
Create the signature by passing the signature base string and signing key to the HMAC-SHA256
hashing algorithm and converting the result to a base64 string.
*/
private fun createSignature(key: String, data: String): String {
val mac = Mac.getInstance("HmacSHA256").apply {
val secretKey = SecretKeySpec(key.toByteArray(), "HmacSHA256")
init(secretKey)
}
return runCatching {
Base64.encodeToString(mac.doFinal(data.toByteArray()), Base64.DEFAULT)
.replace("\n", "")
}.getOrDefault("")
}
private fun String.urlEncode() = URLEncoder.encode(this, "utf-8")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment