douxie9471 2016-11-21 15:43
浏览 120
已采纳

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

I have been looking around for a solution but can't find it.

This question is directly related to:

Here's the scenario I want to execute:

  1. authenticate to the SP using SAML2. Coded in PHP with SimpleSamlPhp.
  2. get an OAuth token from the API mgr endpoint, using the SAML2 assertion. (using URL http://api.gateway/token)
  3. call APIs over the API mgr's gateway, using the OAuth token.

I'm stuck at the instruction: get the SAML2 assertion token. Where do I find this token? In SimpleSamlPhp I can get attributes of the user, or their id, but I can't find any assertion.

I hacked SSP to get the last assertion, but don't know what to do with it. I was expecting a single value (like a token), but it's a complex structure. And one of the links above says I shouldn't be accessing it!

What do I send, encoded, to the token URL?


EDIT: adding some samples. My assert XML (edited):

<?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>

encode as base64-URL-encoded XML:

PHNhbWwyO...dGlvbj4,

using the method copied from another SO post

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

It's about 20 lines long (and yes, there's a comma at the end).

It doesn't work, I get the JSON result

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

In the traces:

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}

I'm asking around to the configurators of the system. Seems to me there's something missing in the link between IDS, APIM and OAuth, some declaration. (I googled this, and came up with a stackoverflow exchange to check the issuer id in the assertion, which I did, but I can't identify anything wrong there)

Thanks for the help, I will come back if I have anything new. Except of course if I have overlooked something obvious!

  • 写回答

2条回答 默认 最新

  • douzuita7325 2016-12-08 11:11
    关注

    I have succeeded, so here are some indications for others who may have the same issue.

    1. I hacked simpleSamlPhp because they do not provide the SAML2 assertion (see https://github.com/simplesamlphp/simplesamlphp/issues/220). I did not do it in a nice way, because I only wanted to make it work. It's ugly but it works. Here's my hack, I put it at line 125 of saml2-acs.php:

      // ADDED to get SAML2 assertion in SP
      if (array_key_exists('SAMLResponse', $_POST)) {
          $attributes["samlresp"] = $_POST['SAMLResponse'];
      }
      
    2. In my PHP app, I then use this code:

      $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. I encode the assertion base64 and URL-encode. For this I used code from Passing base64 encoded strings in URL (thanks joeshmo!)

    4. in APIM / Entity Providers / list / myIdS / edit / Federated Authenticators / SAM2 web SSO... / Identity Provider entity ID I set the value to the expected IDS endpoint, https://myids:9443/samlsso. This solved my initial issue

    5. in the SP configuration (in the IDS) I added the oauth token both as audience and recipient, looks like https://myAPIM:9443/oauth2/token/. Caution, both as audience and recipient!

    6. Because I was debugging I had formatted the XML assertion, so it wasn't working, I ran into the problem detailed here WSO2 Identity Server OAuth2 Bearer SAML Assertion so I simply removed the formatting and used the XML string as-is. (I have of course removed this error from above)

    7. I had a last error easy to solve: the NotOnOrAfter flag was making trouble, because there was a delay between getting the SAML2 assertion and using it to generate a token. Lesson learned: The SAML2 assertion should be created just after logging in, not just before calling APIs.

    Hope this helps others. Thanks @Bhathiya for helping!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 在线手电筒追加按钮JS
  • ¥15 调用函数时,无关变量的改变引起函数值的改变
  • ¥15 xy坐标转化为经纬度坐标
  • ¥15 一般三角模糊数的上界值和下届值取中值的多少比较合理?
  • ¥15 关于#python#的问题,请各位专家解答!
  • ¥20 Hbase启动失败,无法启动HMaster
  • ¥20 Lumerical FDTD solutions 中模型的相对阻抗,有效介电常数和有效磁导率的实部和虚部的数据如何获得?
  • ¥100 sql reporting service 远程smtp服务器配置支持
  • ¥15 ppyoloe_r带角度目标检测,loss_cls没法收敛
  • ¥15 淘宝交易指数如何解读,其关联的数据指标是什么