DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world
ShibCurl
// description of your code here
[shib.php]
<?php
// Mark Lin
//
// Curl a shib protected site
/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
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;
}
}
?>




