C#LDAP AD身份验证,使用职务标题进行授权

时间:2018-05-28 21:31:42

标签: c# asp.net-mvc active-directory ldap userprincipal

我看过许多关于如何使用基于角色的授权的在线文章和示例代码,但无法找到与基于标题的授权相关的任何内容。

我在AD认证课程中有以下内容:

 protected ClaimsIdentity CreateIdentity(UserPrincipalExtended userPrincipal)
    {
        var identity = new ClaimsIdentity(MyAuthentication.ApplicationCookie, ClaimsIdentity.DefaultNameClaimType,
            ClaimsIdentity.DefaultRoleClaimType);
        identity.AddClaim(new Claim(
            "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider",
            "Active Directory"));
        identity.AddClaim(new Claim(ClaimTypes.Name, userPrincipal.Name));
        identity.AddClaim(new Claim(ClaimTypes.GivenName, userPrincipal.GivenName ?? string.Empty));
        identity.AddClaim(new Claim(ClaimTypes.Surname, userPrincipal.Surname ?? string.Empty));
        identity.AddClaim(new Claim(userPrincipal.Title, userPrincipal.Title ?? string.Empty));
        identity.AddClaim(new Claim(userPrincipal.Department, userPrincipal.Department ?? string.Empty));
        identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userPrincipal.SamAccountName));
        if (!string.IsNullOrEmpty(userPrincipal.EmailAddress))
            identity.AddClaim(new Claim(ClaimTypes.Email, userPrincipal.EmailAddress));

        var claims = new List<Claim>();
        var dirEntry = (DirectoryEntry) userPrincipal.GetUnderlyingObject();
        foreach (string groupDN in dirEntry.Properties["memberOf"])
        {
            var parts = groupDN.Replace("CN=", "").Split(',');
            claims.Add(new Claim(ClaimTypes.Role, parts[0]));
        }


        if (claims.Count > 0)
            identity.AddClaims(claims);


        var title = dirEntry.Properties["title"].Value.ToString();
        return identity;
    }

这很好用,我可以看到从Active Directory中检索到的正确标题和部门。显然我使用的是扩展的UserPrincipal,因为标题和部门不是标准UserPrincipal的一部分。

我的问题是我无法将标题和部门值传递给我的Controller for Authorization。

在HomeController中,我使用以下命令获取经过身份验证的用户的信息:

var firstname = System.Web.HttpContext.Current.User.GetFirstname();
var lastname = System.Web.HttpContext.Current.User.GetLastname();
var email = System.Web.HttpContext.Current.User.GetEmail();
var uid = System.Web.HttpContext.Current.User.GetUserID();

显然,这使用的标准IPrincipal不包含标题和部门的规定。

有没有一种简单的方法可以将标题和部门参数传递给控制器​​?是否可以使用标题来授权访问而不是角色?

提前致谢

1 个答案:

答案 0 :(得分:1)

我遇到了类似的挑战,并通过使用(在您的情况下)标题和部门作为角色来解决它。 这允许使用所有开箱即用的基于角色的授权功能。

if (userPrinciple.Title != null)
{
    identity.AddClaim(new Claim(ClaimTypes.Role, userPrincipal.Title));
}

if (userPrincipal.Department != null)
{
    identity.AddClaim(new Claim(ClaimTypes.Role, userPrincipal.Department));
}

如果角色是特定于部门的,则可以将两者结合使用。

identity.AddClaim(new Claim(ClaimTypes.Role, $"{userPrincipal.Department}.{userPrincipal.Title}));