将角色添加到ADFS IPrincipal

时间:2015-05-08 19:55:07

标签: asp.net-mvc adfs ws-federation

我几天来一直在寻找这个问题的答案,但我没有找到任何成功。我会发布链接,但它可能会占用整个页面。

所以这就是我所拥有的......

我有一个MVC应用程序,它使用WC-Federation协议。我已经能够配置应用程序,以便它对用户进行身份验证,并从ADFS返回声明。这很完美。我也可以提取所有索赔,没有任何问题。但我在控制器中的一个操作中执行此操作。

这就是我想要做的......

我想使用ADFS对用户进行身份验证,但我希望使用自己的内部角色来授权用户访问特定的控制器(例如[Authorize(Roles = "CoolRole")])。我希望能够这样做,因为我已经有一个使用OAuth 2.0的Web API,后端SQL Server数据库来管理用户和角色(内部和外部用户)。我现在想要一个允许内部用户的安全门户通过单点登录体验访问数据。查看Controller模型,我注意到有一些与身份验证过程相关联的属性(OnAuthenticationOnAuthenticationChallenge)和一个与授权过程相关的属性(OnAuthorization。)

我不一定需要代码,但我觉得我已经打了一个砖头,我需要指向正确的方向。

更新

我试过了:

protected override void OnAuthorization(
       System.Web.Mvc.AuthorizationContext filterContext)
{
    //Private class to create a new IPrincipal based on my AppUserMgr
    var user =  _setCurrentUser(
                  (ClaimsIdentity)filterContext.HttpContext.User.Identity);
    filterContext.HttpContext.User = user;

    base.OnAuthorization(filterContext);
}

这返回了401(未经授权)的回复。

和...

protected override void OnAuthentication(
    System.Web.Mvc.Filters.AuthenticationContext filterContext)
{
    //Private class to create a new IPrincipal based on my AppUserMgr
    var user =  _setCurrentUser(
                  (ClaimsIdentity)filterContext.HttpContext.User.Identity);
    filterContext.Principal = user;

    base.OnAuthorization(filterContext);
}

这只是在STS失败之前多次调用STS。我甚至尝试在分配之后交换到两者之后调用基数。没有运气。

在之前的版本之前,我还尝试向控件添加AuthorizeFilter,但这没有帮助:

http://pratapreddypilaka.blogspot.in/2012/03/custom-filters-in-mvc-authorization.html

2 个答案:

答案 0 :(得分:4)

找到答案,YESSS !!!

所以,我找到了这个链接:http://brockallen.com/2013/01/17/adding-custom-roles-to-windows-roles-in-asp-net-using-claims/

从那里,我猜到了我的方式,好吧:)

以下是我所做的基本知识:

我最终覆盖了Controller的OnAuthentication方法,但仍然确保调用了base。我是在扩展课程中完成的。这是概念:

public class AdfsController : Controller
{
    //Some code for adding the AppUserManager (used Unity)
    protected override void OnAuthentication(
            System.Web.Mvc.Filters.AuthenticationContext filterContext)
    {
        base.OnAuthentication(filterContext);
        //Private method to set the Principal
        _setCurrentUser(filterContext.Principal);
    }

    private void _setCurrentUser(IPrincipal principal)
    {
        //Put code to find to use your ApplicationUserManager or 
        //dbContext.  roles is a string array

        foreach(var role in roles)
        {
            ((ClaimsIdentity)((ClaimsPrincipal)principal).Identity)
                .AddClaim(new Claim(ClaimTypes.Role, role));
        }
    }
}

在Controller中,您现在可以添加以下内容:

public class HomeController : AdfsController
{
    //I used a magic string for demo, but store these in my globals class
    [Authorize(Roles = "CoolRole")]
    public ActionResult Index()
    {
        return View();
    }
}

我通过检查分配给当前用户的角色对此进行了测试,这是有效的!然后我将角色更改为"拒绝",用户未分配;我收到了401 Unauthorized。所以,是的,非常酷!

我知道我就是那个问过这个问题的人,但希望有人觉得这很有帮助并节省了一些时间。

〜干杯!

答案 1 :(得分:-3)

ADFS是Azure中的身份验证/令牌服务。要启用基于角色的身份验证,您可以使用Azure RBAC(基于角色的访问控制)服务来基本增加从ADFS返回的声明,并将从RBAC返回的角色添加到令牌,并使用相同的令牌在您的API中使用该扩充令牌锁定或保护后端... 这是RBAC的参考:

http://azure.microsoft.com/en-in/documentation/articles/role-based-access-control-configure/