work on the endpoints class, add a generic dispatching class using QUERY_INFO, and a specific saml2 endpoints class

This commit is contained in:
<bdauvergne@entrouvert.com> 1208797731 +0200 0001-01-01 00:00:00 +00:00
parent 2183d6b9af
commit c675aa2ee7
4 changed files with 187 additions and 41 deletions

View File

@ -1,49 +1,34 @@
<?php
require_once('lassospkit_helper.inc.php');
require_once('lassospkit_debug.inc.php');
require_once('lassospkit_utils.inc.php');
require_once('lassospkit_metadata.inc.php');
class LassoSPKitEndpoint {
var $dispatch_table = array();
var $protocol = null;
require_once('lassospkit_url_dispatch.inc.php');
class LassoSPKitEndpoint extends LassoSPKitUrlDispatch {
function LassoSPKitEndpoint($protocol) {
$this->__construct($protocol);
}
function __construct($protocol) {
$this->protocol = $protocol;
$this->addDispatch('/metadata', 'metadata');
}
function addDispatch($point, $method) {
$dispatch_table[$point] = $method;
}
function dispatchAndExit() {
if (! isset($_SERVER['PATH_INFO'])) {
throw new Exception('No PATH INFO');
}
$path_info = $_SERVER['PATH_INFO'];
$fname = $this->dispatch_table[$path_info];
if ($fname) {
$fname();
exit(0);
} else {
header("HTTP/1.0 404 Not Found");
exit(0);
}
$this->addDispatch('/assertionConsumer', 'assertionConsumer');
$this->addDispatch('/sloBrws','sloBrws');
$this->addDispatch('/sloSoap','sloSoap');
$this->addDispatch('/sloReturn','sloReturn');
}
// Urls
function metadata() {
$datadir = LassoSPKitHelper::getMetadataDir($this->protocol);
$pkey = $datadir . "/" . PRIVATE_KEY;
LassoSPKitUtils::extractPublicKey($pkey, $publickey, $error);
$content = LassoSPKitMetadataSAML2::generateMetadata(dirname(LassoSPKitUtils::mydir()), LassoSPKitConfig::get('organization'), $publickey);
if ($content) {
header('Content-type: text/xml');
echo $content;
/** Return the session object. */
function getSession() {
static $session;
if ($session == null) {
$session_class = "LassoSPKit" . LassoSPKitConfig::get('session');
$session = new $session_class();
}
return $session;
}
// Verify that the host is the same has HTTP_HOST
function distpatchAndExit() {
if (isset($_SERVER['HTTP_REFERER'])) {
$host = $_SERVER['HTTP_REFERER'];
$this->verifyUrl($host);
}
parent::dispatchAndExit();
}
/** Verify that the host is the same has HTTP_HOST */
function verifyUrl($host) {
$host = strstr('//', $host);
$pos = strpos($host, '/');
@ -56,5 +41,72 @@ class LassoSPKitEndpoint {
exit(1);
}
}
function getProfileObject() {
throw new Exception('Not implemented');
}
function assertionConsumer() {
$profile = $this->getProfileObject();
$http_method = $this->limitMethodBrws($this->identifyHttpMethod());
$query_string = $this->getQueryString($http_method);
$ok = $profile->ssoConsumer($http_method, $query_string);
$return_url = LassoSPKitUtilsSession::getRelayState('sso');
finish($return_url);
}
/** Profiles initiés par l'IdP */
function sloBrws() {
$profile = $this->getProfileObject();
$http_method = $this->limitMethodBrws($this->identifyHttpMethod());
$query_string = $this->getQueryString($http_method);
return $profile->processRequestSLO($http_method, $query_string);
}
function sloSoap() {
$profile = $this->getProfileObject();
return $profile->processSOAPRequestSLO();
}
/** Profiles initiés par le SP */
function sloReturn() {
$profile = $this->getProfileObject();
$http_method = $this->limitMethodBrws($this->identifyHttpMethod());
$query_string = $this->getQueryString($http_method);
return $profile->processResponseSLO($http_method, $query_string);
}
function identifyHttpMethod() {
if (isset($_POST) && ( isset($_POST['SAMLResponse']) || isset($_POST['SAMLRequest']))) {
return LASSO_HTTP_METHOD_POST;
}
if (isset($_GET) && ( isset($_GET['SAMLResponse']) || isset($_GET['SAMLRequest']) ) {
return LASSO_HTTP_METHOD_REDIRECT;
}
if (isset($_GET) && ( isset($_GET['SAMLart']))) {
return LASSO_HTTP_METHOD_ARTIFACT_GET;
}
if (isset($_POST) && ( isset($_POST['SAMLart']))) {
return LASSO_HTTP_METHOD_ARTIFACT_POST;
}
return LASSO_HTTP_METHOD_NONE;
}
function getQueryString($http_method) {
switch ($http_method) {
case LASSO_HTTP_METHOD_POST:
case LASSO_HTTP_METHOD_ARTIFACT_POST:
return @file_get_contents('php://input');
case LASSO_HTTP_METHOD_REDIRECT:
case LASSO_HTTP_METHOD_ARTIFACT_GET:
return $_SERVER['QUERY_STRING'];
}
return null;
}
/** Restrict possible method for HTTP endpoints,
so forbid using SOAP on HTTP endpoints. */
function limitMethodBrws($http_method) {
switch ($http_method) {
case LASSO_HTTP_METHOD_POST:
case LASSO_HTTP_METHOD_ARTIFACT_POST:
case LASSO_HTTP_METHOD_REDIRECT:
case LASSO_HTTP_METHOD_ARTIFACT_GET:
return $http_method;
}
return LASSO_HTTP_METHOD_NONE;
}
}

View File

@ -0,0 +1,39 @@
<?php
require_once('lassospkit_debug.inc.php');
require_once('lassospkit_endpoints.inc.php');
require_once('lassospkit_metadata.inc.php');
class LassoSPKitSaml2Endpoint extends LassoSPKitEndpoint {
function LassoSPKitSaml2Endpoint() {
parent::LassoSPKitEndpoint();
$this->addDispatch('/nameIdManagementBrws','nameIdManagementBrws');
$this->addDispatch('/nameIdManagementSoap','nameIdManagementSoap');
$this->addDispatch('/nameIdManagementReturn','nameIdManagementReturn');
$this->addDispatch('/metadata','metadata');
}
function getProfileObject() {
return new LassoSPKitSAML2($this->getSession());
}
/** Generate metadatas for the SAML2 endpoint */
function metadata() {
$datadir = LassoSPKitHelper::getMetadataDir(LASSO_PROTOCOL_SAML_2_0);
$pkey = $datadir . "/" . PRIVATE_KEY;
LassoSPKitUtils::extractPublicKey($pkey, $publickey, $error);
try {
$content = LassoSPKitMetadataSAML2::generateMetadata(LassoSPKitConfig::get('baseUrl'), LassoSPKitConfig::get('organization'), $publickey);
if ($content) {
header('Content-type: text/xml');
echo $content;
}
} catch (Exception $e) {
echo 'An exception occured';
lassospkit_errlog($e);
}
}
function nameIdManagementBrws() {
}
function nameIdManagementSoap() {
}
function nameIdManagementReturn() {
}
}

View File

@ -16,7 +16,7 @@ class LassoSPKitSAMLCommon {
var $ret = 0;
var $ret_str = "";
var $exception = null;
var $relay_state;
var $relay_state = null;
public function __construct(LassoSPKitGenericSession $session) {
$this->session = $session;
@ -198,6 +198,7 @@ class LassoSPKitSAMLCommon {
$login = new LassoLogin($this->server);
$retPRM = 0;
$retAR = 0;
$retFF = 0;
switch ($method) {
case LASSO_HTTP_METHOD_ARTIFACT_GET:
case LASSO_HTTP_METHOD_ARTIFACT_POST:
@ -235,12 +236,24 @@ class LassoSPKitSAMLCommon {
LassoSPKitHelper::assertionExtractAttributes($login->assertion, $attributes);
$this->session->processAttributes($attributes);
}
if ($retAR) {
return $retAR;
}
if ($retPRM) {
return $retPRM;
}
if ($retFF) {
return $retFF;
}
}
/** Web SLO methods */
/* SP initiated */
public function initiateSLO($method = LASSO_HTTP_METHOD_SOAP, $remoteID = null)
public function initiateSLO($method = LASSO_HTTP_METHOD_SOAP, $remoteID = null, $relayState = )
{
if ($method == null) {
$method = LASSO_HTTP_METHOD_SOAP;
}
$logout = new LassoLogout($this->server);
$this->findFederation($logout);
$retIR = $logout->initRequest($remoteID, $method);
@ -292,11 +305,15 @@ class LassoSPKitSAMLCommon {
return $this->processRequestSLO(LASSO_HTTP_METHOD_REDIRECT,
$_SERVER['QUERY_STRING']);
}
/** Read the SOAP request in the POSTed HTTP message,
and process it as a SLO request. */
public function processSOAPRequestSLO() {
$contents = $this->receiveSoapMessage();
return $this->processRequestSLO(LASSO_HTTP_METHOD_SOAP,
$contents);
}
/** Use $message as a query for the given http_method,
and treat it as a SLO request. */
public function processRequestSLO($method, $message) {
$logout = new LassoLogout($this->server);
$retPRM = $logout->processRequestMsg($message);
@ -304,7 +321,9 @@ class LassoSPKitSAMLCommon {
$retVR = $logout->validateRequest();
$retBR = $this->finishResponse($logout, $logout->http_request_method);
$this->session->logout();
lassospkit_infolog("Logout request handled for nameId: " . $logout->nameID . " retPRM: $retPRM retVR: $retVR retBR: $retBR");
if ($retPRM || $retVR || $retBR) {
lassospkit_infolog("Error during SLO request handling for nameId: " . $logout->nameID . " retPRM: $retPRM retVR: $retVR retBR: $retBR");
}
if ($retPRM) {
return $retPRM;
}
@ -316,13 +335,20 @@ class LassoSPKitSAMLCommon {
}
return 0;
}
/** If result of profile is a modification of identity or session objects,
save them in the federations database. */
public function saveFederation(LassoProfile $profile) {
LassoSPKitHelper::saveFederation($profile, $this->session);
}
/** Find a federation using as many hints as possible (maybe the nameid given in the request,
or the nameid present in the current session) */
public function findFederation(LassoProfile $profile) {
return LassoSPKitHelper::findFederation($profile, $this->session);
}
/** Federation termination **/
/** Federation termination.
Supress the current federation. That is the records associated
to the nameid and userid in the current session.
**/
public function initiateFTNotification($method = LASSO_HTTP_METHOD_SOAP, $remoteID = null) {
$this->session->changeFederation(null, null);
}
@ -356,4 +382,7 @@ class LassoSPKitSAMLCommon {
function setMessage($message) {
LassoSPKitUtilsSession::setLastError($message);
}
function getRelayState() {
return $this->relay_state;
}
}

View File

@ -0,0 +1,26 @@
<?php
require_once('lassospkit_helper.inc.php');
require_once('lassospkit_utils.inc.php');
require_once('lassospkit_metadata.inc.php');
class LassoSPKitUrlDispatch {
var $dispatch_table = array();
function addDispatch($point, $method) {
$this->dispatch_table[$point] = $method;
}
function dispatchAndExit() {
if (! isset($_SERVER['PATH_INFO'])) {
throw new Exception('No PATH INFO');
}
$path_info = $_SERVER['PATH_INFO'];
$fname = $this->dispatch_table[$path_info];
if ($fname) {
$fname();
exit(0);
} else {
header("HTTP/1.0 404 Not Found");
exit(0);
}
}
}