Налаштування федеративної аутентифікації у WCF

Здалися цікавими, на мій смак, пости

Сергію, добрий день.

Що ж, я в принципі розібрався з усіма складнощами та напастями, що мені зустрічалися і тепер можу розповісти, що ж у мене вийшло. На даний момент, у мене готовий перший варіант, з тих, що описував, тобто. практично всю роботу на себе бере WCF (правда в .Net 4.5 робота так чи інакше йде з використанням WIF, але від вас особисто не вимагатиме жодного рядка коду для WIF - хіба що ви почнете робити якісь кастомні розширення).

Для початку, щоб у нас було єдине розуміння того, що відбувається, дозволю собі невеликий опис процесу (див. картинку):

федеративної
0. Користувач вводить свої UserName та Password (U/P) 1. Клієнт намагається підключитися до WCF Service, використовуючи передані йому U/P. Однак, інфраструктура WCF аналізує вказані їй налаштування і з'ясовує, що від неї потрібно працювати за Federation протоколом, а це означає, що замість прямого звернення WCF Service вона формує спеціальний Security Token Request (STR), який відсилає на STS. При цьому як credentials в SRT використовуються наші U/P. 2. STS отримує STR і насамперед аналізує credentials (треба сказати, що в загальному випадку це не обов'язково повинні бути саме UserName/Password, а будь-який допустимий спосіб аутентифікації Windows, Certificate, … — аж до отриманого раніше сертифіката! Але ми розглядаємо найпростіший випадок). Отримавши та аутентифікувавши STR, наш STS починає його аналізувати та обробляти. Робить він це так:
  • дивиться, для якого сервера буде видаватися токен (у термінології WIF такий сервер-одержувач токена називається Relying Party, RP). Якщо в списку його довірених такого сервера формується помилка і токен невидається
  • витягує зі своєї бази дані користувача (користувача він бере з переданих credentials)
  • генерує ключі симетричного шифрування для клієнта та сервера — цими ключами захищатиметься канал/сесія між клієнтом та RP
  • формує токен для RP (що складається з даних користувача і ключа шифрування), підписує його своїм закритим ключем і шифрує відкритим ключем RP.
  • потім, зашифрований пакет вкладає ще один пакет, призначений вже для клієнта (там можуть бути ті ж дані, але зазвичай там тільки шифрування для клієнта). Цей пакет також підписується
  • результат повертається клієнту (Security Token Response, STRes)
3. Клієнт, який отримав STRes, перевіряє підпис STS, дістає свої дані і зашифрований пакет для RP і вже з цим пакетом робить запит на встановлення з'єднання з WCF Service 4. WCF Service отримує запит, дістає звідти зашифрований пакет, розшифровує його закритим ключем і перевіряє підпис STS. Якщо все гаразд, то встановлюється сесія з клієнтом, а дані з токена використовуються як дані автентифікованого користувача.

Тепер переходимо до клієнта.Тут теж нічого спеціально робити не треба, просто створити ServiceReference для нашого WCF Service.

Ну все, налаштування закінчено

Тепер пишемо пробний код клієнта(створюємо proxy і вказуємо User/Password як credentials)

Ну і залишилося навести код сервісуТам нічого складного, просто показую як дістатися до переданих Claims. На відміну від WIF 3.5, WIF 4.5 не змінює Principal поточного потоку (хоча може десь і є така опція), а пропонує як і загалом у WCF все отримувати через OperationContext

Сподіваюся, всевийшло досить зрозуміло. Якщо залишаться питання - запитуйте без збентеження (якщо я не довго відповідатиму - запитайте в особу, я не завжди читаю RSDN, а так має прийти повідомлення).

З приводу другого варіанта (окреме отримання токена і потім вручну додавання його в виклики сервісів як Credentials) - він теж повинен бути можливий (ми саме так і працюємо), але з ходу накидати приклад на WCF/WIF 4.5 я не зможу, а більше поки часу на дослідження, на жаль, не залишилося.