我们的一位客户要求我们通过SAML实施单点登出(SLO)。他们SAML服务的一方是身份提供商,而我们的服务提供商。单点登录(SSO)通过使用客户端的IdP验证用户的凭证,然后将用户重定向到另一个平台上的登录页面,使用令牌让他们直接登录。该平台完全不了解SAML,并且特别是不共享SimpleSAMLphp会话状态。
注销需要通过两种方式实现:
如果用户点击我们平台上的注销按钮,则需要将其注销我们的网站,然后点击IdP的SLO服务。
如果用户点击客户端或其他服务提供商那边的注销按钮,客户端IdP将会点击我们的SP的SLO服务,然后需要在重定向用户之前将其记录到真实平台之外返回SP的退出响应页面。
我能够说服我们的平台在注销时将用户重定向到任意页面,所以我认为第一部分可以通过使用SimpleSAML_Auth_Simple::getLogoutURL()
的页面来实现。
这样的页面在从IdP端点击时也可能有效,但是SAML规格很复杂,直到我们尝试它才能确定。但是,config/authsources.php
中的SP配置不接受SingleLogoutService
参数;由/www/module.php/saml/sp/metadata.php/entityid
生成的元数据仍将/www/module.php/saml/sp/saml2-logout.php/entityid
列为SingleLogoutService位置。如果该页面是清除SimpleSAMLphp会话所必需的,那很好,但我需要知道如何处理将用户登出我们平台所需的额外重定向。
我尝试过搜索示例,但我得到的只是API参考。知道如何在不尝试设置我自己的IdP的情况下测试注销也很好;是否有像openidp.feide.no
这样的服务来处理SLO和SSO?
答案 0 :(得分:3)
想象一下这个方案:
Plattform - SP1 ----- IdP ----- SP2 ----- App
Plattform和Apps与simpleSAMLphp SP连接,它还与IdP形成联盟。
你必须找到Platffom,app1和app2的正常注销功能并重写它:
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
}
这将结束本地会话,连接到此应用程序的SP会话,IdP会话以及连接到IdP的SP的SP会话但是......其他应用会话会发生什么?他们仍然会活跃。你想过一个活跃的电话来结束它,但我认为如果你也覆盖&#34; is_logged_in()&#34;许多应用程序实现的功能。
您必须覆盖此函数,并且只有在使用函数
存在有效的SP会话时才返回true$auth->isAuthenticated()
最近我在Wordpess SAML plugin上实现了此功能,请检查code
使用Onelogin free trial,您可以在那里注册您的SP并使用其IdP。请遵循此guide to configure your SAML connectors
但我认为你最好自己尝试建立一个IdP。 有一个很好的documentation,步骤很简单。使用&#34; example-userpass&#34; authsource如果你不想浪费时间配置数据库/ ldap。
此外,您可以将实际的simplesamlphp实例设置为SP&amp; IdP但我认为,如果你正在学习simplesamlphp,最好不要混用。
答案 1 :(得分:0)
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);
}
最后要做:
$httpResponse = $this->logout();
$this->_redirectUrl($httpResponse->getTargetUrl());