Preview:
/**
 * Method to authenticate an external credential using the external credential using the 
 * Auth URL.
 */

String externalCredential = 'TDX_DC_ORG';
String principalName = 'NAMED_PRINCIPAL';


System.debug(getAuthUrlFromConnectApi(externalCredential, principalName));


String getAuthUrlFromConnectApi(String externalCredential, String principalName){
    
    String body = JSON.serialize(
        new Map<String,String>{
            'externalCredential'=> externalCredential,
            'principalName'     => principalName,
            'principalType'     => 'NamedPrincipal'
        }
    );
    
    // Create a new request
    HttpRequest req = new HttpRequest();
    req.setMethod('POST');
    req.setEndpoint(Url.getOrgDomainUrl().toExternalForm() + '/services/data/v60.0/named-credentials/credential/auth-url/o-auth');
    req.setHeader('Authorization','Bearer ' + UserInfo.getSessionId());
    req.setHeader('Content-Length', String.ValueOf(body.length()));
    req.setBody(body);
    
    System.debug(body);

    // Execute request and fetch response
    HttpResponse res = new Http().send(req);

    // Throw an error if the status code for the final call is not equal to 200
    if(res.getStatusCode() != 200){
        throw new StringException('Unexpected status code in connect api callout. Response: ' + res.getBody());
    }

    // Parse the response into a Connect API class
    ConnectApi.OAuthCredentialAuthUrl ocau = (ConnectApi.OAuthCredentialAuthUrl) JSON.deserializeStrict(
        res.getBody(),
        ConnectApi.OAuthCredentialAuthUrl.class
    );

    // Return the authentication from the Connect API response
    return ocau.authenticationUrl;
}



// This comes from your Apex API Call
Integer statusCode        = 400;
Boolean statusIsAuthError = true;

// Configuration for
String  authUrl           = 'https://dc-mgmt-dev-ed.develop.my.salesforce.com/services/auth/xds/TDX_DC_ORG?startURL=/0puQy0000000AQn';

// Run this logic when
if(statusCode == 400 && statusIsAuthError){

    // Start the flow by calling the external credential auth URL and validate that the response is as we expect
    RedirectResponse initialResponse = validateRedirectResponse(
        callout(
            authUrl,
            null
        )
    );

    // Handle the first redirect and validate that the response is as we expect
    RedirectResponse firstRedirectResponse = validateRedirectResponse(
        callout(
            initialResponse.location,
            initialResponse.cookie
        )
    );

    // Handle the second redirect and validate that the response is as we expect
    // !! Use the cookie from the initial request !!
    HttpResponse finalResponse = callout(
            firstRedirectResponse.location,
            initialResponse.cookie
    );

    // Throw an error if the status code for the final call is not equal to 200
    if(finalResponse.getStatusCode() != 200){
        throw new StringException('Unexpected status code in final callout. Response: ' + finalResponse.getBody());
    }
}


/**
 * Method to do a get callout with a cookie header setter
 */
HttpResponse callout(String endpoint, String cookie){
    HttpRequest req = new HttpRequest();
    req.setEndpoint(endpoint);
    req.setMethod('GET');

    // Set the cookie if not blank
    if(!String.isBlank(cookie)){
        secondRedirectRequest.setHeader('Cookie',cookie);
    }
    HttpResponse res = new Http().send(req);
}


/**
 * Basic validation that the response is as we expect
 */
RedirectResponse validateRedirectResponse(HttpResponse res){
    // Check it is a status 302
    if(res.getStatusCode() != 302){
        throw new StringException('Unexpected response code, expected the response status code to be 302');
    }

    // Return a redirect response object
    return new RedirectResponse(
        res.getHeader('Location')
        res.getHeader('Set-Cookie');
    );
}


/**
 * Simple redirect response object to make the code more readable
 */
class RedirectResponse{

    public String location;
    public String cookie;

    RedirectResponse(String location, String cookie){
        this.location = location;
        this.cookie   = cookie;
    }
}
downloadDownload PNG downloadDownload JPEG downloadDownload SVG

Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!

Click to optimize width for Twitter