将自定义RoleProvider与Windows Identity Foundation-STS一起使用 [英] Using Custom RoleProvider with Windows Identity Foundation - STS

查看:73
本文介绍了将自定义RoleProvider与Windows Identity Foundation-STS一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了负责身份验证部分的STS.它使用自定义成员资格提供程序. 成功登录后,我将重定向到我的RP网站.一切都在身份验证方面工作正常.

I created STS that does the authentication part. It uses Custom Membership provider. After successful login I get redirected to my RP website. All works fine in terms of authentication.

我已经在RP网站的web.config中定义了CustomRolesProvider.它使用STS返回的用户名从RP的数据库中获取该用户的角色. 当我使用Roles.GetRolesForUser时,我确实获得了正确的角色.

I have defined a CustomRolesProvider defined in web.config of my RP website. It uses the username returned by STS to fetch the roles for that user from RP's database. When I use Roles.GetRolesForUser I do get the right roles.

我在RP的web.config中具有以下内容,以仅允许admin授予对admin文件夹的访问权限.

I have the following in the web.config of my RP to allow only admin to give access to admin folder.

并且站点地图提供程序具有securityTrimmingEnabled ="true"

And the sitemap provider has 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中的授权规则和站点地图提供者不能识别角色.

Problem: When the user is in the admin role, the menu tabs for admin pages won't showup. I did check that Roles.IsUserInRole("admin") returns true. So the role is recognized by roles provider but not by authorization rules and sitemap provider in the web.config.

如果我从web.config中注释掉位置",即允许每个登录用户访问admin文件夹,则我的菜单项会显示正常.

If I comment out the "location" from the web.config i.e. allowing every logged-in user to admin folder, my menu items show up fine.

根据我对WIF的理解,RP可以拥有自己的Roles实现,而不必依赖STS的Roles Claim.

From my understanding of WIF, RP can have it's own implementation of Roles and does not have to rely on Roles Claim from STS.

有人有什么想法吗?

更新2(2012年1月20日)::我发现STS返回的角色声明如下:

Update 2(01/20/2012): I found that the STS returns role claims as below:

http://schemas.microsoft.com/ws/2008/06/identity/claims/role = Manager

因此,如果我更改<allow roles="admin" /> to <allow roles="Manager" />,则将选择该角色,并正确显示菜单选项卡.

So if I change <allow roles="admin" /> to <allow roles="Manager" /> the role is picked up and menu tabs are shown appropriately.

因此,我确定我缺少有关如何利用我的角色的链接,而不是通过声明返回的链接.

So I am sure I am missing a link on how to make use of my roles and not the one returned via claims.

更新2(2012年1月20日): 如果我将角色添加到ClaimsIdentity中,如下所示:

Update 2(01/20/2012): If I add the role to the claimsIdentity like below it works:

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语句来解决此问题)

But then what would be the best place to add that code? If I add it in Application_AuthenticateRequest it's added upon each request and it keeps adding.(I fixed this by adding if statement)

* 更新3(01/24/2012): *我的代码的版本2使用我的CustomRoleProvider获取角色,然后将其添加到ClaimsCollection:

*Update 3(01/24/2012):*Version 2 of my code that uses my CustomRoleProvider to get the Roles and then add it to the 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;
    }

但是我不确定这是否正确.

But I am not sure if that's the right way.

有没有做过这样的事情的人?

Is there anyone who has done something like this??

更新4(2012年1月26日):发现我可以使用自定义ClaimsAuthencationManager (第4步)来转换我的声明. 我将Global.asax中AuthenticateRequest方法中的代码移到ClaimsAuthenticationManager类中的Authenticate方法中.

Update 4 (01/26/2012): Found that I can use Custom ClaimsAuthencationManager(Step 4) to transform my claims. I moved the code in AuthenticateRequest method in Global.asax to Authenticate method in ClaimsAuthenticationManager class.

我怀疑它会比这更好.我将发布我的解决方案作为答案.但是,如果还有其他更好的解决方案,请随时发表评论.

I doubt it can get any better than this. I will post my solution as answer. But still if anyone has any other better solution feel free to comment.

推荐答案

您可以使用自定义的ClaimsAuthencationManager,但是,它将在每次请求时调用.我的建议是使用 WSFederationAuthenticationModule.SecurityTokenValidated .使用SecurityTokenValidatedEventArgs类的ClaimsPrincipal属性,并使用提供程序添加角色.另外,您可能希望考虑使用 ClaimsIdentity.RoleClaimType .

You could use a custom ClaimsAuthencationManager, however, it will be called on every request. My recommendation would be to use WSFederationAuthenticationModule.SecurityTokenValidated. Use the ClaimsPrincipal property of SecurityTokenValidatedEventArgs class and add the roles using your provider. Also, instead of hard coding the role claim type, you may wish to consider using ClaimsIdentity.RoleClaimType.

查找到的角色将保存在加密的cookie中(假设您使用的是默认设置).

The looked up roles will be saved in the encrypted cookie (assuming you are using the default).

这篇关于将自定义RoleProvider与Windows Identity Foundation-STS一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆