Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

ShibCurl

DZone's Guide to

ShibCurl

·
Free Resource
// description of your code here



[shib.php]

  .
*/

/*
Example:

$shib_curl = new ShibCurl('headless_account','mypassword');
//$shib_curl->setDebug(true);
// curl a site by submitting a forms using $forms
$shib_curl->curl("https://yoursite.com/", $forms);

*/
class ShibCurl {

  private static $ch, $username, $password;

  private static $shib_cookie = "shib-cookie";

  private static $debug = false;

  // Initialize curl handler with SSO username and pass
  function __construct($username,$password) {
    self::$ch = curl_init();
    // Sets up options for the curl handler
    curl_setopt(self::$ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt(self::$ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt(self::$ch, CURLOPT_COOKIEFILE, self::$shib_cookie);
    curl_setopt(self::$ch, CURLOPT_COOKIEJAR, self::$shib_cookie);
    curl_setopt(self::$ch, CURLOPT_COOKIESESSION, 1);
    curl_setopt(self::$ch, CURLOPT_COOKIE, session_name() . '=' . session_id());
    curl_setopt(self::$ch, CURLOPT_FOLLOWLOCATION, 1);
    if ( empty($username) || empty($password)  ) {
      throw new Exception("Empty username or password");
    }
    else {
      self::$username = $username;
      self::$password = $password;
    }

  }

  // At destruct time, close the curl handler and remove cookie
  function __destruct() {
    curl_close(self::$ch);
    if ( file_exists("./".self::$shib_cookie) ) {
      unlink("./".self::$shib_cookie);
    }
  }

  function setDebug($v) {
    self::$debug = $v;
  }

  // To curl a given url
  public function curl($url, $formvars = array()) {

    curl_setopt(self::$ch, CURLOPT_URL, $url);
    // Post the form
    curl_setopt(self::$ch, CURLOPT_POSTFIELDS, $formvars);

    $out = curl_exec(self::$ch);
   
    $info = curl_getinfo(self::$ch);
 
    // Check if we're forward to idp, if not we just need to submit the form to continue
    if ( preg_match('@/idp/Authn@',$info['url']) ) {
      if ( self::$debug ) {
        echo "we're in IDP\n";
      }
      $url_auth = $info['url'];
     
      // Set curl to hit idp next
      curl_setopt(self::$ch, CURLOPT_URL, $url_auth);
     
      // Set this request to be post
      curl_setopt(self::$ch, CURLOPT_POST, 1);
     
      // Our lovely headless account
      $forms = "j_username=".urlencode(self::$username)."&j_password=".urlencode(self::$password);
     
      // Add it to request
      curl_setopt(self::$ch, CURLOPT_POSTFIELDS, $forms);
     
      // Get the output
      $out = curl_exec(self::$ch);

      if ( self::$debug ) {
    //    print $out;
      }

      // If we returned to auth form, that means unable to authenticate
      if ( preg_match('@Authentication Failed@', $out) ) {
        throw new Exception('Unable to authenticate');
      }
    }
   
    // Now we should be properly authenticated.  IDP send us back to SP's shib site.  
    // Normally, javascript will kick in and submit the page automatically, but this is curl
    // so we have to do the submit ourself.
    // Get the SP's SAML url from the output
    if ( preg_match('@form action="([^"]+)"@', $out, $matches) ) {

      if ( self::$debug ) {
        echo "we're in sp SAML\n";
      }

      $url_sp = $matches[1];
     
      // Get the fields, match all input type=hidden
      preg_match_all('@input type="hidden" name="([^"]+)" value="([^"]+)"@i', $out, $matches);
      // Get rid of first element which just contains the whole matched string.
      unset($matches[0]);
     
      // $matches now contains fields needed SP to validate session, we'll build a POST form around it.
      $forms = array();
      for ( $i = 0; $i < count($matches[1]); $i++ ) {
        $forms[] = $matches[1][$i] .'='. urlencode($matches[2][$i]);
      }
     
      // Again, setup the path and get the form in
      curl_setopt(self::$ch, CURLOPT_URL, $url_sp);
      curl_setopt(self::$ch, CURLOPT_POSTFIELDS, join('&',$forms));
     
      // wheeee, finally we get the page.
 
      $out = curl_exec(self::$ch);
      if ( self::$debug ) {
     //   print $out;
      }
 
      // Now we are properly authenticated and got a session with this SP, do last curl to send the form
 
      curl_setopt(self::$ch, CURLOPT_POSTFIELDS, $formvars);
 
      $out = curl_exec(self::$ch);
    }

    // return the output
    return $out;
  }

}



?> 
Topics:

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}