Я создал STS, который выполняет часть аутентификации. Он использует поставщика пользовательских членства. После успешного входа я перенаправляюсь на свой сайт RP. Все работает отлично с точки зрения аутентификации.Использование настраиваемого RoleProvider с Windows Identity Foundation - STS
Я определил CustomRolesProvider, определенный в web.config моего сайта RP. Он использует имя пользователя, возвращаемое STS, для извлечения ролей этого пользователя из базы данных RP. Когда я использую Roles.GetRolesForUser, я получаю правильные роли.
У меня есть следующее в web.config моего RP, чтобы разрешить только администратору предоставлять доступ к папке администратора.
И провайдер карты сайта имеет securityTrimmingEnabled = «истинный»
<location path="admin">
<system.web>
<authorization>
<allow roles="admin" />
<deny users="*" />
</authorization>
</system.web>
</location>
<add name="default" type="System.Web.XmlSiteMapProvider" siteMapFile="Web.sitemap" securityTrimmingEnabled="true" />
Проблема: Когда пользователь находится в роли администратора, вкладки меню для администратора страниц не showup. Я проверил, что Roles.IsUserInRole («admin») возвращает true. Таким образом, роль распознается поставщиком ролей, но не правилами авторизации и поставщиком Sitemap в web.config.
Если я прокомментирую «местоположение» из web.config, то есть разрешая каждому зарегистрированному пользователю доступ к папке администратора, мои пункты меню отображаются в порядке.
Из моего понимания WIF, RP может иметь собственную реализацию Ролей и не должен полагаться на Требование Роли от STS.
У кого-нибудь есть идеи?
Обновление 2 (01/20/2012): я обнаружил, что СТС возвращает роль утверждает, как показано ниже:
http://schemas.microsoft.com/ws/2008/06/identity/claims/role = Manager
Так что если я изменить <allow roles="admin" /> to <allow roles="Manager" />
роль подобран и вкладки меню показаны соответственно ,
Так что я уверен, что мне не хватает ссылки о том, как использовать мои роли, а не тот, который возвращается через претензии.
Update 2 (01/20/2012): Если добавить роль в claimsIdentity, как показано ниже это работает:
void Application_AuthenticateRequest(object sender, EventArgs e) {
if (Request.IsAuthenticated) {
IClaimsPrincipal claimsPrincipal = HttpContext.Current.User as IClaimsPrincipal;
IClaimsIdentity claimsIdentity = (IClaimsIdentity)claimsPrincipal.Identity;
if (!claimsIdentity.Claims.Exists(c => c.ClaimType == ClaimTypes.Role))
{
claimsIdentity.Claims.Add(new Claim(ClaimTypes.Role, "admin"));
}
}
}
Но то, что было бы лучшее место, чтобы добавить этот код? Если я добавлю его в Application_AuthenticateRequest, он добавляется по каждому запросу и продолжает добавлять. (я это исправил, добавив, если заявление)
* Update 3 (01/24/2012): * Version 2 моего кода, который использует мой CustomRoleProvider, чтобы получить роли, а затем добавить его в ClaimsCollection:
void Application_AuthenticateRequest(object sender, EventArgs e) {
if (Request.IsAuthenticated) {
string[] roleListArray = Roles.GetRolesForUser(User.Identity.Name);
IClaimsPrincipal claimsPrincipal = HttpContext.Current.User as IClaimsPrincipal;
IClaimsIdentity claimsIdentity = (IClaimsIdentity)claimsPrincipal.Identity;
var roleclaims = claimsIdentity.Claims.FindAll(c => c.ClaimType == ClaimTypes.Role);
foreach (Claim item in roleclaims)
{
claimsIdentity.Claims.Remove(item);
}
foreach(string role in roleListArray)
{
claimsIdentity.Claims.Add(new Claim(ClaimTypes.Role, role));
}
HttpContext.Current.User = claimsPrincipal;
}
Но я не уверен, что это правильный путь.
Есть ли кто-нибудь, кто сделал что-то подобное?
Обновление 4 (01/26/2012): Обнаружено, что я могу использовать Custom ClaimsAuthencationManager (Шаг 4), чтобы преобразовать свои претензии. Я переместил код в методе AuthenticateRequest в метод Global.asax для проверки подлинности в классе ClaimsAuthenticationManager.
Я сомневаюсь, что это может стать лучше, чем это. Я отправлю свое решение в качестве ответа. Но все же, если у кого-то есть другое лучшее решение, не стесняйтесь комментировать.
Проблема в том, что роли добавляются конкретным RP.Другим решением было бы добавить их в пользовательскую STS, но тогда ваш пользовательский STS должен был бы получить доступ к этой информации. Это было бы лучшим решением, если бы более одной RP необходимо было знать эту информацию о роли. – Kaido
В зависимости от ситуации наличие ролей, известных STS, может быть неправильным. Например, если вы используете Google или MSN в качестве STS, должны ли Google и MSN знать о ролях вашего RP? Кроме того, если вы используете ADFS внутри домена Active Directory, вам может потребоваться предоставить ADFS роль пользователя. Роли могут поступать от групп AD или базы данных aspnet. –
@Phil: Спасибо, я посмотрю на событие SecurityTokenValidated и попробую в одном из моих RP. Роли в другом RP обновляются на основе того, какой пользователь клиент-программа выбирает. Поэтому в этом случае мне придется проверять их по каждому запросу. – gbs