如何在PHP中检索SAML2令牌以从WSO2获取OAuth令牌APIM

时间:2016-11-21 15:43:42

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

我一直在寻找解决方案,但无法找到它。

此问题与以下内容直接相关:

这是我想要执行的场景:

  1. 使用SAML2对SP进行身份验证。使用SimpleSamlPhp在PHP中编写。
  2. 使用SAML2断言从API mgr端点获取OAuth令牌。 (使用网址http://api.gateway/token
  3. 使用OAuth令牌通过API mgr网关调用API。
  4. 我坚持说明:获取SAML2断言令牌。 我在哪里可以找到这个令牌? 在SimpleSamlPhp中,我可以获取用户的属性或他们的id,但我无法找到任何断言。

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

    我将哪些内容编码发送到令牌网址?

    编辑:添加一些样本。 我的断言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,我做了,但我无法识别那里的错误)

    感谢您的帮助,如果我有新的东西,我会回来的。当然,如果我忽略了一些显而易见的东西!

2 个答案:

答案 0 :(得分:2)

使用SAML SSO登录时,会收到包含Assertion的SAML回复。您可以看到示例响应/断言here。您需要此断言才能获得OAuth2令牌。但是,看起来您的php框架不直接向您提供SAML响应。这太糟糕了,因为你需要它。

无论如何,既然您已设法获得该功能,那么您现在要做的就是base64-URL对整个<Assertion>....</Assertion>代码进行编码,并使用OAuth2令牌请求进行发送。 Here is a nice online tool如果您需要手动尝试。

答案 1 :(得分:1)

我已经成功了,所以这里有一些迹象表明可能有同样问题的其他人。

  1. 我攻击了 simpleSamlPhp ,因为他们没有提供SAML2断言(请参阅https://github.com/simplesamlphp/simplesamlphp/issues/220)。我没有以一种很好的方式做到这一点,因为我只是想让它发挥作用。这很难看,但它确实有效。这是我的黑客,我把它放在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-encode进行编码。为此,我使用了来自Passing base64 encoded strings in URL的代码(感谢joeshmo!)

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

  6. 在SP配置中的
  7. (在IDS中)我将oauth令牌添加为受众和收件人,看起来像 https://myAPIM:9443/oauth2/token/ 。注意,作为观众收件人!

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

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

  10. 希望这有助于他人。谢谢@Bhathiya的帮助!