-
-
Save dzmitry-savitski/0c9c7f54ad8c1c87fad44fa9b28924a7 to your computer and use it in GitHub Desktop.
Revisions
-
dzmitry-savitski revised this gist
Jun 24, 2025 . 1 changed file with 31 additions and 23 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,28 +1,36 @@ import java.time.Instant import java.time.format.DateTimeFormatter import java.util.UUID import javax.crypto.Mac import javax.crypto.spec.SecretKeySpec import org.forgerock.util.encode.Base64 def SECRET = "my-super-secret-key" // 🔐 Replace with real shared secret String computeSignature(String method, String path, String timestamp, String nonce, String body, String secret) { String data = "${method.toUpperCase()}\n${path}\n${timestamp}\n${nonce}\n${body}" SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256") Mac mac = Mac.getInstance("HmacSHA256") mac.init(keySpec) byte[] hmacBytes = mac.doFinal(data.getBytes("UTF-8")) return Base64.encode(hmacBytes) } def timestamp = DateTimeFormatter.ISO_INSTANT.format(Instant.now()) def nonce = UUID.randomUUID().toString() def method = request.method def path = request.uri.path def body = request.entity?.string ?: "" // Calculate signature def signature = computeSignature(method, path, timestamp, nonce, body, SECRET) // Add headers request.headers.add("X-Timestamp", timestamp) request.headers.add("X-Nonce", nonce) request.headers.add("X-API-Key", "your-key-id") // or use env/config request.headers.add("X-Signature", signature) logger.info("HMAC Signature Added: ${signature}") return next.handle(context, request) -
dzmitry-savitski revised this gist
Jun 16, 2025 . 1 changed file with 24 additions and 24 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,28 +1,28 @@ import org.forgerock.http.protocol.Request import org.forgerock.http.protocol.Response import org.forgerock.http.protocol.Form import org.forgerock.http.protocol.UrlEncodedFormEntity // Build form with credentials def form = new Form() form.add("grant_type", "client_credentials") form.add("client_id", "my-client-id") form.add("client_secret", "my-client-secret") form.add("scope", "my-scope") // Build request def req = new Request() req.setMethod("POST") req.setUri("https://auth.example.com/oauth2/token") req.getHeaders().add("Content-Type", "application/x-www-form-urlencoded") req.setEntity(new UrlEncodedFormEntity(form)) // Send the request and handle the response http.send(req).thenAccept { Response externalResp -> def status = externalResp.getStatus() def body = externalResp.getEntity().getString() logger.info("Token endpoint responded with status $status") logger.info("Body: $body") } return next.handle(context, request) -
dzmitry-savitski created this gist
Jun 16, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,28 @@ import org.forgerock.http.protocol.* import org.forgerock.openig.http.* // Replace with your actual values def clientId = "my-client-id" def clientSecret = "my-client-secret" def tokenEndpoint = "https://am.example.com/oauth2/access_token" // Prepare request def tokenRequest = new Request() tokenRequest.uri = tokenEndpoint tokenRequest.method = "POST" tokenRequest.headers.put("Content-Type", "application/x-www-form-urlencoded") tokenRequest.entity = "grant_type=client_credentials&client_id=${clientId}&client_secret=${clientSecret}" // Send the request using IG's internal HTTP client def response = client.call(tokenRequest) // Parse the access token if (response.status.successful) { def json = new JsonSlurper().parseText(response.entity.string) def accessToken = json.access_token logger.info("Got token: " + accessToken) return new Response(Status.OK).setEntity("Access token: ${accessToken}") } else { logger.error("Token request failed: ${response.status}") return new Response(Status.UNAUTHORIZED).setEntity("Failed to get token") }