.netasp.net-coreasp.net-web-apioktaokta-api

How to retrieve Okta SAML token from Okta web API programmatically


I am taking this answer as base for my question because I was nearly there...

I am building a proxy that would convert Okta SAML into our own JWT. Idea is - take SAML token and use it to make our private JWT with claims. The setup is JS UI - .net WEB API - Okta SSO

From .net web API I've successfully connected to Okta and got token using POST payload

{
  "username": "myuser@company.com",
  "password": "mysecret",
  "options": {
    "multiOptionalFactorEnroll": false,
    "warnBeforePasswordExpired": false
  }
}

Then I've retrieved the one-time token (cookie token) from the response using POST on https://SomeCompany.okta.com/api/v1/sessions?additionalFields=cookieToken with payload

{ "sessionToken": "token I retrieved in the step 1" }

And this ^^ gave me the response which contains the cookieToken. And now I used this cookie token to make a GET request to the URL set in my Okta application, which looks like https://SomeCompany.okta.com/app/SomeCompanysso_123/4tg7uknm765on6yhnmk/sso/saml

I added a query parameter so it looks like https://SomeCompany.okta.com/app/SomeCompanysso_123/4tg7uknm765on6yhnmk/sso/saml?onetimetoken=THE_TOKEN_I_GOT_IN_STEP2

And this fetched me the whole SSO HTML page with SAML token in the hidden field SAMLResponse.

Is there a way to get this SAMLResponse cleanly, without need to rip it out of HTML and if not, what is the efficient way to do it?

Thanks


Solution

  • Based on the question, this is the answer to the last part for the obtaining of SAML token cleanly. We retrieve the HTML Document, load it into the c# instance and take the SAML token node for further processing.

    // token comes in the controle with this name
    private const string _samlTokenFormControlName = "SAMLResponse";
    
    // here response content 'string responseContent' is HTML page
    var htmlDoc = new HtmlDocument();
    try
    {
        htmlDoc.LoadHtml(responseContent);
        HtmlNodeCollection nodes =
        htmlDoc.DocumentNode.SelectNodes($"//input[@name='{_samlTokenFormControlName}']");
        if (nodes.Count > 0)
        {
            samlToken = nodes[0].GetAttributeValue("value", null);
            if (samlToken != null)
                retVal = true;
            }
    }
    catch
    {}
    
    return retVal; // gets me clean SAML token
    

    After this I decode this token and retrieve Claims out of it using Microsoft.IdentityModel.Tokens.Saml2.