我在哪里设置MVC.NET的AuthorizeServices中的角色?

时间:2009-09-14 00:16:32

标签: asp.net-mvc asp.net-membership openid authorization

我不知道自己错过了什么,而且我不知道还有什么要读,以使它正确。我将尝试这个灰色问题,看看我是否更接近解决方案。我正在构建一个.NET MVC应用程序。

此应用程序使用DotNetOpenAuth库使用OpenID进行身份验证,所有这些都正常工作。一旦用户进行身份验证,我就会在数据库中对openid令牌进行反叛,并创建调用表单身份验证,如下所示。

            FormsAuthentication.SetAuthCookie(confirmedUser.OpenID, false);

之后,此用户在我的代码中传递所有authorize属性。如下所示:

    [Authorize]
    public ActionResult About()
    {
        return View();
    }

我不知道在哪里为特定用户设置角色。我没有使用会员服务。

我需要使用以下属性:

    [Authorize(Roles="Administrator")]
    public ActionResult About()
    {
        return View();
    }

2 个答案:

答案 0 :(得分:7)

首先,不使用会员提供商对您有好处。这对OpenID不起作用。

要使角色在没有成员资格提供程序的情况下工作,您需要实现自己的派生自System.Web.Security.RoleProvider的类。它完全脱离了身份验证,这使您很容易。您只需要在数据库中为每个用户存储它们所属的角色,然后您的RoleProvider就会与该数据库进行交互。

编写角色提供程序类后,请在web.config文件中将其与此联系起来。此代码段应显示在system.web部分。

<roleManager enabled="true" defaultProvider="Database">
    <providers>
        <add name="Database" type="MyRoleProvider" />
    </providers>
</roleManager>

这是我为OpenID Web应用程序编写的一个角色提供程序。它是使用Linq to Entities编写的,但您可以了解并实现它以对抗您的数据库。

public class MyRoleProvider : RoleProvider {
    public override string ApplicationName {
        get { throw new NotImplementedException(); }
        set { throw new NotImplementedException(); }
    }

    public override void AddUsersToRoles(string[] usernames, string[] roleNames) {
        var users = from token in Global.DataContext.AuthenticationToken
                    where usernames.Contains(token.ClaimedIdentifier)
                    select token.User;
        var roles = from role in Global.DataContext.Role
                    where roleNames.Contains(role.Name, StringComparer.OrdinalIgnoreCase)
                    select role;
        foreach (User user in users) {
            foreach (Role role in roles) {
                user.Roles.Add(role);
            }
        }
    }

    public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) {
        var users = from token in Global.DataContext.AuthenticationToken
                    where usernames.Contains(token.ClaimedIdentifier)
                    select token.User;
        var roles = from role in Global.DataContext.Role
                    where roleNames.Contains(role.Name, StringComparer.OrdinalIgnoreCase)
                    select role;
        foreach (User user in users) {
            foreach (Role role in roles) {
                user.Roles.Remove(role);
            }
        }
    }

    public override void CreateRole(string roleName) {
        Global.DataContext.AddToRole(new Role { Name = roleName });
    }

    /// <summary>
    /// Removes a role from the data source for the configured applicationName.
    /// </summary>
    /// <param name="roleName">The name of the role to delete.</param>
    /// <param name="throwOnPopulatedRole">If true, throw an exception if <paramref name="roleName"/> has one or more members and do not delete <paramref name="roleName"/>.</param>
    /// <returns>
    /// true if the role was successfully deleted; otherwise, false.
    /// </returns>
    public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) {
        Role role = Global.DataContext.Role.SingleOrDefault(r => r.Name == roleName);
        if (role == null) {
            return false;
        }

        if (throwOnPopulatedRole && role.Users.Count > 0) {
            throw new InvalidOperationException();
        }

        Global.DataContext.DeleteObject(roleName);
        return true;
    }

    /// <summary>
    /// Gets an array of user names in a role where the user name contains the specified user name to match.
    /// </summary>
    /// <param name="roleName">The role to search in.</param>
    /// <param name="usernameToMatch">The user name to search for.</param>
    /// <returns>
    /// A string array containing the names of all the users where the user name matches <paramref name="usernameToMatch"/> and the user is a member of the specified role.
    /// </returns>
    public override string[] FindUsersInRole(string roleName, string usernameToMatch) {
        return (from role in Global.DataContext.Role
                where role.Name == roleName
                from user in role.Users
                from authTokens in user.AuthenticationTokens
                where authTokens.ClaimedIdentifier == usernameToMatch
                select authTokens.ClaimedIdentifier).ToArray();
    }

    public override string[] GetAllRoles() {
        return Global.DataContext.Role.Select(role => role.Name).ToArray();
    }

    public override string[] GetRolesForUser(string username) {
        return (from authToken in Global.DataContext.AuthenticationToken
                where authToken.ClaimedIdentifier == username
                from role in authToken.User.Roles
                select role.Name).ToArray();
    }

    public override string[] GetUsersInRole(string roleName) {
        return (from role in Global.DataContext.Role
                where string.Equals(role.Name, roleName, StringComparison.OrdinalIgnoreCase)
                from user in role.Users
                from token in user.AuthenticationTokens
                select token.ClaimedIdentifier).ToArray();
    }

    public override bool IsUserInRole(string username, string roleName) {
        Role role = Global.DataContext.Role.SingleOrDefault(r => string.Equals(r.Name, roleName, StringComparison.OrdinalIgnoreCase));
        if (role != null) {
            return role.Users.Any(user => user.AuthenticationTokens.Any(token => token.ClaimedIdentifier == username));
        }

        return false;
    }

    public override bool RoleExists(string roleName) {
        return Global.DataContext.Role.Any(role => string.Equals(role.Name, roleName, StringComparison.OrdinalIgnoreCase));
    }
}

答案 1 :(得分:0)

我还在学习这些东西,但你可能需要创建一个自定义授权属性。检查this