Я создал STS, который выполняет аутентификацию.Он использует пользовательское членство провайдера.После успешного входа в систему меня перенаправляют на мой сайт RP.Все работает нормально с точки зрения аутентификации.
Я определил CustomRolesProvider, определенный в web.config моего сайта RP.Он использует имя пользователя, возвращаемое STS, чтобы получить роли для этого пользователя из базы данных RP.Когда я использую Roles.GetRolesForUser, я получаю правильные роли.
У меня есть следующее в web.config моего RP, чтобы позволить только администратору предоставлять доступ к папке администратора.
А у провайдера карты сайта есть securityTrimmingEnabled = "true"
<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" />
Проблема: Когда пользователь в роли администратора, вкладки меню для страниц администратора выиграли 'т показ.Я проверил, что Roles.IsUserInRole ("admin") возвращает true.Таким образом, роль распознается поставщиком ролей, а не правилами авторизации и поставщиком карты сайта в файле web.config.
Если я закомментирую «местоположение» из файла web.config, то есть разрешив каждому вошедшему в систему пользователю администраторпапка, мои пункты меню отображаются нормально.
Исходя из моего понимания WIF, RP может иметь собственную реализацию ролей и не должен полагаться на утверждение ролей из STS.
Кто-нибудь имеетесть идеи?
Обновление 2 (20.01.2012): Я обнаружил, что STS возвращает заявки о ролях, как показано ниже:
http://schemas.microsoft.com/ws/2008/06/identity/claims/role = Manager
Так что, если я изменюсь <allow roles="admin" /> to <allow roles="Manager" />
роль выбрана и вкладки меню отображаются соответствующим образом.
Поэтому я уверен, что мне не хватает ссылки о том, как использовать мои роли, а не ссылки, возвращенной с помощью утверждений.
Обновление 2 (20.01.2012): Если я добавлю роль к заявке, как показано ниже, она будет работать:
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, он добавляется при каждом запросе и продолжает добавляться. (я исправил это, добавив оператор if)
* Update 3 (24.01.2012): * Версия 2 моего кода, который использует мой CustomRoleProvider для получения ролей и добавления его в коллекцию ClaimsCol:
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;
}
Но я не уверен, что это правильноway.
Есть ли кто-нибудь, кто сделал что-то подобное ??
Обновление 4 (26.01.2012): Обнаружил, что могу использовать CustomClaimsAuthencationManager (шаг 4) для преобразования моих утверждений.Я переместил код в метод AuthenticateRequest в Global.asax в метод Authenticate в классе ClaimsAuthenticationManager.
Я сомневаюсь, что это может быть лучше, чем это.Я опубликую свое решение как ответ.Но все же, если у кого-то есть какое-либо иное лучшее решение, не стесняйтесь комментировать.