0

我正在开发一个 MVC4 应用程序,该应用程序在启动应用程序之前由 ADFS 完成了身份验证,并且只会由成功通过身份验证的用户启动。在应用程序本身中,我有一个包含在以下类中的用户列表:

public class MyAppUser : IPrincipal
{
    [Key]
    public int UserID { get; set; }

    [StringLength(128)]
    public string Username { get; set; }              

    public int ParticipationPoints { get; set; }

    public DateTime JoinDate { get; set; }

    public DateTime LastLogin { get; set; }

    //1-to-1 Mappings
    public int? CompanyID { get; set; }
    public virtual Company Company { get; set; }

    public int? ProfileID { get; set; }
    public virtual Profile Profile { get; set; }

    public int? SocialID { get; set; }
    public virtual SocialMedia Social { get; set; }

    public int? RoleID { get; set; }
    public virtual Role Role { get; set; }

    //1-to-many Mappings
    public virtual ICollection<Block> Blocks { get; set; }

    public virtual ICollection<Enrollment> Enrollments { get; set; }

    public virtual ICollection<CategoryMap> CategoryMaps { get; set; }

    public virtual ICollection<Feedback> Feedbacks { get; set; }

    public virtual ICollection<Survey> Surveys { get; set; }

    public virtual ICollection<Friend> Friends { get; set; }

    public virtual ICollection<Participation> Participations { get; set; }

    public virtual ICollection<Post> Posts { get; set; }

    public virtual ICollection<Target> Targets { get; set; }

    public virtual ICollection<CourseStatus> CourseStatuses { get; set; }

    public virtual ICollection<Objective> Objectives { get; set; }

    public virtual ICollection<UserCourseInfo> UserCourseInfos { get; set; }

    public IIdentity Identity { get; set; }

    public bool IsInRole(string role)
    {
        if (this.Role.Name == role)
        {
            return true;
        }
        return false;
    }
}

我创建了一个与我的 dbcontext 绑定的自定义角色提供程序,如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration.Provider;
using MyApp.Data;
using MyApp.ViewModels;

namespace MyApp.Providers
{
  public class MyAppProvider : System.Web.Security.SqlRoleProvider
  {
    private MyAppContext dbcontext = new MyAppContext(System.Configuration.ConfigurationManager.ConnectionStrings["MyAppContext"].ConnectionString);
    private Repository<MyAppUser> userRepository;
    private Repository<Role> roleRepository;

    public MyAppProvider()
    {
        this.userRepository = new Repository<MyAppUser>(dbcontext);
        this.roleRepository = new Repository<Role>(dbcontext);
    }

    public override string[] GetAllRoles()
    {
        IEnumerable<Role> dbRoles = roleRepository.GetAll();
        int dbRolesCount = roleRepository.GetAll().Count();
        string[] roles = new string[dbRolesCount];
        int i = 0;
        foreach(var role in dbRoles)
        {
            roles[i] = role.Name;
            i++;
        }
        return roles;
    }

    public string[] GetAllUsers()
    {
        IEnumerable<MyAppUser> dbUsers = userRepository.GetAll();
        int dbUsersCount = userRepository.GetAll().Count();
        string[] users = new string[dbUsersCount];
        int i = 0;
        foreach (var user in dbUsers)
        {
            users[i] = user.Username;
            i++;
        }
        return users;
    }

    public override bool RoleExists(string roleName)
    {
        string[] roles = { "Admin", "User", "BobsBusiness" };
        if(roles.Contains(roleName))
            return true;
        else
            return false;
    }

    public override void CreateRole(string roleName)
    {
        Role newRole = new Role();
        newRole.Name = roleName;
        roleRepository.Add(newRole);
        roleRepository.SaveChanges();
    }

    public override void AddUsersToRoles(string[] usernames, string[] roleNames)
    {
        foreach (var username in usernames)
        {
            MyAppUser user = userRepository.Get(u => u.Username == username).FirstOrDefault();

            foreach (var rolename in roleNames)
            {
                Role role = roleRepository.Get(r => r.Name == rolename).FirstOrDefault();
                user.RoleID = role.RoleID;
                userRepository.Add(user);
                userRepository.SaveChanges();
            }

        }
    }

    public override string[] GetRolesForUser(string username)
    {
        MyAppUser user = userRepository.Get(u => u.Username == username).FirstOrDefault();
        if (user == null)
        {
            string[] roles = new string[1];
            roles[0] = "Fail";
            return roles;
        }
        else
        {
            Role role = roleRepository.Get(r => r.RoleID == user.RoleID).FirstOrDefault();
            if (role == null)
            {
                string[] roles = new string[1];
                roles[0] = "Fail";
                return roles;
            }
            else
            {
                string[] roles = new string[1];
                roles[0] = role.Name;
                return roles;
            }
        }

    }

    public override bool IsUserInRole(string userName, string roleName)
    {
        MyAppUser user = userRepository.Get(u => u.Username == userName).FirstOrDefault();
        if (user == null)
          throw new ProviderException("Username cannot be empty or null.");
        Role role = roleRepository.Get(r => r.Name == roleName).FirstOrDefault();
        if (role == null)
          throw new ProviderException("Role name cannot be empty or null.");
        if (user.RoleID == role.RoleID)
            return true;
        else
            return false;
    }
  }
}

现在我尝试创建一个 CustomMembershipProvider,但我不确定如何将它与我创建的 dbcontext 和 MyAppUser 联系起来。由于身份验证类型,我们没有 AccountController,因此 simpleMembership 不是一个选项。我为自定义会员提供者创建了抽象类,如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MyApp.Data;

namespace MyApp.Providers
{
  public class MyAppMembershipProvider : System.Web.Security.MembershipProvider
  {
    private MyAppContext dbcontext = new MyAppContext(System.Configuration.ConfigurationManager.ConnectionStrings["MyAppContext"].ConnectionString);
    private Repository<MyAppUser> userRepository;
    public MyAppUser User { get; private set; }

    public MyAppMembershipProvider()
    {
        this.userRepository = new Repository<MyAppUser>(dbcontext);
        User = userRepository.Get(u => u.Username == "jpmcfeely").FirstOrDefault();
    }

    public override string ApplicationName
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }

    public override bool ChangePassword(string username, string oldPassword, string newPassword)
    {
        throw new NotImplementedException();
    }

    public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
    {
        throw new NotImplementedException();
    }

    public override System.Web.Security.MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out System.Web.Security.MembershipCreateStatus status)
    {
        throw new NotImplementedException();
    }

    public override bool DeleteUser(string username, bool deleteAllRelatedData)
    {
        throw new NotImplementedException();
    }

    public override bool EnablePasswordReset
    {
        get { throw new NotImplementedException(); }
    }

    public override bool EnablePasswordRetrieval
    {
        get { throw new NotImplementedException(); }
    }

    public override System.Web.Security.MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
    {
        throw new NotImplementedException();
    }

    public override System.Web.Security.MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
    {
        throw new NotImplementedException();
    }

    public override System.Web.Security.MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
    {
        throw new NotImplementedException();
    }

    public override int GetNumberOfUsersOnline()
    {
        throw new NotImplementedException();
    }

    public override string GetPassword(string username, string answer)
    {
        throw new NotImplementedException();
    }

    public override System.Web.Security.MembershipUser GetUser(string username, bool userIsOnline)
    {
        //throw new NotImplementedException();
        MyAppUser user = userRepository.Get(u => u.Username == username).FirstOrDefault();
        return GetUser(username, true);
    }

    public override System.Web.Security.MembershipUser GetUser(object providerUserKey, bool userIsOnline)
    {
        throw new NotImplementedException();
    }

    public override string GetUserNameByEmail(string email)
    {
        throw new NotImplementedException();
    }

    public override int MaxInvalidPasswordAttempts
    {
        get { throw new NotImplementedException(); }
    }

    public override int MinRequiredNonAlphanumericCharacters
    {
        get { throw new NotImplementedException(); }
    }

    public override int MinRequiredPasswordLength
    {
        get { throw new NotImplementedException(); }
    }

    public override int PasswordAttemptWindow
    {
        get { throw new NotImplementedException(); }
    }

    public override System.Web.Security.MembershipPasswordFormat PasswordFormat
    {
        get { throw new NotImplementedException(); }
    }

    public override string PasswordStrengthRegularExpression
    {
        get { throw new NotImplementedException(); }
    }

    public override bool RequiresQuestionAndAnswer
    {
        get { throw new NotImplementedException(); }
    }

    public override bool RequiresUniqueEmail
    {
        get { throw new NotImplementedException(); }
    }

    public override string ResetPassword(string username, string answer)
    {
        throw new NotImplementedException();
    }

    public override bool UnlockUser(string userName)
    {
        throw new NotImplementedException();
    }

    public override void UpdateUser(System.Web.Security.MembershipUser user)
    {
        throw new NotImplementedException();
    }

    public override bool ValidateUser(string username, string password)
    {
        throw new NotImplementedException();
    }
  }
}

我将非常感谢任何人在将 MyAppUser 连接到自定义会员提供程序方面的任何提示。

4

2 回答 2

1

假设应用程序通过 ADFS 对用户进行身份验证,则您的角色提供者和成员提供者无关。完全地。ADFS 将身份与角色一起传递给应用程序。

你可以做的是有一个自定义的 ClaimsAuthenticationmanager。前段时间我在博客上写过:

http://netpl.blogspot.com/2012/09/sessionauthenticationmodule-and-dynamic.html

于 2013-09-12T19:16:21.677 回答
0

由于我已经通过 ADFS 的身份验证,因此我在声明中获得了用户名并将其保存在会话变量中。然后,我使用此会话变量通过已覆盖的 GetRolesForUser 方法调用我的数据库用户。效果很好,不用太费力。

于 2013-09-12T21:25:25.813 回答