Розбираємо токени авторизації у MS SSO

Довелося розбиратися із системами авторизації у системах MS, і натрапив на гарний гайд по ADFS Deep-Dive: Comparing WS-Fed, SAML, and OAuth, який допоміг при реалізації авторизації у PHP аплікації.

SAML 1.1 токен

Найпростішим способом авторизації є протокол WS-FED (WS-Federation). Після успішної верифікації користувача йде перенаправлення на сторінку сервіса, який зробив запит. У POST даних у змінній wresult приходить токен у форматі SAML 1.1, який є XML структурою.

Для перевірки валідності отриманого токена:

  1. Беремо із блока X509Data сертифікат у форматі Base64-encoded, витягуємо публічний ключ і параметри сертифіката, зокрема його номер, термін дії і видавець. Звіряємо чи ми його визнаємо.
  2. Беремо блок ds:SignedInfo, канонізуємо по схемі вказаній у ds:CanonicalizationMethod, в даному випадку C14N, і звіряємо підпис ds:SignatureValue
    по алгоритму вказному у ds:SignatureMethod (в нас rsa-sha256) відповідно до публічного ключа. Якщо дані не співпадають, дані було змінено.
  3. Беремо блок у XML який підписувався, на нього вказується параметр ds:Reference URI,

це saml:Assertion, і видаляємо з цього блоку структуру ds:Signature

Канонізуємо цей блок по алгоритму вказаному у ds:Transform і знаходимо хеш по алгоритму вказаному у ds:DigestMethod. В даному випадку SHA256. Від має співпати із значенням ds:DigestValue. Якщо все ок, даним можна вірити.

4. Далі беремо дані із підписаного блоку, оскільки їм можна вірити. Це дані коли було зроблено авторизацію AuthenticationInstant, сайт для якого було зроблено автозизарію saml:AudienceRestrictionCondition і дані з блоку saml:AttributeStatement, які можна сконфігурувати у ADFS, наприклад ім’я користувача, його електронна пошта.

5. Звіряємо час видачі токена із поточним часом, і щоб він був відрізнявся не більше, наприклад ніж 10 секунд.

6. Даним із непідписаного блоку не можна вірити, зокрема блоку t:Lifetime.

Також цікава інформація із статті An Introduction to XML Digital Signatures.

JWT токен

Токен може приходити у JWT форматі. Для дебагу рекомендую онлайн тулу JWT.IO.

Токен складається з 3 частин розділених крапкою. Перша частина це JSON дані у форматі Base64. Друга це інформацію про підпис, зокрема йхто валідував, коли, дані користувача. Третя це цифровий підпис першого і другого блоку. Сертифікат для перевірки завантажуємо із сервера, який підписав токет і якому ми довіряємо.

UPD1: при канонізації є певний баг у .NET.

Коментарі