0

I'm trying to perform SAML authentication against the CyberArk Password Vault application. I was given this PowerShell code by CyberArk for performing this SAML authentication, and it works great and I get the SAML Response token for performing subsequent calls. The issue is that I need to perform this SAML authentication in Python instead of PowerShell, and so far I've been unable to replicate the successful PowerShell code into Python.

My initial attempt was to use Selenium with the Edge webdriver, but that fails, and the PowerShell code doesn't seem to use any particular browser? Any ideas how to replicate this PowerShell code into Python?

Successful PowerShell code for SAML authentication, that gives me the SAML Response token from the IDP

<# ###########################################################################
NAME: CyberArk SAML Authentication via REST API
AUTHOR: Shay Tevet
########################################################################### #>

Add-Type -AssemblyName System.Windows.Forms 
Add-Type -AssemblyName System.Web

$PVWAAddress = "https://passwordvault.acme.net"

function CA_API_SAMLAuth($PVWAAddress)
{    
    $global:tkn = ""
    try{
        $Logon_Body = @{}|ConvertTo-Json
        
        $Logon_URI = "$PVWAAddress/PasswordVault/api/auth/saml/Logon" 
        
        $IdpUrl = Invoke-RestMethod -Uri $Logon_URI -Body $Logon_Body -Method POST -ContentType "application/json" -SessionVariable websession

        $cookies = $websession.Cookies.GetCookies("$PVWAAddress/PasswordVault/api/auth/saml/Logon")
        
        foreach ($cookie in $cookies) { 
            if ($cookie.name -eq "CA88888"){$CA8 = $cookie.value}
        }
    }
    catch{
       Write-Host "StatusMessage:" $_
       return
    }

    try{
        $SAML_Form = New-Object Windows.Forms.Form
        $SAML_Form.StartPosition = 'CenterScreen'
        $SAML_Form.Size = New-Object System.Drawing.Size(650,750) 
       
        $SAML_WB = New-Object Windows.Forms.WebBrowser
        $SAML_WB.Dock = 'Fill'
        $SAML_WB.ScriptErrorsSuppressed = $true

        $SAML_Form.Controls.Add($SAML_WB)

        # Navigate to the IDP URL
        $SAML_WB.Navigate($IdpUrl)

        # Do something before we go anywhere else
        $SAML_WB.add_Navigating({          

            if ($SAML_WB.DocumentText.Contains("SAMLResponse")){

                $_.cancel = $true

                $SAMLElement = $SAML_WB.Document.GetElementsByTagName("input").GetElementsByName("SAMLResponse")[0].GetAttribute("value");

                $SAMLRes = $($SAMLElement -replace ' ', '')

                try{
                    $sessioncc = [Microsoft.PowerShell.Commands.WebRequestSession]::new()

                    $cookie8 = [System.Net.Cookie]::new('CA88888', $CA8)
                    $cookie8.HttpOnly=$true
                    $cookie8.Secure=$true
                    $cookie8.Domain = $PVWAAddress.Split("/")[2]
                    $cookie8.Path = "/"

                    $sessioncc.Cookies.Add($PVWAAddress, $cookie8)
                    
                    $body = @{concurrentSession='true';apiUse='true';SAMLResponse="$($SAMLRes.Trim())"}

                    $contentType = 'application/x-www-form-urlencoded'

                    $SessionToken = Invoke-WebRequest -Method POST -Uri $Logon_URI -body $body -ContentType $contentType  -WebSession $sessioncc

                    $global:tkn = $SessionToken.Content -replace '"', ''
                }
                catch{
                   Write-Host "StatusMessage:" $_
                   return
                }
                $SAML_Form.Close()                
            }
        })

        $SAML_Form.ShowDialog()

        $SAML_Form.Dispose()

        if($global:tkn){
            Write-Host SessionToken: $global:tkn
            return $global:tkn
        }else{
            Write-Host "Something went wrong during the authentication process.\nPlease try signing in again."
            return
        }
    }
    catch{
       Write-Host "StatusMessage:" $_
       return
    }
}


$Token = CA_API_SAMLAuth($PVWAAddress)

The Python code I've tried, using Selenium. This Python code gives me the MFA prompt in the automated Edge browser, but I never get the SAML Response here in Python like I do in the above PowerShell code. I'm wondering if I need to open the IDP URL not in an Edge browser, but just in a generic frame, and somehow handle the SAML redirects?


import time
import os
import re
import urllib.request
import requests

from selenium import webdriver
from selenium.webdriver.edge.service import Service as EdgeService
from selenium.webdriver.edge.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import (
    ElementClickInterceptedException,
    NoSuchElementException,
    ElementNotInteractableException,
    SessionNotCreatedException
)

# Webdriver details
ms_edge_webdriver_path = f"C:\\Users\\bugsbunny\\Downloads\\edgedriver_win64\\msedgedriver.exe"

ms_edge_binary_path = "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe"

pwv_saml_url = f"https://passwordvault.acme.net/PasswordVault/api/auth/saml/Logon"

headers = {
    'Content-Type': 'application/json'
}

initial_pwv_cookie = ""
initial_idp_url = ""

body = {}

with requests.post(pwv_saml_url, headers=headers, verify=False) as initial_idp_response:
    
    initial_idp_url = json.loads(initial_idp_response.content)

    for cookie in initial_idp_response.cookies:
        if cookie.name == "CA88888":
            initial_pwv_cookie = cookie.value

    # --- Setup Selenium Edge driver --- #
    options = Options()

    # https://stackoverflow.com/questions/51865300/python-selenium-keep-browser-open
    options.add_experimental_option("detach", True)
    
    # Suppress the stupid "Personalize your web experience" prompt
    # that can appear randomly and throw things off. You can launch the browser
    # in "guest" mode but if we do SSO I don't want that, so instead we'll
    # just turn off the Edge toggle that initiates that prompt.
    # https://stackoverflow.com/questions/76377363/how-can-i-disable-personalize-your-web-experience-ms-edge-prompt-for-selenium
    # https://stackoverflow.com/questions/77609588/selenium-edge-webdriver-notification-disable
    options.add_experimental_option("prefs",
                                    {"user_experience_metrics": {"personalization_data_consent_enabled": True}})

    # suppressing any console output (FYI, currently this does not totally work when used with
    # the --headless or --headless=new options, so be aware if you are using this with those options).
    #   https://github.com/SeleniumHQ/selenium/issues/13095
    #   https://stackoverflow.com/questions/69919930/selenium-edge-python-errors-auto-close-edge-browser-after-test-execution
    options.add_experimental_option('excludeSwitches', ['enable-logging'])

    service = EdgeService(executable_path=ms_edge_webdriver_path)

    driver = webdriver.Edge(service=service, options=options)

    # Maximize the window
    driver.maximize_window()

    # driver = webdriver.Edge(service=service)
    driver.get(initial_idp_url)
2
  • I would think you would want to use requests and not Selenium and a browser. Commented Apr 23 at 1:24
  • 1
    A couple of things for you to consider; 1) You can always comment on your question and the answers below it (it has nothing to do with rep). For other posts though, you need 50 reps to be able to leave a comment. 2) Your answer was deleted by regular curators (because it should've been an edit or a comment maybe). The other answer was deleted by a moderator because it was AI generated. 3) Guideline on "SO for Teams" does not apply to here. Although we have similar guidelines. 4) Curators are generally aware of the guidelines. Cheers. p.s. Please flag this as "No Longer Needed" after reading it Commented Apr 24 at 21:28

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.