是否有一个很好的SimpleSAMLphp SLO示例


Is there a good SimpleSAMLphp SLO example?

我们的一个客户要求我们通过SAML实现单次注销(SLO)。他们的SAML服务是身份提供者,而我们的SAML服务是服务提供者。单点登录(SSO)的工作原理是使用客户机的IdP验证用户的凭据,然后将用户重定向到另一个平台上的登录页面,并使用令牌让他们直接登录。该平台完全不了解SAML,特别是不共享SimpleSAMLphp会话状态。

注销需要以两种方式发生:

  • 如果用户在我们的平台上点击登出按钮,需要将其登出我们的网站,并点击IdP的SLO服务

  • 如果用户点击客户端或其他服务提供商的注销按钮,客户端IdP将点击我们的服务提供商的SLO服务,然后需要将用户从我们的真实平台注销,然后将用户重定向到服务提供商的注销响应页面。

我能够说服我们的平台在注销时将用户重定向到任意页面,所以我认为第一部分可以通过使用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?

SLO Issue

想象一下这个方案:

Plattform——SP1 IdP SP2,应用

平台和应用程序与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会话,但…其他应用程序会话发生了什么?它们仍然是活跃的。你想过一个主动调用来结束它,但我认为如果你也覆盖许多应用程序实现的"is_logged_in()"函数会更好。

你必须重写这个函数,并且只有当存在一个有效的SP会话活动时才返回true。

$auth->isAuthenticated()

最近我在wordpress SAML插件上实现了这个功能,检查代码

<标题> 国内流离失所者问题

使用Onelogin免费试用版,您可以在那里注册您的SP并使用其IdP。按照本指南配置SAML连接器

但我认为你最好试着自己建立一个IdP。有一个很好的文档和步骤很容易。如果你不想浪费时间配置数据库/ldap,请使用"example-userpass" authsource。

你也可以将你的simplesamlphp实例设置为SP &IdP,但我认为如果你正在学习simplesamlphp最好不要混合。

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