有没有好的 SimpleSAMLphp SLO 示例?
Posted
技术标签:
【中文标题】有没有好的 SimpleSAMLphp SLO 示例?【英文标题】:Is there a good SimpleSAMLphp SLO example? 【发布时间】:2011-11-23 20:28:27 【问题描述】:我们的一位客户要求我们通过 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?
【问题讨论】:
看看Shibboleth。 @JaredFarrish:那里的软件似乎是基于 Java 的,我们被要求使用 PHP 来制作歇斯底里的葡萄干。如果你指的是协议,它是由客户决定的;两者是相关的,但我完全不确定它们是否完全兼容。说服一个真正的 SAML 包与客户的服务对话已经够难的了。 【参考方案1】: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());
【讨论】:
【参考方案2】:SLO 问题
想象一下这个方案:
平台 -- 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()
最近我在Wordpess SAML plugin上实现了这个功能,查看code
IdP 问题
使用 Onelogin free trial ,您可以在那里注册您的 SP 并使用其 IdP。关注这个guide to configure your SAML connectors
但我认为您最好尝试自己构建 IdP。 有一个不错的documentation,步骤很简单。如果您不想浪费时间配置数据库/ldap,请使用“example-userpass”authsource。
您也可以将实际的 simplesamlphp 实例设置为 SP 和 IdP,但我认为如果您正在学习 simplesamlphp,最好不要混用。
【讨论】:
以上是关于有没有好的 SimpleSAMLphp SLO 示例?的主要内容,如果未能解决你的问题,请参考以下文章
simplesamlphp 上没有安装名为“ldap”的模块
在 symfony 中使用 SimpleSAMLphp 和 composer