.net многоуровневая идентификация и авторизация в сервисной архитектуре

Я создаю приложение, где требования кажутся стандартными (по крайней мере, для меня)... У меня есть Web.UI, основанный на asp .net mvc и клиентах от iphone, andriod и blackberry.

Поэтому разумнее всего перенести всю мою бизнес-логику на уровень сервисов, к которому можно получить доступ через http. Этот уровень сервисов должен принимать запросы с пользовательским контекстом (идентификацией) и каким-то приятным образом последовательно выполнять авторизацию, независимо от того, какой тип клиента с ним общается (надеюсь?).

Более года подряд я выступал на трехмесячном концерте, в котором работал W.I.F. (Windows Identity Foundation) в гибридной локальной и облачной архитектуре. Мне понравилось. Три вещи, которые вызвали отклик: (1) экстернализация аутентификации без учета того, как это делается, (2) удаление логики авторизации из бизнес-логики, (3) авторизация на основе утверждений.

За последний год я слышал и смотрел все о Rest Services, «новом крутом хипповском способе ведения дел». Так что я, хотя большой, давайте попробуем это. После того, как я начал играть и писать код, я начал сильно запутываться (и впоследствии читал около 10 часов вчера, не написав ни одной строки на С#). Я все еще запутался во всей болтовне SOAP против REST, WS.* против Http, SAML против SWT. Я действительно не хочу, чтобы эта ветка была об этом, потому что в stackoverflow достаточно разговоров об этом, но я чувствую, что у меня есть выбор между двумя лагерями, когда на самом деле не кажется, что я хочу один или другой но биты от каждого?

Мне кажется, что 3 пункта, которые я упомянул выше о WIF, не кажутся концепциями, которые следует привязывать к WS.* ? Но я чувствую, что они, или, по крайней мере, то, как WIF приходит в данный момент, делает их без какой-либо экспертной настройки (например, я наткнулся на этот пост, написанный всего несколько дней назад - http://zamd.net/2011/02/08/using-simple-web-token-swt-with-wif/).

Другие области, о которых я мало знаю, это мои клиенты (iphone, andriod, blackberry), способные играть с WIF, это та же STS, которая выдает им токен SAML, и они ведут себя так же, как браузер, и передают его обратно в заголовке, как и любой другой клиент? Да, мне придется это выяснить, но если это нарушит договор с W.I.F., и я узнаю об этом сразу после публикации, то, по крайней мере, я смогу отвлечься от этого.

Наконец, чтобы добавить еще одну вещь в микс. Я действительно не хочу думать ни о чем из этого. Я хочу использовать стороннего поставщика услуг аутентификации/идентификации — http://www.janrain.com/products/engage - который, как мне кажется, использует OpenID. Может ли это вписаться в W.I.F. или я просто создаю новый токен SAML из OpenID и с этого момента использую WIF.

Думаю, в конце этой болтовни я хочу вернуться к тому, с чего начал, потому что чем больше вопросов я задаю и чем больше вариантов рассматриваю, тем все сложнее и сложнее.

Является ли наличие уровня служб (на WCF), который взаимодействует с разными клиентами, отличными от .net, для которых требуется контекст удостоверения и авторизация, настолько странный? Если вы построили что-то подобное, как вы подошли к этому?


person Jonathon Kresner    schedule 18.02.2011    source источник


Ответы (4)


Когда у вас много устройств, один из способов добиться того, чтобы одно и то же решение работало на всех из них, — ориентироваться на наименьший общий знаменатель.

Предположим, что все ваши клиенты поддерживают файлы cookie. Один из способов сделать это:

  • Наличие системы аутентификации на основе файлов cookie.
  • Кэшировать всю авторизационную информацию на стороне сервера, связанную с сеансом или ключом в куки
  • Для каждого запроса проверьте авторизацию

Не так элегантно, как использование токенов SAML, но работает на разных платформах/устройствах.

iPhone поддерживает файлы cookie http://support.apple.com/kb/HT1675.

Blackberry поддерживает файлы cookie http://docs.blackberry.com/en/developers/deliverables/11844/feature_cookie_storage_438273_11.jsp

person Shiraz Bhaiji    schedule 18.02.2011
comment
Токен SAML — это просто формат, встроенный в файл cookie... Конечно, они могут быть очень большими, но если они не предназначены для уничтожения, я не понимаю, почему токен SAML нельзя использовать на разных платформах. - person Jonathon Kresner; 18.02.2011
comment
Чтобы уточнить, на данный момент я не так озабочен авторизацией и использованием SAML на клиенте, я больше озабочен этим на уровне службы. Что мне нужно знать, так это то, что клиенты могут использовать токен, как браузер. Другими словами, могу ли я предположить то, что вы говорите «предполагая» в своем ответе. - person Jonathon Kresner; 18.02.2011
comment
Я не думаю, что приложение для iphone — это то же самое, что и сафари на вашем iphone? Я думаю, вы должны использовать это, возможно, - developer.apple.com/library/ios/#documentation/DataManagement/ ... В любом случае, я хотел бы знать, действительно ли у кого-нибудь есть трещина в более широкой картине. - person Jonathon Kresner; 18.02.2011
comment
Нет, но собираетесь ли вы создавать разные приложения для каждого устройства? Или вы напишете одно HTML5-приложение, которое будет работать в браузере на всех устройствах? - person Shiraz Bhaiji; 02.03.2011
comment
Нативные приложения на каждом устройстве - person Jonathon Kresner; 02.03.2011
comment
Это очень похоже на схему аутентификации, которую я использую для остальных API. Он очень легкий и простой в реализации. - person Chris Nicola; 07.03.2011

Я попытаюсь ответить на ваш вопрос немного более абстрактно...

Прежде чем я начну, мой фон связан с MS, поэтому могут быть такие же (или лучшие) варианты, доступные из других источников.

Две ссылки, которые я нашел очень полезными:

1) Руководство по идентификации и управлению доступом на основе утверждений

http://msdn.microsoft.com/en-us/library/ff423674.aspx

2) Программирование Windows Identity Foundation

Автор: Витторио Берточчи Доступно в печатном виде в формате Kindle.

Есть много других источников, но эти два охватывают несколько сценариев и дают хорошую справочную информацию для всех, кто хочет ускориться с вашей отправной точкой.

Я призываю других авторов заполнять любые пробелы или неточности :) Я опускаю множество технических деталей, чтобы сосредоточиться на заданном вопросе.

Я разбиваю федеративную идентичность примерно следующим образом:

  1. Приложение(я) [Приложение(я)]
  2. Служба(ы) аутентификации [STS(и)]
  3. Набор(ы) претензий [Претензия(и)]
  4. Доверительные отношения (ы) [Доверие (я)]
  5. Метод(ы) транспортировки [Транспорт(ы)]

STS отвечает за проверку личности пользователя и подтверждение некоторых утверждений. Для этого либо предоставляется (1) подписанный большой двоичный объект, содержащий утверждения, либо (2) уникальный идентификатор, который третья сторона может использовать для поиска утверждений.

Приложение, которое хочет предоставить пользователю услугу, может «доверить» STS в предоставлении ему утверждений, которые оно может использовать для надлежащей работы с пользователем, тем самым снимая с него ответственность за проверку пользователя (среди прочего, такую ​​как поддержка централизованного метаданные, но я отвлекся).

Существует также способность СС «доверять» другому СС, по сути говоря: «Если вы говорите, что этот человек — Джо Смит, и у него есть роли X, Y и Z, то я ручаюсь за то, что вы говорите!»

Итак, перефразируя:

Приложение (я) «доверяет» службе STS { которая, в свою очередь, может «доверять» другой службе STS } в предоставлении ей/им претензий.

** Переключение передач **

МЫЛО против ОТДЫХА

В конце концов, SOAP и REST являются типами службы, давайте назовем их потребителями утверждений. Они оба хотят, чтобы кто-то дал им ведро, полное требований, чтобы они могли сделать свою работу и отправить кое-что обратно. Кроме того, оба типа службы могут быть представлены с утверждениями через строку запроса с использованием маркера (при условии, что служба может обрабатывать некоторые изменения URL-адресов) или через заголовок (HTTP для REST и SOAP для служб SOAP). В любом случае цель одна и та же: передать претензии или UID в приложение.

WS* против HTTP

Это (наряду с TCP/IP, SSL, кольцами секретных декодеров и т. д.) методы передачи информации туда и обратно, хотя и с разной степенью уверенности в том, что кто-то посередине не сможет найти способ выдать себя за пользователя.

SAML против SWT

Они (наряду с кодировкой base 64, xml, простым текстом и т. д.) являются методами сериализации утверждений. Эти двое просто соответствуют стандартам, которых нет у других, поэтому все могут говорить на одном языке.

**Возвращаясь к сути **

Каждая из этих технологических комбинаций допустима (в зависимости от приложения, некоторые из них менее безопасны, другие проще внедрить, третьи лучше работают на устройствах более низкого уровня и т. д.) и представляют собой способ выполнения работы одним человеком по сравнению с другим.

Таким образом, если у меня есть приложение .Net, которому был предоставлен набор утверждений в формате SAML по конвейеру WS*, конечным результатом будет то, что приложение имеет [утверждения в SAML].

С некоторой обработкой их можно преобразовать в [утверждения в SWT].

Затем новые утверждения можно упаковать и отправить через HTTP/SSL в приложение Java.

ЕСЛИ приложение Java «доверяет» той же STS (или STS, которая «доверяет» STS приложений .Net), тогда оно открывает претензии и выполняет свою работу.

  • Экспертная настройка, о которой вы говорите, должна произойти, вопрос только в том, кем и насколько она прозрачна.

    1. Dave provides a perfectly valid example of one way to accomplish the tweaking with custom code.
    2. ADFS предоставляет правила трансляции, которые пытаются выполнить слияние и трансляцию через конфигурацию.
  • Идея наличия сервисов на разных платформах/устройствах/приложениях/и т. д. совсем не странная, это именно тот сценарий, для решения которого все это создается.

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

Упомянутая вами служба Engage позволяет вам связывать пользователей вашего приложения с внешними источниками и может использоваться для аутентификации этих пользователей... аля "Я вижу, что вы прошли аутентификацию в Google как [email protected], я знаю вас как Джона Уокера с идентификатором из 4321, о, смотрите, вы изменили свой любимый цвет в Google на синий... продолжайте!"

Чего он не делает, так это предоставляет претензии к вашему приложению, которые относятся к вашему приложению (если только все, что вам нужно знать, не исходит из данных Google, и в этом случае вы, вероятно, создаете мешанину, а не LOB-приложение...

Другой сценарий:

  1. Пользователь переходит в ваше приложение
  2. перенаправляется на вашу STS
  3. перенаправляется в Google
  4. Возвращается на ваш STS
  5. Добавлена ​​электронная почта и заявления о любимых цветах (на Google)
  6. Добавлен список ролей и заявлений о лимите покупки (из хранилища данных конкретного приложения)
  7. Пользователь возвращается в приложение
  8. Пользователь пытается купить фиолетовые виджеты за 10 000 долларов, а вы говорите: «Ну, вы можете купить только 5 000 долларов в кредит и… вы уверены, что хотите фиолетовые, я слышал, вы предпочитаете синие?»

Еще одно место, на которое я хотел бы вас направить, — это служба управления доступом AppFabric, предлагаемая Microsoft. (http://msdn.microsoft.com/en-us/library/ee732536.aspx) отказ от ответственности: я еще не использовал его, но похоже, что он делает такие переводы, как вы ищет с большим количеством мяса, спрятанного для вас.

person Perry    schedule 03.03.2011
comment
Не могли бы вы ответить на stackoverflow.com/questions/9553267/ ? - person LCJ; 04.03.2012

Поскольку WIF говорит о WS-Trust / WS-Federation под капотом, вы можете выставить проверку подлинности на основе утверждений на уровне служб.

В этой статье показано, как создать службу STS WCF, которая будет взаимодействовать с внешними клиентами с помощью этих протоколов. http://msdn.microsoft.com/en-us/library/ee748498.aspx

С точки зрения авторизации на уровне сервисов вы можете использовать настраиваемый менеджер авторизации, чтобы проверить, были ли предъявлены претензии. http://msdn.microsoft.com/en-us/library/ms731774.aspx

Чтобы подключить внешние службы идентификации, такие как OpenID, и добавить свои собственные утверждения к утверждениям, созданным WIF, вы можете создать подкласс из ClaimsAuthenticationManager следующим образом:

public class MyClaimsAuthenticationManager : ClaimsAuthenticationManager {

    public override IClaimsPrincipal Authenticate(string resourceName, IClaimsPrincipal incomingPrincipal)
    {
        if (!incomingPrincipal.Identity.IsAuthenticated)
        {
            return incomingPrincipal;
        }

        //TODO: obtain user profile claims from external source, i.e. database, web service            
        // below code demonstrates how to custom claims to the current principal 
        // (which are then persisted for the lifecycle of the user's browser session)            

        IClaimsIdentity identity = (IClaimsIdentity)incomingPrincipal.Identity;

        identity.Claims.Add(new Claim(ClaimTypes.Email, "[email protected]"));

        return incomingPrincipal;
    }
}

Вам нужно указать WIF использовать собственный диспетчер утверждений в файле Web.config, установив параметр конфигурации ClaimsAuthenticationManager.

Надеюсь это поможет.

person DaveRead    schedule 03.03.2011
comment
Одна вещь, которую я должен уточнить, заключается в том, что ссылка диспетчера авторизации WCF, которую я разместил, использует классы утверждений WCF, и что вы должны использовать пространство имен Microsoft.IdentityModel, если вы развертываете службы позади WIF. - person DaveRead; 03.03.2011

Я подошел к аналогичной проблеме, используя spring + java; все необходимые концепции находятся в .net, поэтому я упоминаю об этом здесь. Я обнаружил, что решение, которое предлагает spring-security, работает хорошо (для моих простых требований авторизации ). На моем уровне служб методы, требующие определенных разрешений, объявляют это с помощью аннотаций (либо в интерфейсе, либо в реализации):

@Secured(MyPermissions.READ, MyPermissions.WRITE)
void modifyPerson(PersonChanges changes);

@Secured(MyPermissions.READ)
Person readPerson();

В этом примере структура безопасности (пружина) оборачивает реализации службы с помощью динамического прокси, который проверяет, что мой уровень авторизации поместил правильные роли/разрешения в области потока в контексте, где оценивается метод службы, если не выдается исключение безопасности. .

Я также счел полезным сгруппировать сервисы, которым требуются разрешения по шаблонам URL, чтобы требование «требуется аутентифицированный участник» выполнялось на самом высоком уровне: например. myapp/services/secure/personService -- любой шаблон URL, требующий */secure, будет перенаправлять на страницу аутентификации, если информация для аутентификации отсутствует.

Что действительно приятно (хотя я) в требовании учетных данных для потока, так это то, что даже если настройка перехватчика HTTP верхнего уровня выполнена неправильно (например, не удается проверить/создать сеанс аутентификации), пока работает динамический прокси, нет способ выполнения бизнес-логики.

Кроме того, это очень хорошо работает для агрегированных сервисов — если один сервис вызывает другой, правила авторизации более низкого уровня по-прежнему применяются, если они не объявлены должным образом в составном сервисе.

person Justin    schedule 07.03.2011