Setting Up AtScale API with Okta SAML

This is a procedural guide on how to set up an AtScale API call when security is set with Okta SAML.

Pre-requisite: you must already have Okta fully integrated with AtScale and can do an SSO from your browser.

For AtScale to recognize the API, with SSO/SAML, we don’t use JWT (token), but instead, we are using SAMLResponse/Cookies that get returned from your IDP provider. Follow these steps to get the token and proper SAMLResponse from your IDP.

Okta

First, you need to get the embedded link from Okta Admin.

For this example: 

https://dev-755126.okta.com/home/atscale/0oa6e32b9yOhv18t84x7/aln1gtyixki1dVEmx1d8

 

The next step is to obtain the domain URL for your Okta SAML authentication.

For this example:

dev-755126.okta.com

API Call

The next step is to register the cookie session to call the AtScale API.

First, we need to register the cookie session with AtScale:

curl -s \
   --insecure \
   --location \
   --cookie-jar ./AtScaleCookieJar \
   --cookie ./AtScaleCookieJar \
   --output ./request-01.dat \

-X GET \
   https://okta-saml.atscaledomain.com:10500/org/default/SAML2/ConstructAndPostSAMLRequest 

 

Note: the AtScaleCookieJar contains the modeler session

#HttpOnly_okta-saml.atscaledomain.com FALSE / TRUE 1646361599 MODELER_SESSION ed00cf7208213c791a0294f6b48d56aab67d80ab-%00csrf_token%3AvH38Ghl8Li58x5XrULqGWU6eGtokXRQgRzIXrmAve%2FU%3D%00%00_TS%3A1646361599%00

#HttpOnly_okta-saml.atscaledomain.com FALSE / TRUE 0 MODELER_FLASH

 

The request-01.dat file contains the SAMLRequest

<form method="post" action="https://dev-755126.okta.com/app/atscale/exk6e32b9x2sNVtkC4x7/sso/saml">

  <input type="hidden" name="SAMLRequest" value="PHNhbWxwOkF1dGhuUmVxdWVzdCB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiBJRD0iXzBhOGQ3NDQ0LTU2ODYtNDQzNy1hZDNkLWFhNGExZDRiYmQ4ZCIgVmVyc2lvbj0iMi4wIiBQcm90b2NvbEJpbmRpbmc9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpiaW5kaW5nczpIVFRQLVBPU1QiIEFzc2VydGlvbkNvbnN1bWVyU2VydmljZVVSTD0iaHR0cHM6Ly9va3RhLXNhbWwuYXRzY2FsZWRvbWFpbi5jb206MTA1MDAvb3JnL2RlZmF1bHQvU0FNTDIvQXNzZXJ0aW9uQ29uc3VtZXJTZXJ2aWNlL1BPU1QiIElzc3VlSW5zdGFudD0iMjAyMi0wMy0wNFQwMDozOTo1OVoiIERlc3RpbmF0aW9uPSJodHRwczovL2Rldi03NTUxMjYub2t0YS5jb20vYXBwL2F0c2NhbGUvZXhrNmUzMmI5eDJzTlZ0a0M0eDcvc3NvL3NhbWwiPjxzYW1sOklzc3Vlcj5odHRwczovL29rdGEtc2FtbC5hdHNjYWxlZG9tYWluLmNvbToxMDUwMC9vcmcvZGVmYXVsdDwvc2FtbDpJc3N1ZXI&#43;PHNhbWxwOk5hbWVJRFBvbGljeSBBbGxvd0NyZWF0ZT0idHJ1ZSIgRm9ybWF0PSIiLz48L3NhbWxwOkF1dGhuUmVxdWVzdD4=" />

  <input type="hidden" name="RelayState" value="" />

</form>

<script>

  window.onload = function () { document.forms[0].submit(); }

</script>

 

Next, grab the SAML Request and convert it to base64 format:

SAMLRequest=$(grep '"SAMLRequest" value="' ./request-01.dat | sed -E 's/.*"SAMLRequest" value="([^"]+)".*/\1/'|html2text)

 

Echo $SAMLRequest

PHNhbWxwOkF1dGhuUmVxdWVzdCB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiBJRD0iXzBhOGQ3NDQ0LTU2ODYtNDQzNy1hZDNkLWFhNGExZDRiYmQ4ZCIgVmVyc2lvbj0iMi4wIiBQcm90b2NvbEJpbmRpbmc9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpiaW5kaW5nczpIVFRQLVBPU1QiIEFzc2VydGlvbkNvbnN1bWVyU2VydmljZVVSTD0iaHR0cHM6Ly9va3RhLXNhbWwuYXRzY2FsZWRvbWFpbi5jb206MTA1MDAvb3JnL2RlZmF1bHQvU0FNTDIvQXNzZXJ0aW9uQ29uc3VtZXJTZXJ2aWNlL1BPU1QiIElzc3VlSW5zdGFudD0iMjAyMi0wMy0wNFQwMDozOTo1OVoiIERlc3RpbmF0aW9uPSJodHRwczovL2Rldi03NTUxMjYub2t0YS5jb20vYXBwL2F0c2NhbGUvZXhrNmUzMmI5eDJzTlZ0a0M0eDcvc3NvL3NhbWwiPjxzYW1sOklzc3Vlcj5odHRwczovL29rdGEtc2FtbC5hdHNjYWxlZG9tYWluLmNvbToxMDUwMC9vcmcvZGVmYXVsdDwvc2FtbDpJc3N1ZXI+PHNhbWxwOk5hbWVJRFBvbGljeSBBbGxvd0NyZWF0ZT0idHJ1ZSIgRm9ybWF0PSIiLz48L3NhbWxwOkF1dGhuUmVxdWVzdD4=

 

Next, grab the session token:

curl -s \
   --insecure \

-v -X POST \
   -H "Accept: application/json" \
   -H "Content-Type: application/json"\
   --location \
   --cookie-jar ./AtScaleCookieJar \
   --cookie ./AtScaleCookieJar \
   --output ./request-02.dat \

-d '{
  "username": "rudy.w*******",
  "password": "*******,
  "relayState": "/home/atscale/0oa6e32b9yOhv18t84x7/aln1gtyixki1dVEmx1d8",
  "options": {
    "multiOptionalFactorEnroll": false,
    "warnBeforePasswordExpired": false
  }

}' "https://dev-755126.okta.com/api/v1/authn" \

--data-urlencode "SAMLRequest=${SAMLRequest}"


The string that you have to grab from admin, that would be the relayState valueOutput of the request-02.dat file:

{"expiresAt":"2022-03-04T00:51:43.000Z","status":"SUCCESS","relayState":"/home/atscale/0oa6e32b9yOhv18t84x7/aln1gtyixki1dVEmx1d8","sessionToken":"20111YM5IZA88q89KCb9tepYSj-Yp4soOnnlcv88ArpZoXaD8xgTFG9","_embedded":{"user":{"id":"00u4wu0u7R6dbkTUx4x6","passwordChanged":"2020-03-25T20:26:30.000Z","profile":{"login":"rudy.widjaja@atscale.com","firstName":"Rudy","lastName":"Widjaja","locale":"en_US","timeZone":"America/Los_Angeles"}}},"_links":{"cancel":{"href":"https://dev-755126.okta.com/api/v1/authn/cancel","hints":{"allow":["POST"]}}}}%
 

Next, grab the session token:

sessionToken=`jq '.sessionToken' -r request-02.dat`

 

The last step is to get the SAMLResponse for your cookies session:

curl -s --insecure \
   --location \
   --cookie-jar ./AtScaleCookieJar \
   --cookie ./AtScaleCookieJar \
    --output ./request-03.dat \

-H "Content-type:application/x-www-form-urlencoded" \

-X GET "https://dev-755126.okta.com/login/sessionCookieRedirect?token=${sessionToken}&redirectUrl=/home/atscale/0oa6e32b9yOhv18t84x7/aln1gtyixki1dVEmx1d8" 

 

Then grab the SAMLResponse from the request-03.dat file:

SAMLResponse=$(grep '"SAMLResponse" type="hidden" value="' ./request-03.dat | sed -E 's/.*"SAMLResponse" type="hidden" value="([^"]+)".*/\1/'|html2text)

 

Echo $SAMLResponse

PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c2FtbDJwOlJlc3BvbnNlIERlc3RpbmF0aW9uPSJodHRwczovL29rdGEtc2FtbC5hdHNjYWxlZG9tYWluLmNvbToxMDUwMC9vcmcvZGVmYXVsdC9TQU1MMi9Bc3NlcnRpb25Db25zdW1lclNlcnZpY2UvUE9TVCIgSUQ9ImlkMTcwMzg3MDc5NjkxMzM0OTgxNzgwOTYzNDg2IiBJc3N1ZUluc3RhbnQ9IjIwMjItMDMtMDRUMDA6NDg6MTMuOTY5WiIgVmVyc2lvbj0iMi4wIiB4bWxuczpzYW1sMnA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCIgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIj48c2FtbDI6SXNzdWVyIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6ZW50aXR5IiB4bWxuczpzYW1sMj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+aHR0cDovL3d3dy5va3RhLmNvbS9leGs2ZTMyYjl4MnNOVnRrQzR4Nzwvc2FtbDI6SXNzdWVyPjxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPjxkczpTaWduZWRJbmZvPjxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZHNpZy1tb3JlI3JzYS1zaGEyNTYiLz48ZHM6UmVmZXJlbmNlIFVSST0iI2lkMTcwMzg3 

 

Take a look at the AtScaleCookieJar.  It should have most of the items needed to open an AtScale session.

dev-755126.okta.com FALSE / TRUE 1677890894 proximity_92728fcee2ea827f2741aa29b1415426 eyJ6aXAiOiJERUYiLCJwMnMiOiItQW94NGlVbmZoVFVkWTFFQVNlc1J3IiwicDJjIjoxMDAwLCJ2ZXIiOiIxIiwiZW5jIjoiQTI1NkdDTSIsImFsZyI6IlBCRVMyLUhTNTEyK0EyNTZLVyJ9.URe2tWT91f_-mRXGYvbP6tpFxohJRIpymvQiH1oeLqQOah2E1cPzYg.IXAIxbohnyNDeaCy.6UYez-tUoYPOWe0fyq0z1uLBwY6g-UUk5Vdxlz1FaV2gXr1l8XP2iA33qS-ioSUrem-4vbwp6Wq3kFK9uktmyyklHB7_MIb7A77pJgje6DeuXWIyLPNgQ1FtNQOmWucgRovXA8JHJkXasZmrLcvnjYrY_2PEnnFwOB0pZcom7iOGoQ.RS7qCUwIanWJQJJyl5rrsg

dev-755126.okta.com FALSE / TRUE 0 sid 102cJIwTGpIQc2LFIUe6masLw

dev-755126.okta.com FALSE / TRUE 1709426893 DT DI0QrMAqXB3QG6audWwE0Bq6w

dev-755126.okta.com FALSE / FALSE 0 t default

#HttpOnly_okta-saml.atscaledomain.com FALSE / TRUE 1646361599 MODELER_SESSION ed00cf7208213c791a0294f6b48d56aab67d80ab-%00csrf_token%3AvH38Ghl8Li58x5XrULqGWU6eGtokXRQgRzIXrmAve%2FU%3D%00%00_TS%3A1646361599%00

#HttpOnly_okta-saml.atscaledomain.com FALSE / TRUE 0 MODELER_FLASH

#HttpOnly_dev-755126.okta.com FALSE / TRUE 0 JSESSIONID A63C0FC15DC38E772BF0D1A6F3BF785E

 

The next step is to register the cookie session to AtScale:

curl -s -vvv \
   --insecure \
   --location \
   --cookie-jar ./AtScaleCookieJar \
   --cookie ./AtScaleCookieJar \
   --output ./request-04.dat \

    -X POST \

    https://okta-saml.atscaledomain.com:10500/org/default/SAML2/AssertionConsumerService/POST \

--data-urlencode "SAMLResponse=${SAMLResponse}"

 

Verification step: in the auth log, you now have a cookie session established with your SAML

time="2022-03-04T00:52:18Z" level=info msg="Plaintext Authentication Response: <?xml version=\"1.0\" encoding=\"UTF-8\"?><saml2p:Response Destination=\"https://okta-saml.atscaledomain.com:10500/org/default/SAML2/AssertionConsumerService/POST\" ID=\"id170387079691334981780963486\" IssueInstant=\"2022-03-04T00:48:13.969Z\" Version=\"2.0\" xmlns:saml2p=\"urn:oasis:names:tc:SAML:2.0:protocol\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"><saml2:Issuer Format=\"urn:oasis:names:tc:SAML:2.0:nameid-format:entity\" xmlns:saml2=\"urn:oasis:names:tc:SAML:2.0:assertion\">http://www.okta.com/exk6e32b9x2sNVtkC4x7</saml2:Issuer><ds:Signature xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"/><ds:SignatureMethod Algorithm=\"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256\"/><ds:Reference URI=\"#

****

time="2022-03-04T00:52:19Z" level=info msg="Copying user record on login"

time="2022-03-04T00:52:19Z" level=info msg="The NameId given in the assertion rudy.widjaja@atscale.com"

time="2022-03-04T00:52:19Z" level=info msg="The user has a saml principal id of rudy.widjaja@atscale.com that will be persisted in the session."

time="2022-03-04T00:52:19Z" level=info msg="WE ARE INSIDE 'putSessionKey'. samlPrincipalId: rudy.widjaja@atscale.com \n\n"

time="2022-03-04T00:52:19Z" level=info msg="Error decoding the request body: EOF"

time="2022-03-04T00:52:19Z" level=info msg="bout to create session in db. samlPrincipalId: rudy.widjaja@atscale.com \n\n"

 

Next step: submit your API

curl -s -vvv \

    --insecure \

    --location \

    --cookie-jar ./AtScaleCookieJar \

    --cookie ./AtScaleCookieJar \

    https://okta-saml.atscaledomain.com:10500/api/1.0/org/default/engine|jq

 

{
 "status": {
   "i18n_message": "response.ok",
   "message": "OK"
 },

  "response": [
   {
     "engine_id": "2591c41d-14f9-474b-6243-1a1470f80307",
     "org_id": "default",
     "name": "default",
     "protocol": "https",
     "host": "okta-saml.atscaledomain.com",
     "port": 10502,
     "properties": "{}",
     "default_engine": true
   }
 ]
}

Your session will continue until the session timeout from AtScale.

Was this article helpful?

0 out of 0 found this helpful