Как получить токен SAML2 в PHP для получения токена OAuth из WSO2 APIM


Я искал решение, но не могу его найти.

Этот вопрос напрямую связан с:

Вот сценарий, который я хочу выполнить:

  1. аутентифицируйтесь в SP с помощью SAML2. Закодированный на PHP с SimpleSAMLphp.
  2. получите токен OAuth из конечной точки mgr API, используя утверждение SAML2. (используя URL-адрес http://api.gateway/token)
  3. вызывайте API-интерфейсы через шлюз mgr API, используя токен OAuth.

Я застрял на инструкции: получите токен утверждения SAML2. Где я могу найти этот жетон? В SimpleSAMLphp я могу получить атрибуты пользователя или его идентификатор, но не могу найти никакого утверждения.

Я взломал SSP, чтобы получить последнее утверждение, но не знаю, что делать делай с этим. Я ожидал одного значения (например, токена), но это сложная структура. И одна из ссылок выше говорит, что я не должен получать к ней доступ!

Что мне отправить в зашифрованном виде на URL-адрес токена?


ПРАВКА: добавление некоторых образцов. Мой XML-файл assert (отредактированный):

<?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">[email protected]</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>

Кодировать как XML в кодировке base64-URL:

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}

Я расспрашиваю о конфигураторах системы. Мне кажется, что в связи между идентификаторами, APIM и OAuth чего-то не хватает, какого-то объявления. (Я погуглил это и придумал обмен stackoverflow, чтобы проверить идентификатор эмитента в утверждении, что я и сделал, но я не могу определить, что там не так)

Спасибо за помощь, я вернусь, если у меня будет что-нибудь новое. За исключением, конечно, если у меня есть упустил что-то очевидное!

Author: JRobinss, 2016-11-21

2 answers

Когда вы входите в систему с помощью единого входа SAML, вы получаете ответ SAML с Assertion в нем. Вы можете увидеть образец ответа/утверждения здесь. Это утверждение необходимо для получения токена OAuth2. Однако, похоже, что ваш php-фреймворк не предоставляет вам ответ SAML напрямую. Это очень плохо, потому что тебе это нужно здесь.

В любом случае, поскольку вам удалось это получить, все, что вам теперь нужно сделать, это base64-URL закодировать весь тег <Assertion>....</Assertion> и отправить с запросом токена OAuth2. Здесь это хороший онлайн-инструмент, если вам нужно попробовать вручную.

 2
Author: Bee, 2016-11-21 17:03:26

Мне это удалось, поэтому вот некоторые указания для других, у кого может быть такая же проблема.

  1. Я взломал SimpleSAMLphp, потому что они не предоставляют утверждение SAML2 (см. https://github.com/simplesamlphp/simplesamlphp/issues/220 ). Я сделал это не по-хорошему, потому что я только хотел, чтобы это сработало. Это некрасиво, но это работает. Вот мой хак, я поместил его в строку 125 из saml2-acs.php :

    // 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-адрес. Для этого я использовал код из , передавая строки в кодировке base64 в URL (спасибо joeshmo!)

  4. В APIM / Поставщики сущностей / список / Мои идентификаторы / редактирование / Федеративные аутентификаторы / Веб-единый вход SAM2... / Идентификатор сущности поставщика удостоверений Я установил значение в конечную точку ожидаемых идентификаторов, https://myids:9443/samlsso. Это решило мою первоначальную проблему

  5. В СП конфигурация (в идентификаторах) Я добавил токен oauth как в качестве аудитории, так и получателя, выглядит так https://myAPIM:9443/oauth2/token/. Внимание, как аудитория , так и получатель !

  6. Поскольку я отлаживал, я отформатировал утверждение XML, поэтому оно не работало, я столкнулся с проблемой, подробно описанной здесь Утверждение SAML носителя сервера идентификации WSO2 OAuth2, поэтому я просто удалил форматирование и использовал строку XML как есть. (Я, конечно, удалил эта ошибка сверху)

  7. У меня была последняя ошибка, которую легко было решить: флаг NotOnOrAfter создавал проблемы, потому что была задержка между получением утверждения SAML2 и использованием его для создания токена. Извлеченный урок: Утверждение SAML2 должно создаваться сразу после входа в систему, а не только перед вызовом API.

Надеюсь, это поможет другим. Спасибо @Bhathiya за помощь!

 1
Author: JRobinss, 2017-05-23 12:09:01