有一个很好的SimpleSAMLphp SLO示例吗?

时间:2011-09-23 17:05:26

标签: php logout saml

我们的一位客户要求我们通过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?

2 个答案:

答案 0 :(得分:3)

SLO问题

想象一下这个方案:

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

IdP问题

使用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());