When using Shibboleth, the IdP returns a SAML assertion to the SP. The following examples simply display the results of the SAML assertion. This gives a very brief introduction which shows how your application might consume the information and use it.

Perl ( 2.x version)

#!/usr/bin/perl

print "Content-type: text/html\n\n";
print "<html>\n";
print "<head>";
print "  <title>Shibboleth Attributes - ".$ENV{SERVER_NAME}."</title>\n";
print "  <META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">\n";
print "  <META HTTP-EQUIV=\"Expires\" CONTENT=\"-1\">\n";
print <<__ENDJSCRIPT__;
<script language"JavaScript" type="text/JavaScript">
<!--
  function decodeAttributeResponse() {
 	var textarea = document.getElementById("attributeResponseArea");
  	var base64str = textarea.value;
	var decodedMessage = decode64(base64str);
	textarea.value = tidyXml(decodedMessage);
	textarea.rows = 15;
	document.getElementById("decodeButtonBlock").style.display='none';
  }

  function tidyXml(xmlMessage) {
	//put newline before closing tags of values inside xml blocks
	xmlMessage = xmlMessage.replace(/([^>])</g,"\$1\\n<");
	//put newline after every tag
	xmlMessage = xmlMessage.replace(/>/g,">\\n");
	var xmlMessageArray = xmlMessage.split("\\n");
	xmlMessage="";
	var nestedLevel=0;
	for (var n=0; n < xmlMessageArray.length; n++) {
		if ( xmlMessageArray[n].search(/<\\//) > -1 ) {
			nestedLevel--;
		}
		for (i=0; i<nestedLevel; i++) {
			xmlMessage+="  ";
		}
		xmlMessage+=xmlMessageArray[n]+"\\n";
		if ( xmlMessageArray[n].search(/\\/>/) > -1 ) {
			//level status the same
		}
		else if ( ( xmlMessageArray[n].search(/<\\//) < 0 ) && (xmlMessageArray[n].search(/</) > -1) ) {
			//only increment if this was a tag, not if it is a value
			nestedLevel++;
		}
	}
  	return xmlMessage;
  }

  var base64Key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  function decode64(encodedString) {
    var decodedMessage = "";
    var char1, char2, char3;
    var enc1, enc2, enc3, enc4;
    var i = 0;
  
    //remove all characters that are not A-Z, a-z, 0-9, +, /, or =
    encodedString = encodedString.replace(/[^A-Za-z0-9\\+\\/\\=]/g, "");
    do {
	enc1 = base64Key.indexOf(encodedString.charAt(i++));
	enc2 = base64Key.indexOf(encodedString.charAt(i++));
	enc3 = base64Key.indexOf(encodedString.charAt(i++));
	enc4 = base64Key.indexOf(encodedString.charAt(i++));

	char1 = (enc1 << 2) | (enc2 >> 4);
	char2 = ((enc2 & 15) << 4) | (enc3 >> 2);
	char3 = ((enc3 & 3) << 6) | enc4;

	decodedMessage = decodedMessage + String.fromCharCode(char1);
	if (enc3 != 64) {
		decodedMessage = decodedMessage + String.fromCharCode(char2);
	}
	if (enc4 != 64) {
		decodedMessage = decodedMessage + String.fromCharCode(char3);
	}
    } while (i < encodedString.length);
    return decodedMessage;
  }
// -->
</script>
__ENDJSCRIPT__

print "</head>\n";
print "\n\n<body>\n";

print "<b>-shib-</b><br/>";
print "<table>";
foreach $var (sort(keys(%ENV))) {
    if ($var =~ m/SHIB/i || $var =~ m/REMOTE_USER/ || $var =~ m/HTTP_REMOTE_USER/) {
    	$val = $ENV{$var};
    	$val =~ s|\n|\\n|g;
    	$val =~ s|"|\\"|g;
    	print "<tr>";
    	print "<td>${var}</td><td>${val}</td>";
    	print "</tr>\n";
    }
}
print "</table>\n";

print "<br/>\n";

print "attribute response from the IdP (<code>HTTP_SHIB_ATTRIBUTES</code>):<br/>\n";
print "<textarea id=\"attributeResponseArea\" onclick=\"select()\" rows=\"1\" cols=\"130\">";
print $ENV{"HTTP_SHIB_ATTRIBUTES"};
print <<__ENDBLOCK__;
</textarea><br/>
<span id="decodeButtonBlock"><input type="button" id="decodeButton" value="decode base64 encoded attribute response using JavaScript" onClick="decodeAttributeResponse();"><br/></span>

<br/>

<small>
notes:<br/>
The AAP throws away invalid values (eg an unscopedAffiliation of value "myBoss@&lt;yourdomain&gt;" or a value with an invalid scope which scope is checked)<br/>
The raw attribute response (<code>HTTP_SHIB_ATTRIBUTES</code>) is NOT filtered by the AAP and should therefore be disabled for most applications (<code>exportAssertion=false</code>).<br/>
</small>

<br/>
<hr/>
<br/>
__ENDBLOCK__

print "<b>-env-</b><br/>";
print "<pre>";
foreach $var (sort(keys(%ENV))) {
    $val = $ENV{$var};
    $val =~ s|\n|\\n|g;
    $val =~ s|"|\\"|g;
    print "${var}=\"${val}\"\n";
}
print "</pre>\n";

print "<hr/><b>-end-</b><br/>\n";

print "</body>\n\n";
print "</html>\n";



PHP (2.x version)

<script language"JavaScript" type="text/JavaScript">
<!--
  function decodeAttributeResponse() {
 	var textarea = document.getElementById("attributeResponseArea");
  	var base64str = textarea.value;
	var decodedMessage = decode64(base64str);
	textarea.value = tidyXml(decodedMessage);
	textarea.rows = 15;
	document.getElementById("decodeButtonBlock").style.display='none';
  }

  function tidyXml(xmlMessage) {
	//put newline before closing tags of values inside xml blocks
	xmlMessage = xmlMessage.replace(/([^>])</g,"$1\n<");
	//put newline after every tag
	xmlMessage = xmlMessage.replace(/>/g,">\n");
	var xmlMessageArray = xmlMessage.split("\n");
	xmlMessage="";
	var nestedLevel=0;
	for (var n=0; n < xmlMessageArray.length; n++) {
		if ( xmlMessageArray[n].search(/<\//) > -1 ) {
			nestedLevel--;
		}
		for (i=0; i<nestedLevel; i++) {
			xmlMessage+="  ";
		}
		xmlMessage+=xmlMessageArray[n]+"\n";
		if ( xmlMessageArray[n].search(/\/>/) > -1 ) {
			//level status the same
		}
		else if ( ( xmlMessageArray[n].search(/<\//) < 0 ) && (xmlMessageArray[n].search(/</) > -1) ) {
			//only increment if this was a tag, not if it is a value
			nestedLevel++;
		}
	}
  	return xmlMessage;
  }

  var base64Key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  function decode64(encodedString) {
    var decodedMessage = "";
    var char1, char2, char3;
    var enc1, enc2, enc3, enc4;
    var i = 0;
  
    //remove all characters that are not A-Z, a-z, 0-9, +, /, or =
    encodedString = encodedString.replace(/[^A-Za-z0-9\+\/\=]/g, "");
    do {
	enc1 = base64Key.indexOf(encodedString.charAt(i++));
	enc2 = base64Key.indexOf(encodedString.charAt(i++));
	enc3 = base64Key.indexOf(encodedString.charAt(i++));
	enc4 = base64Key.indexOf(encodedString.charAt(i++));

	char1 = (enc1 << 2) | (enc2 >> 4);
	char2 = ((enc2 & 15) << 4) | (enc3 >> 2);
	char3 = ((enc3 & 3) << 6) | enc4;

	decodedMessage = decodedMessage + String.fromCharCode(char1);
	if (enc3 != 64) {
		decodedMessage = decodedMessage + String.fromCharCode(char2);
	}
	if (enc4 != 64) {
		decodedMessage = decodedMessage + String.fromCharCode(char3);
	}
    } while (i < encodedString.length);
    return decodedMessage;
  }
// -->
</script>



<b>-all SHIB headers-</b> (<code>HTTP_SHIB_ATTRIBUTES</code> is not shown in this list)
<?php
echo '<table>';
foreach ($_SERVER as $key => $value)
{
	$fkey='_'.$key;
	if ( strpos($fkey,'SHIB')>1 && $key!="HTTP_SHIB_ATTRIBUTES")
#	if ( strpos($fkey,'SHIB')>1 )
	{
		echo '<tr>';
		echo '<td>'.$key.'</td><td>'.$value.'</td>';
		echo '</tr>';
	}
}
echo '<tr><td>(REMOTE_USER)</td><td>'.$_SERVER['REMOTE_USER'].'</td></tr>';
echo '<tr><td>(HTTP_REMOTE_USER)</td><td>'.$_SERVER['HTTP_REMOTE_USER'].'</td></tr>';
echo '</table>';
?>
<br/>

attribute response from the IdP (<code>HTTP_SHIB_ATTRIBUTES</code>):<br/>
<textarea id="attributeResponseArea" onclick="select()" rows="1" cols="130"><?php echo $_SERVER["HTTP_SHIB_ATTRIBUTES"]; ?></textarea><br/>
<span id="decodeButtonBlock"><input type="button" id="decodeButton" value="decode base64 encoded attribute response using JavaScript" onClick="decodeAttributeResponse();"><br/></span>

<br/>

<small>
notes:<br/>
The AAP throws away invalid values (eg an unscopedAffiliation of value "myBoss@&lt;yourdomain&gt;" or a value with an invalid scope which scope is checked)<br/>
The raw attribute response (<code>HTTP_SHIB_ATTRIBUTES</code>) is NOT filtered by the AAP and should therefore be disabled for most applications (<code>exportAssertion=false</code>).<br/>
</small>

<br/>
<hr/>
<br/>


<b>$_REQUEST</b>
<?php
echo '<table>';
foreach ($_REQUEST as $key => $value)
{
	echo '<tr>';
	echo '<td>'.$key.'</td><td>'.$value.'</td>';
	echo '</tr>';

}
echo '</table>'
?>



<br/>
<hr/>
<br/>

<b>$_SERVER</b>
<?php
echo '<table>';
foreach ($_SERVER as $key => $value)
{
	echo '<tr>';
	echo '<td>'.$key.'</td><td>'.$value.'</td>';
	echo '</tr>';

}
echo '</table>'
?>

<br/>
<hr/>
<br/>

<b>$_SESSION</b>
<?php
echo '<table>';
foreach ($_SESSION as $key => $value)
{
	echo '<tr>';
	echo '<td>'.$key.'</td><td>'.$value.'</td>';
	echo '</tr>';

}
echo '</table>'
?>

<br/>
<hr/>
<br/>


PHP (1.3 version)

<?php

<table>

foreach($_SERVER as $key => $value) {
    $fkey = '_' . $key;
    if (strpos($fkey, 'SHIB') > 0) {
        echo '<tr>';
        echo "<td>$key</td><td>$value</td>";
        echo '</tr>';
    }
}

</table>

?>

Perl (1.3 version)

foreach $var (sort(keys(%ENV))) {
    if ($var =~ m/SHIB/ || $var =~ m/REMOTE_USER/) {
        $val = $ENV{$var};
        $val =~ s|\n|\\n|g; $val =~ s|"|\\"|g;
        print "<tr>";
        print "<td>${var}</td><td>${val}</td>";
        print "</tr>";
    }
}

SSI - Server Side Includes (1.3 version)

<\!\--\#printenv-\->

or

<\!--#echo var="HTTP_SHIB_EP_PERSONPRINCIPALNAME" \-->

ASP (1.3 version)

<table>

<% For Each strKey In Request.ServerVariables %>
<tr>
<td><%= strKey %></td>
<td><%= Request.ServerVariables(strKey) %></td>
</tr>
<% Next %>

</table>

</table>

JSP (1.3 version)

<u>HEADERS</u><br />

<table>
<%
java.util.Enumeration eHeaders = request.getHeaderNames();
while(eHeaders.hasMoreElements())
{ String name = (String) eHeaders.nextElement(); Object object = request.getHeader(name); String value = object.toString(); out.println("" + name + "" + value + ""); }
%>
</table>

Similar samples can be found at Katholieke Universiteit Leuven

  • No labels