Asp.net mvc Asp mvc 4成员资格和网站安全

Asp.net mvc Asp mvc 4成员资格和网站安全,asp.net-mvc,asp.net-mvc-4,asp.net-membership,simplemembership,Asp.net Mvc,Asp.net Mvc 4,Asp.net Membership,Simplemembership,我需要一个关于做什么的建议。我目前正在使用WebSecurity方法来完成所有与帐户相关的工作。但是,它不支持电子邮件唯一性验证,因此我有几个选项: 写入(子类)一个新的SimpleMembershipProvider,覆盖现有的createuserAndAccount方法以验证电子邮件地址。但我还必须实现登录注销功能(就像websecurity一样)和其他一些功能 在数据库上添加唯一性约束,并在我的代码中捕捉它们。但是,这将导致我依赖于数据库 这可能有点便宜,但我可以在一个新类上复制/粘贴We

我需要一个关于做什么的建议。我目前正在使用WebSecurity方法来完成所有与帐户相关的工作。但是,它不支持电子邮件唯一性验证,因此我有几个选项:

  • 写入(子类)一个新的SimpleMembershipProvider,覆盖现有的createuserAndAccount方法以验证电子邮件地址。但我还必须实现登录注销功能(就像websecurity一样)和其他一些功能

  • 在数据库上添加唯一性约束,并在我的代码中捕捉它们。但是,这将导致我依赖于数据库

  • 这可能有点便宜,但我可以在一个新类上复制/粘贴WebSecurity源代码(因为它是开放的),并修改createUserAndAccount方法

  • 还有其他选择吗?目前我的目标是选择3,这将是最快的方式。 另一方面,将来我也需要角色,我不确定WebSecurity是否为它们提供支持。

    使用选项一 1.您的自定义成员资格是否继承自ExtendedMemberShipprovider
    AccountMembershipProvider:ExtendedMemberShipprovider

  • 用户为单元可测试性提供Web安全性包装 范例

    公共类WebSecurity说话者:IWebSecurity

    {

  • 在这里,您可以添加您的电子邮件更改您想要的任何方法

  • 在web.config中将您的成员资格提供程序注册为默认提供程序

  • 如果是我,我可能会这样做:

    首先,假设您将SimpleMembership与实体框架或某种数据库连接(ADO、LINQ到SQL等)一起使用您将有两个组件:
    WebSecurity.*
    方法调用和数据库连接以进行配置文件更改。就个人而言,我会将
    约束添加到数据库中以确保您的数据是纯的,但您也可以实现处理此逻辑的成员资格服务

    首先,将它们分组到一个可在控制器中引用的接口中(如下所示):

    然后您可以将该服务实现为SimpleMembership和数据库连接的混合体。为了保持通用性,我使用了
    IRepository
    模式,但这可能是直接的
    DbContext
    ObjectContext
    ,等等。我也保持了它的简洁性,因此请原谅缺少校验和和简短的实现

    public class MembershipService : IMembershipService
    {
        protected readonly SimpleMembershipProvider membershiProvider;
        protected readonly SimpleRoleProvider roleProvider;
        protected readonly IRepository<UserProfile> profileRepository;
    
        public MembershipService(IRepository<UserProfile> profileRepository)
        {
            this.membershipProvider = Membership.Provider as SimpleMembershipProvider;
            this.roleProvider = Role.Provider as SimpleRoleProvider;
            this.profileRepository = userRepository;
        }
    
        #region IMembershipService Implementation
    
        public Int32 CurrentUserId
        {
            get { return WebSecurity.CurrentUserId; }
        }
        public String CurrentUserName
        {
            get { return WebSecurity.CurrentUserName; }
        }
        public Boolean IsAuthenticated
        {
            get { return WebSecurity.IsAuthenticated; }
        }
    
        public Boolean CreateUserAndAccount(String username, String password, String emailaddress = null)
        {
            // validate the email address is unique
            if (!this.profileRepository.Any(x => x.EmailAddress == emailaddress))
            {
                WebSecurity.CreateUserAndAccount(username, password, new
                {
                    EmailAddress = emailaddress
                }, createConfirmationToken);
                return true;
            }
            else
            {
                // handle the error how you see fit
                // (maybe even exception?)
                return false;
            }
        }
        public Boolean CreateUserAndAccount(String username, String password, out String confirmationToken, String emailaddress = null, out)
        {
            // validate the email address is unique
            if (this.profileRepository.First(x => x.EmailAddress == emailaddress) == null)
            {
                confirmationToken = WebSecurity.CreateUserAndAccount(username, password, new
                {
                    EmailAddress = emailaddress
                }, createConfirmationToken);
                return true;
            }
            else
            {
                // handle the error how you see fit
                // (maybe even exception?)
                confirmationToken = String.Empty;
                return false;
            }
        }
        public Boolean Login(String username, String password, Boolean persistCookie = false)
        {
            return WebSecurity.Login(username, password, persistCookie);
        }
        public void Logout()
        {
            WebSecurity.Logout();
        }
    
        #endregion
    }
    

    如果您使用的是EntityFramework,还可以使用。为了避免重复,这里有另一个SO问题/答案,用于检查唯一条目:


    我同意创建一个界面,但您可以轻松地在实现中实现独特的电子邮件约束。但我也坚信,这种约束应该在数据库级别进行,并引导到web项目中。好吧,这是一个验证问题。我将提前验证,正如您所说,也要进行验证db-side too实现ExtendedMembershipProvider只需要一个额外的功能就需要做太多的工作,因为我必须实现所有的方法,而扩展SimpleMembershipProvider时,我可以重写register方法,这不是很容易吗?我也可以在这个新类中添加login/logout方法。为什么需要实现整个ExtenderMembershipProvider?我扩展了ExtendedMembershipProvider,只实现了我需要的东西。这是一个非常好的解决方案。太棒了,很高兴我能提供帮助。如果是新数据库,另一个选择是使用电子邮件作为用户名。默认情况下,用户名是唯一的。
        public bool Login(string userName, string password, bool rememberMe)
        {
            return WebSecurity.Login(userName, password, rememberMe);
        }
    
    
        public bool ChangePassword(string userName, string currentPassword, string newPassword)
        {
            return WebSecurity.ChangePassword(userName, currentPassword, newPassword);
        }
    
        public void LogOut()
        {
            WebSecurity.Logout();
        }
    }
    
    public interface IMembershipService
    {
        Int32 CurrentUserId { get; }
        String CurrentUserName { get; }
        Boolean IsAuthenticated { get; }
    
        Boolean CreateUserAndAccount(String username, String password, String emailaddress = null);
        Boolean CreateUserAndAccount(String username, string password, out String confirmationToken, String emailaddress = null);
        Boolean Login(String username, String password, Boolean persistCookie = false);
        void Logout();
    }
    
    public class MembershipService : IMembershipService
    {
        protected readonly SimpleMembershipProvider membershiProvider;
        protected readonly SimpleRoleProvider roleProvider;
        protected readonly IRepository<UserProfile> profileRepository;
    
        public MembershipService(IRepository<UserProfile> profileRepository)
        {
            this.membershipProvider = Membership.Provider as SimpleMembershipProvider;
            this.roleProvider = Role.Provider as SimpleRoleProvider;
            this.profileRepository = userRepository;
        }
    
        #region IMembershipService Implementation
    
        public Int32 CurrentUserId
        {
            get { return WebSecurity.CurrentUserId; }
        }
        public String CurrentUserName
        {
            get { return WebSecurity.CurrentUserName; }
        }
        public Boolean IsAuthenticated
        {
            get { return WebSecurity.IsAuthenticated; }
        }
    
        public Boolean CreateUserAndAccount(String username, String password, String emailaddress = null)
        {
            // validate the email address is unique
            if (!this.profileRepository.Any(x => x.EmailAddress == emailaddress))
            {
                WebSecurity.CreateUserAndAccount(username, password, new
                {
                    EmailAddress = emailaddress
                }, createConfirmationToken);
                return true;
            }
            else
            {
                // handle the error how you see fit
                // (maybe even exception?)
                return false;
            }
        }
        public Boolean CreateUserAndAccount(String username, String password, out String confirmationToken, String emailaddress = null, out)
        {
            // validate the email address is unique
            if (this.profileRepository.First(x => x.EmailAddress == emailaddress) == null)
            {
                confirmationToken = WebSecurity.CreateUserAndAccount(username, password, new
                {
                    EmailAddress = emailaddress
                }, createConfirmationToken);
                return true;
            }
            else
            {
                // handle the error how you see fit
                // (maybe even exception?)
                confirmationToken = String.Empty;
                return false;
            }
        }
        public Boolean Login(String username, String password, Boolean persistCookie = false)
        {
            return WebSecurity.Login(username, password, persistCookie);
        }
        public void Logout()
        {
            WebSecurity.Logout();
        }
    
        #endregion
    }
    
    public class AccountController: Controller
    {
        private readonly IMembershipService membershipService;
    
        public AccountController(IMembershipService membershipService)
        {
            this.membershipService = membershipService;
        }
    
        /* ... */
    
        [HttpPost, ValidateAntiForgeryToken]
        public ActionResult Register(LoginViewModel model, String returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (this.membershipService.CreateUserandAccount(model.Username, model.Password, model.EmailAddress))
                {
                    this.membershipService.Login(model.Username, model.Password);
                    if (!String.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    return RedirectToRoute("Default");
                }
                else
                {
                    ModelState.AddModelError("", "Unable to register.");
                }
            }
            return View(model);
        }
    
        /* ... */
    }