Is there a good SimpleSAMLphp SLO example?
One of our clients is requesting that we implement Single Logout (SLO) through SAML. Their side of the SAML service is the Identity Provider, while ours is the Service Provider. Single-Signon (SSO) works by validating the user's credentials with the client's IdP, then redirecting the user to a login page on yet another platform, with a token that lets them log straight in. That platform knows absolutely nothing about SAML, and in particular doesn't share the SimpleSAMLphp session state.
Logout needs to happen two ways, though:
If the user hits the logout button on our platform, need to log them out of our site, and hit the IdP's SLO service.
If the user hits the logout button on the client's side, or on another service provider's side, the client IdP will hit our SP's SLO service, which then needs to log them out of our real platform before redirecting the user back to the SP's logout response page.
I'm able to convince our platform to redirect the user to an arbitrary page on logout, so I think the first part can be achieved by a page that uses SimpleSAML_Auth_Simple::getLogoutURL()
.
Such a page might also work when hit from the IdP side, but the SAML specs are complicated enough that I can't be sure until we try it. However, the SP configuration in config/authsources.php
does开发者_高级运维n't accept a SingleLogoutService
parameter; the metadata as produced by /www/module.php/saml/sp/metadata.php/entityid
still lists /www/module.php/saml/sp/saml2-logout.php/entityid
as the SingleLogoutService location. If that page is necessary for clearing the SimpleSAMLphp session, that's fine, but I need to know how to slip in the extra redirects required for logging the user out of our platform.
I've tried searching for examples, but all I get is API references. It would also be nice to know how I can test logout without attempting to set up my own IdP; is there a service like the openidp.feide.no
that handles SLO as well as SSO?
SLO Issue
Imagine this scheme:
Plattform -- SP1 ----- IdP ----- SP2----- App
Plattform and Apps are connected with simpleSAMLphp SP, that also forms a federation with a IdP.
You must find the normal log out function of Platffom, app1 and app2 and rewrite it:
normal_app_logout() {
// code of the normal logout
....
....
// new code
require_once('<path-to-ssp>/simplesamlphp/lib/_autoload.php'); //load the _autoload.php
$auth = new SimpleSAML_Auth_Simple('default-sp'); // or the auth source you using at your SP
$auth->logout(); <--- call to the SLO
}
This will end local session, the SP session connected to this application, the IdP session and the SP sessions of the SPs connected to the IdP but... what happen to the others apps session? They will still be active. You thought about an active call to end it but I think is better if you also override the "is_logged_in()" function that many app implement.
You must override this function and only return true if exists also a valid SP session active using the function
$auth->isAuthenticated()
Recently I implemented this functionality on the Wordpess SAML plugin, check the code
IdP Issue
Use Onelogin free trial , you can register your SP there and use its IdP. Follow this guide to configure your SAML connectors
But I think that you better may try to build a IdP by yourself. There is a nice documentation and the steps are easy. Use "example-userpass" authsource if you dont want to waste time configuring a database/ldap.
Also you can set your actual simplesamlphp instance as SP & IdP but i think that if you are learning simplesamlphp better dont mix.
public function logout()
{
$timeNotOnOrAfter = new \DateTime();
$timeNow = new \DateTime();
$timeNotOnOrAfter->add(new DateInterval('PT' . 2 . 'M'));
$context = new \LightSaml\Model\Context\SerializationContext();
$request = new \LightSaml\Model\Protocol\LogoutRequest();
$request
->setID(\LightSaml\Helper::generateID())
->setIssueInstant($timeNow)
->setDestination($this->_helper->getSloServiceUrl())
->setNotOnOrAfter($timeNotOnOrAfter)
->setIssuer(new \LightSaml\Model\Assertion\Issuer($this->_helper->getSpEntityId()));
$certificate = \LightSaml\Credential\X509Certificate::fromFile($this->_helper->getSpCertFile());
$privateKey = \LightSaml\Credential\KeyHelper::createPrivateKey($this->_helper->getSpPemFile(), '', true);
$request->setSignature(new \LightSaml\Model\XmlDSig\SignatureWriter($certificate, $privateKey));
$serializationContext = new \LightSaml\Model\Context\SerializationContext();
$request->serialize($serializationContext->getDocument(), $serializationContext);
$serializationContext->getDocument()->formatOutput = true;
$xml = $serializationContext->getDocument()->saveXML();
Mage::log($xml);
$bindingFactory = new \LightSaml\Binding\BindingFactory();
$redirectBinding = $bindingFactory->create(\LightSaml\SamlConstants::BINDING_SAML2_HTTP_REDIRECT);
$messageContext = new \LightSaml\Context\Profile\MessageContext();
$messageContext->setMessage($request);
return $redirectBinding->send($messageContext);
}
Finally do:
$httpResponse = $this->logout();
$this->_redirectUrl($httpResponse->getTargetUrl());
精彩评论