6

Ne yapacağım konusunda bir öneriye ihtiyacım var. Şu anda hesapla ilgili tüm işleri yapmak için WebGüvenlik yöntemlerini kullanıyorum.Asp mvc 4 Üyelik ve Web Güvenliği

  1. Yaz (alt sınıf) e-posta adresini doğrulamak için mevcut createuserAndAccount yöntemini üzerine yazarak yeni bir SimpleMembershipProvider: Birkaç seçenek var ancak öyle e-mail benzersizliği doğrulamayı desteklemez. Ama aynı zamanda oturum açma özelliklerini (websecurity gibi) ve birkaçını da uygulamak zorundayım.

  2. Veritabanında benzersiz kısıtlamalar ekleyin ve bunları kodumda yakalayın. Ancak bu, DataBase bağımlı olmamı sağladı.

  3. Bu biraz ucuz olabilir, ancak WebSecurity kaynak kodunu (açık olduğundan) yeni bir sınıfta kopyalayıp yapıştırabilir ve createUserAndAccount yöntemini değiştirebilirim.

Başka seçenek var mı? Şu anda 3 seçeneğini hedefliyorum, en hızlı yol olacaktı. Bir yan not, gelecekte de rolleri gerektirecek ve WebSecurity onlar için destek sağlayıp sağlamadığından emin değilim.

+0

, başka bir seçenek, bir kullanıcı adı olarak e-posta kullanmak olacaktır. kullanıcı adı varsayılan olarak benzersizdir. – Igarioshka

cevap

5

varsayılan sağlayıcı olarak üyelik sağlayıcı Kayıt istersen yöntem e-posta değişikliğini ekleyebilir Muhtemelen aşağıdaki yolu izlerim:

İlk olarak, Entity Framework ile SimpleMembership veya bazı tabase bağlantısı (ADO, LINQ to SQL, vs.) iki bileşene sahip olacaksınız: WebSecurity.* yöntem çağrıları ve profil değişiklikleri yapmak için veritabanı bağlantısı. Kişisel olarak, verilerinizin eksiksiz olduğundan emin olmak için CONSTRAINT veritabanını ekleyebilirim, ancak bu mantığı da işleyen bir üyelik hizmeti de uygulayabilirsiniz. Kumandanızda başvurulabilir bir arayüz (gibi bir şey şu) için

Birincisi, grup bu:

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(); 
} 

Sonra bir SimpleMembership ait hibrid ve veritabanı bağlantısı olarak hizmet uygulayabilir. Ben jenerik tutmak uğruna, ben IRepository<T> desen kullanın, ancak bu doğrudan DbContext, ObjectContext, vb olabilir. Ben de kısa tutmak, eksik checksums ve kısa uygulama özür dilerim.

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 
} 

Artık denetleyicinizde bu arabirime başvurabilir ve mantığı tek bir yerde alabilirsiniz. Eğer bir DI konteyner kullanıyorsanız, belli ki bu kayıt, ama burada bir örnek uygulama: Eğer EntityFramework kullanıyorsanız

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); 
    } 

    /* ... */ 
} 

, ayrıca IValidatableObject kullanabilirsiniz. yinelenmesini direnmek için buraya benzersiz giriş için denetler başka SO soru/cevap: bu yeni bir veritabanı ise

Entity Framework IValidatableObject

+0

Sevdim! Bu gerçekten güzel bir çözüm. – user1777914

+0

müthiş, yardımcı olabilirim. –

+0

Güzel sarıcı. Teşekkürler –

0

kullanın seçeneği bir 1. Örnek özel üyelik AccountMembershipProvider : ExtendedMembershipProvider

  1. kullanıcı ExtendedMemberShipprovider dan Birim testablity için WebSecurity için bir sarıcı miras

    public interface IWebSecurity 
           { 
    
            bool Login(string userName, string password, bool rememberMe = false); 
            bool ChangePassword(string userName, string currentnPassword, string newPassword); 
            void LogOut(); 
           } 
    

    public class WebSecurityWrapper yapın: IWebSecurity

    {

    İşte
    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(); 
        } 
    } 
    

sen, Ben olsaydım

  1. web.config
+0

Bir arayüz oluşturmayı kabul ediyorum, ancak uygulamada benzersiz e-posta kısıtlamasını kolayca uygulayabilirsiniz. Ama aynı zamanda, bu tür bir kısıtlamanın veritabanı düzeyinde yapılması ve web projesine iletilmesi gerektiğine de inanıyorum. –

+0

Eh, bu bir doğrulama sorunu. Doğrulama yapacağım ve dediğiniz gibi db tarafının da doğrulanmasını da söylediniz. –

+0

Impleming ExtendedMembershipProvider, tüm metodları uygulamak zorunda olduğumdan, sadece ekstra bir işlevsellik için çok fazla iş gerektirecektir, SimpleMembershipProvider'ı genişletirken sadece kayıt yöntemini geçersiz kılabilirim. Bu kolay mı? Bu yeni sınıfta giriş/çıkış yöntemlerini de ekleyebilirim. Neden tüm genişlemeyi uygulama ihtiyacı? – user1777914