【问题标题】:How to retrieve SAML2 token in PHP for getting an OAuth token from WSO2 APIM如何在 PHP 中检索 SAML2 令牌以从 WSO2 APIM 获取 OAuth 令牌
【发布时间】:2016-11-21 15:43:41
【问题描述】:

我一直在寻找解决方案,但找不到。

这个问题直接相关:

这是我要执行的场景:

  1. 使用 SAML2 向 SP 进行身份验证。使用 SimpleSamlPhp 用 PHP 编码。
  2. 使用 SAML2 断言从 API mgr 端点获取 OAuth 令牌。 (使用网址http://api.gateway/token
  3. 使用 OAuth 令牌通过 API 经理的网关调用 API。

我被困在指令上:获取 SAML2 断言令牌。 我在哪里可以找到这个令牌? 在 SimpleSamlPhp 中,我可以获取用户的属性或他们的 id,但我找不到任何断言。

我破解了 SSP 以获得最后一个断言,但不知道如何处理它。我期待一个单一的值(如令牌),但它是一个复杂的结构。上面的链接之一说我不应该访问它!

我要向令牌 URL 发送什么编码的内容?


编辑:添加一些示例。 我的断言 XML(已编辑):

<?xml version="1.0" encoding="UTF-8"?>
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" ID="okdjgbm...jdbh" IssueInstant="2016-11-28T09:49:45.808Z" Version="2.0">
   <saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://g...p.com:9443/samlsso</saml2:Issuer>
   <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:SignedInfo>
         <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
         <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
         <ds:Reference URI="#okd...kejdbh">
            <ds:Transforms>
               <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
               <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <ds:DigestValue>RrGcR...cktFuH0=</ds:DigestValue>
         </ds:Reference>
      </ds:SignedInfo>
      <ds:SignatureValue>b91j/k...Z7d4=</ds:SignatureValue>
      <ds:KeyInfo>
         <ds:X509Data>
            <ds:X509Certificate>MIICNT...Wq8uHSCo=</ds:X509Certificate>
         </ds:X509Data>
      </ds:KeyInfo>
   </ds:Signature>
   <saml2:Subject>
      <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">toto@titi.com</saml2:NameID>
      <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
         <saml2:SubjectConfirmationData InResponseTo="_80258326a1...cd4bbd" NotOnOrAfter="2016-11-28T09:54:45.807Z" Recipient="http://1.2.3.4/simplesamlphp/www/module.php/saml/sp/saml2-acs.php/wso2-sp" />
      </saml2:SubjectConfirmation>
      <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
         <saml2:SubjectConfirmationData InResponseTo="_8025832...d4bbd" NotOnOrAfter="2016-11-28T09:54:45.807Z" Recipient="https://my.wso2.apim:8243/token" />
      </saml2:SubjectConfirmation>
   </saml2:Subject>
   <saml2:Conditions NotBefore="2016-11-28T09:49:45.808Z" NotOnOrAfter="2016-11-28T09:54:45.807Z">
      <saml2:AudienceRestriction>
         <saml2:Audience>mytestapp</saml2:Audience>
         <saml2:Audience>https://my.wso2.apim:8243/token</saml2:Audience>
      </saml2:AudienceRestriction>
   </saml2:Conditions>
   <saml2:AuthnStatement AuthnInstant="2016-11-28T09:49:45.815Z" SessionIndex="1f5192...b591">
      <saml2:AuthnContext>
         <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml2:AuthnContextClassRef>
      </saml2:AuthnContext>
   </saml2:AuthnStatement>
   <saml2:AttributeStatement />
</saml2:Assertion>

编码为 base64-URL 编码的 XML:

PHNhbWwyO...dGlvbj4,

使用从另一个 SO 帖子复制的方法

function base64_url_encode($input) {
 return strtr(base64_encode($input), '+/=', '-_,');
}

大约有 20 行长(是的,末尾有一个逗号)。

不行,我得到JSON结果

{"error":"invalid_grant","error_description":"Provided Authorization Grant is invalid."}

在痕迹中:

TID: [0] [AM] [2016-11-29 11:04:50,297] DEBUG {org.wso2.carbon.identity.oauth2.token.handlers.grant.saml.SAML2BearerGrantHandler} -  SAML Token Issuer verification failed or Issuer not registered {org.wso2.carbon.identity.oauth2.token.handlers.grant.saml.SAML2BearerGrantHandler}
TID: [0] [AM] [2016-11-29 11:04:50,298] DEBUG {org.wso2.carbon.identity.oauth2.token.AccessTokenIssuer} -  Invalid Grant provided by the client, id=fkJa...Ohoa, user-name=null to application=myapp-subscriber_test_PRODUCTION {org.wso2.carbon.identity.oauth2.token.AccessTokenIssuer}
TID: [0] [AM] [2016-11-29 11:04:50,300] DEBUG {org.wso2.carbon.identity.oauth2.token.AccessTokenIssuer} -  OAuth-Error-Code=invalid_grant client-id=fkJa...hoa grant-type=urn:ietf:params:oauth:grant-type:saml2-bearer scope=PRODUCTION {org.wso2.carbon.identity.oauth2.token.AccessTokenIssuer}

我正在询问系统的配置器。在我看来,IDS、APIM 和 OAuth 之间的链接中缺少一些东西,一些声明。 (我用谷歌搜索了这个,并提出了一个 stackoverflow 交换来检查断言中的颁发者 ID,我这样做了,但我无法确定那里有什么问题)

感谢您的帮助,如果我有什么新的东西,我会回来的。当然,如果我忽略了一些明显的事情!

【问题讨论】:

标签: php oauth wso2 saml-2.0 wso2-am


【解决方案1】:

当您使用 SAML SSO 登录时,您会收到一个包含 Assertion 的 SAML 响应。您可以看到示例响应/断言here。您需要此断言来获取 OAuth2 令牌。但是,您的 php 框架似乎没有直接向您提供 SAML 响应。这太糟糕了,因为你在这里需要它。

无论如何,既然您已经设法获得了它,那么您现在要做的就是将base64-URL 编码整个&lt;Assertion&gt;....&lt;/Assertion&gt; 标记并使用OAuth2 令牌请求发送。 Here is a nice online tool 如果您需要手动尝试。

【讨论】:

  • 感谢您的快速响应。我将尝试使用我添加到 SSP 的 hack,并使用我得到的断言。
  • 我听从了您的建议:我没有寻找单值标记,而是将整个断言用 XML 进行了编码,将其编码为 base64-url-encode,并将其传递为 assertion=....Didn'不起作用,是我做错了什么,还是我在 APIM 中有一些错误的配置? (请参阅原始问题中的示例)
  • 是的,我检查了,应用注册似乎有问题。我将编辑原始帖子以完成此任务(因为 cmets 编辑器无法胜任任务!)
  • 看起来发行者值在 SP 和 SAML 断言中不同。请仔细检查。
  • 几个问题......当出现这样的错误时,authent 会发生吗?另外,我应该比较什么? SP 配置中的“issuer”是应用程序的名称,而 SAML 消息中的“issuer”是 IS 的 URL(此处为 WSO2 IDS,与 APIM 分开)。谢谢!
【解决方案2】:

我已经成功了,所以这里有一些迹象可供可能遇到相同问题的其他人参考。

  1. 我破解了 simpleSamlPhp,因为它们不提供 SAML2 断言(请参阅 https://github.com/simplesamlphp/simplesamlphp/issues/220)。我没有以一种好的方式做到这一点,因为我只想让它发挥作用。这很丑陋,但它有效。这是我的 hack,我把它放在 saml2-acs.php 的第 125 行:

    // ADDED to get SAML2 assertion in SP
    if (array_key_exists('SAMLResponse', $_POST)) {
        $attributes["samlresp"] = $_POST['SAMLResponse'];
    }
    
  2. 在我的 PHP 应用程序中,然后我使用以下代码:

    $authdata_array= $as->getAuthDataArray();
    $postSaml2Assert = $authdata_array["Attributes"]["samlresp"];
    $msg = base64_decode($postSaml2Assert);
    $document = new DOMDocument();
    $document->loadXML($msg);
    $assertion = $document->getElementsByTagNameNS ("urn:oasis:names:tc:SAML:2.0:assertion", "Assertion")->item(0);
    $saml2AssertionXml = $document->saveXML($assertion);
    
  3. 我对断言 base64 和 URL 编码进行编码。为此,我使用了来自Passing base64 encoded strings in URL 的代码(感谢joeshmo!)

  4. APIM/Entity Providers/list/myIdS/edit/Federated Authenticators/SAM2 web SSO.../Identity Provider entity ID中我将值设置为预期的IDS端点,https://myids:9443/samlsso。 这解决了我最初的问题

  5. 在 SP 配置中(在 IDS 中)我添加了 oauth 令牌作为受众和收件人,看起来像 https://myAPIM:9443/oauth2/token/。小心,作为观众接收者!

  6. 因为我在调试我已经格式化了 XML 断言,所以它没有工作,我遇到了这里详述的问题 WSO2 Identity Server OAuth2 Bearer SAML Assertion 所以我只是删除了格式并按原样使用 XML 字符串。 (我当然已经从上面删除了这个错误)

  7. 最后一个错误很容易解决:NotOnOrAfter 标志出了问题,因为在获取 SAML2 断言和使用它生成令牌之间存在延迟。经验教训:SAML2 断言应该在登录之后创建,而不是在调用 API 之前。

希望这对其他人有所帮助。感谢@Bhathiya 的帮助!

【讨论】:

    猜你喜欢
    • 2022-06-18
    • 2021-09-07
    • 2019-10-17
    • 1970-01-01
    • 2020-06-24
    • 2018-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多