6

어떻게해야할지에 대한 제안이 필요합니다. 현재 모든 계정 관련 작업을 수행하기 위해 WebSecurity 메소드를 사용하고 있습니다.Asp mvc 4 회원 및 웹 보안

  1. 쓰기 (서브 클래스) 이메일 주소를 확인하기 위해 기존의 createuserAndAccount 방법을 덮어 새로운 SimpleMembershipProvider : 나는 몇 가지 옵션이 있으므로 그러나 전자 메일 고유성 확인을 지원하지 않습니다. 하지만 나는 또한 (websecurity처럼) 로그인 - 로그 아웃 기능과 몇 가지 다른 것들을 구현해야한다.

  2. 데이터베이스에 고유성 제약 조건을 추가하고이를 내 코드에서 잡습니다. 그러나 이것은 내가 데이터베이스베이스에 의존하게 만들 것이다.

  3. 이것은 약간 싸울 수도 있지만 새 클래스에 WebSecurity 소스 코드를 복사하여 붙여 넣을 수 있으며 createUserAndAccount 메소드를 수정할 수 있습니다.

다른 옵션은? 나는 옵션 3을 목표로하고 있으며, 가장 빠른 방법이 될 것입니다. 미래에는 역할을 요구할 것이고 WebSecurity가 지원을 제공하는지 확실하지 않습니다.

+0

, 또 다른 옵션은 사용자 이름으로 이메일을 사용하는 것입니다. 사용자 이름은 기본적으로 고유합니다. – Igarioshka

답변

5

의 기본 공급자로 당신의 멤버 자격 공급자를 등록합니다 원하는 방법 이메일 변경을 추가 할 수 있습니다 아마도 다음과 같은 방식으로 진행할 것입니다.

먼저 Entity Framework에서 SimpleMembership을 사용한다고 가정하면 tabase 연결 (ADO, LINQ to SQL 등)에는 두 가지 구성 요소 (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> 패턴을 사용하지만 직접 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 
} 

이제이 인터페이스를 컨트롤러에서 참조하고 로직을 한 곳에서 사용할 수 있습니다. 당신이 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

사용 옵션을 하나 예 사용자 정의 회원이 AccountMembershipProvider : ExtendedMembershipProvider

  1. 사용자에게 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

나는 인터페이스를 만드는 것에 동의하지만 구현 내에서 고유 한 전자 메일 제한을 쉽게 구현할 수 있습니다. 그러나 나는 또한 이러한 종류의 제약이 데이터베이스 수준에서 이루어져야하고 웹 프로젝트에 버블 링되어야한다는 확고한 신념을 갖고있다. –

+0

음, 검증 문제입니다. 당신이 말했듯이 또한 유효성을 검사 할 것입니다. –

+0

SimpleMembershipProvider를 확장하는 동안 확장 메서드를 구현해야하므로 ExtendedMembershipProvider를 구현하는 것은 단지 추가 기능에 너무 많은 작업을 필요로합니다. 쉽게 할 수 있니? 이 새로운 클래스에도 로그인/로그 아웃 메소드를 추가 할 수 있습니다. 왜 전체 extendermembership을 구현해야 하는가? – user1777914