6

何をすべきかについての提案が必要です。私は現在、WebSecurityメソッドを使用して、すべてのアカウント関連の仕事をしています。Asp mvc 4メンバーシップとWebSecurity

  1. 書き込み(サブクラス)のメールアドレスを確認するには、既存のcreateuserAndAccountメソッドを上書きし、新しいSimpleMembershipProvider:私はいくつかのオプションを持っているので、しかし、それは、Eメールの一意性の検証をサポートしていません。しかし、私はログインログアウト機能(websecurityと同じように)とその他の機能を実装する必要があります。

  2. データベースに一意制約を追加し、自分のコードでそれを捕らえます。しかし、これは私がデータベースに依存する原因になります。

  3. これはちょっと安いかもしれませんが、新しいクラスにWebSecurityソースコードをコピーして貼り付けてから、createUserAndAccountメソッドを変更することができます。

他のオプションはありますか?私は現時点でオプション3を目指しています、最速の方法です。 将来的には、私はロールも必要になり、WebSecurityがそれらをサポートしているかどうかはわかりません。

+0

、別のオプションは、ユーザー名として電子メールを使用することです。ユーザー名はデフォルトで一意です。 – Igarioshka

答えて

5

のデフォルトプロバイダとしてあなたのメンバシッププロバイダを登録することができ、私はおそらくそれについて次のように行くでしょう:

まず、あなたがEntity FrameworkまたはいくつかのdaでSimpleMembershipを使用していると仮定します(ADO、LINQ to SQLなど)の2つのコンポーネントがあります:WebSecurity.*メソッド呼び出し、およびプロファイル変更を行うためのデータベース接続。個人的には、データが純粋であることを保証するためにCONSTRAINTをデータベースに追加しますが、このロジックも処理するメンバシップサービスを実装することもできます。

まず、お使いのコントローラ(以下のようなもの)で参照することができるインタフェースにグループこれら:

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

次にあなたがSimpleMembershipのハイブリッドおよびデータベース接続などのサービスを実装することができます。一般的なままにするために、私はIRepository<T>パターンを使用していますが、これは直接DbContextObjectContextなどになる可能性があります。

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 
} 

コントローラでこのインターフェイスを参照し、ロジックを1か所に配置することができます。あなたはDIコンテナを使用している場合、明らかにそれを登録しますが、ここでの実装例です:あなたがEntityFrameworkを使用している場合

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

    /* ... */ 
} 

、あなたもIValidatableObjectを使用することができます。複製に抵抗するために、ここで一意のエントリをチェックし、別のSO質問/答えだ:それは新しいデータベースの場合

Entity Framework IValidatableObject

+0

それを愛しました!これは本当に素晴らしい解決策です。 – user1777914

+0

素晴らしい、私が助けることができてうれしい。 –

+0

ニースラッパー。ありがとう –

0

使用オプション1 1.カスタムメンバーシップを行う継承ユーザー

    1. ExtendedMemberShipprovider AccountMembershipProvider : ExtendedMembershipProviderから単位testablityためWebSecurity社のラッパー 例

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

      パブリッククラスWebSecurityWrapper:IWebSecurity

      {

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

    あなたは

    1. を好きな方法であなたの電子メールの変更を追加し、それは私だったら、あなたのweb.configファイル
  • +0

    私はインターフェイスの作成に同意しますが、インプリメンテーション内で一意の電子メール制約を簡単に実装できます。しかし、私はまた、この種の制約がデータベースレベルで行われ、Webプロジェクトにバブリングされるべきだと確信しています。 –

    +0

    これは検証の問題です。私は前もって検証し、あなたが言ったようにdb側も検証します –

    +0

    SimpleMembershipProviderを拡張している間にExtendedMembershipProviderを実装するには余計な機能が必要ですそれは簡単でしょうか?この新しいクラスにもログイン/ログアウトメソッドを追加できます。 extendermembership全体を実装する必要性はなぜですか? – user1777914

    関連する問題