Как охватить и сохранить претензии к различным клиентам в IdentityServer 3?
Я новичок в IdentityServer3 и имею несколько клиентов MVC, где у пользователей есть претензии, которые потенциально могут конфликтовать и давать нежелательную авторизацию.
Вот пример с двумя клиентами, которые могут отправлять электронные письма и уведомления пользователям. Пользователь может иметь доступ к обоим приложениям, но должен иметь возможность получать уведомления только в Приложении A. Как мы можем запретить пользователю получать уведомления в Приложении B?
Application A
Claim Type: ApplicationFunctionality Claim Value:
RecieveNotifications
Claim Type: ApplicationFunctionality Claim Value: RecieveEmails
Application B
Claim Type: ApplicationFunctionality Claim Value: RecieveEmails
Было бы разумным решением реализовать некую логику в классе, используя интерфейс IUserService?
Было бы правильно использовать утверждения, как я описал выше, для нескольких клиентов, где мы иногда повторно используем утверждения для межклиентских функций. Я предполагаю, что мне потребуется пространство имен утверждений (возможно, с использованием запрошенного имени области, которое клиент отправляет IdentityServer), чтобы различать утверждения для разных клиентов и предотвращать несанкционированный доступ между клиентами.
Вот пример типов претензий пользователя / значений претензий:
Name: John Doe
Email: john.doe@acme.com
PreferedLanguages: English,Swedish,Spanish
ApplicationFunctionality: ClientA.RecieveEmails
ApplicationFunctionality: ClientB.RecieveEmails
ApplicationFunctionality: ClientA.RecieveNotifications
ApplicationFunctionality: ClientB.RecieveNotifications
ApplicationFunctionality: ClientA.ViewBackorders
ApplicationFunctionality: ClientA.DeleteBackorder
ApplicationFunctionality: ClientB.SearchProductInformation
CompanyID: 1145
CompanyID: 6785
CompanyName: Acme Inc
ApplicationLicense: ClientA.PayingNormalUser
ApplicationLicense: ClientB.FreeUser
У пользователя из компании Acme Inc есть несколько CompanyID, которые используются при фильтрации данных, которые мы запрашиваем из веб-сервисов \ баз данных на уровне данных. Пользователь имеет доступ к нескольким приложениям, где он / она может иметь разные уровни функциональности в зависимости от того, какую лицензию они приобрели в приложениях. Некоторые функции существуют в нескольких клиентах, но это не означает, что пользователь авторизован для одинаковых функций во всех клиентах, к которым у него есть доступ.
Я был бы признателен за некоторые рекомендации по поводу претензий или, возможно, указал бы мне на некоторые хорошие ресурсы по этому вопросу. Я читал, что первичные претензии используются для информации, связанной с идентификацией (электронная почта, имя, отдел, любимый цвет, размер обуви и т. Д.), Но если с заявками не следует использовать претензии в стиле ролей / разрешений, то как следует получать информацию о том, что пользователь авторизован? что нужно сделать, чтобы клиенты были постоянными, и как следует фильтровать данные в веб-сервисах / базах данных (поставщиках ресурсов), чтобы пользователь видел только те данные, которые ему разрешено просматривать?
Мои первые мысли о том, что id_token и токен доступа было бы удобно использовать, так как они выдавались STS (IdentityServer), а затем сохранялись в файлах cookie. Служба STS сначала должна выполнить поиск учетной записи пользователя в Active Directory, которая содержит информацию, связанную с идентификацией пользователя, вместе с поиском (с использованием имени пользователя учетной записи пользователя Active Directory) в пользовательской базе данных, содержащей информацию о роли \ разрешениях и утверждениях пользователя.,
Как мне сохранить роли / разрешения и утверждения пользователя, если не используются постоянные маркеры cookie, предоставленные IdentityServer?
2 ответа
Клиенты (приложения) и пользователи могут иметь свои собственные требования. Похоже, вы хотите иметь приложения, которые имеют доступ к различным ресурсам. Это где вы должны использовать области. В основном определяют две области, которые определяют действие на этом ресурсе (это один из распространенных способов сделать это), то есть одну для "чтения" электронных писем и одну для "написания" электронных писем (например, emails.read
а также emails.write
) впоследствии другие рамки могут быть backorders.read
а также backorders.delete
, Это просто хорошая практика, чтобы иметь последовательное наименование здесь.
Хорошо, теперь, так как мы определили эти две области, теперь вы можете определить двух клиентов, один из которых имеет только emails.read
область видимости, а другая имеет области чтения и записи. Все это означает, что один клиент имеет доступ к большему количеству ресурсов, чем другой.
Все утверждения личности пользователя должны придерживаться самого пользователя. Специфическое приложение / клиент никогда не должно быть связано с пользователем. Name
,Email
,ApplicationLicense
, а также PreferredLanguages
все действительные претензии для пользователя, потому что они описывают самого пользователя и что можно утверждать о нем.
Для "сложной" авторизации вы можете посмотреть в этом примере некоторые идеи о том, как настроить составные политики безопасности или авторизацию.
Похоже, вы хотите выставить разные значения для разных клиентов для одной и той же заявки. Это кажется логичным, что нужно сделать, особенно если вы интегрируетесь с клиентами, которые не находятся под вашим контролем и, следовательно, не могут диктовать им, что ожидать в каждой заявке или какие области запросить. Простым примером может служить утверждение о "ролях" - вы можете отправить разные значения в зависимости от приложения, которое делает запрос. Если вы присоединяетесь к чужому предприятию, возможно, с несколькими поставщиками OpenID Connect, у вас не всегда есть выбор между областями или именами заявок.
Я чувствую, что Нат Сакимура избегает этого в видео FAQ OpenID Connect, https://www.youtube.com/watch?v=Kb56GzQ2pSk (1 минута 40 с), идея о том, что сущность может захотеть раскрыть другую личность для разных клиентов.
С точки зрения реализации, мы добавили таблицу с [identityId, clientId, attributeName, attributeValue], чтобы позволить нам хранить один и тот же атрибут identity для разных клиентов. В нашем случае эти атрибуты идентичности становятся утверждениями в исходящем JWT. Поскольку большинство атрибутов пользователя являются глобальными (то есть не специфичными для клиента), мы рассматриваем данные в этой таблице как переопределения базового набора, что позволяет без необходимости дублировать одни и те же данные для каждого клиента. Метод iUserService.GetProfileDataAsync() имеет доступ к клиенту, поэтому может настраивать его ответ в зависимости от потребителя данных.