Programming/.NET

공급자는 ASP.NET 플랫폼에서 기본적으로 제공하는것 이외에 직접 만들어 사용할 수도 있습니다. 예제로 만들어볼 공급자는 회원관리를 위한 공급자인데 이 경우 기존의 MembershipProvider 공급자클래스를 상속받아 새로운 공급자를 생성할 것입니다.

 

새로 만들 공급자클래스는 MembershipProvider의 추상클래스로 부터 기본 골격을 상속받아 생성하고자 합니다. 따라서 임의의 회원관리 클래스를 하나 생성하고 MembershipProvider의 클래스로 부터 상속하도록 한 다음 MembershipProvider 에 커서를 두고 Edit -> IntelliSense -> Implement Abstract Class를 선택하면 다음과 같은 형태의 클래스가 생성됨을 볼 수 있습니다.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;

namespace web_form_test
{
    public class membership : MembershipProvider
    {
        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 MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, 

bool isApproved, object providerUserKey, out 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 MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

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

        public override 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 MembershipUser GetUser(string username, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        public override 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 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(MembershipUser user)
        {
            throw new NotImplementedException();
        }

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

 

그런다음 web.config에 위에서 생성한 공급자를 다음과 같이 정의하도록 합니다.

 

<membership defaultProvider="Mymembership">
  <providers>
    <add name="Mymembership" type="web_form_test.membership" connectionStringName="sqlprovider" />
  </providers>
</membership>

 

신규로 생성한 Mymembership 공급자는 상위의 어느 설정파일에서도 정의되어 있지 않으므로 Mymembership을 defaultProvider로 정의해야 하며 타입은 새로 생성한 클래스로 지정합니다. 회원관리를 위한 저장소는 mssql을 사용할 것이므로 다음과 같이 별도로 connectionStrings를 생성해

 

<connectionStrings>

   <add name="sqlprovider" connectionString="Data Source=localhost;Initial Catalog

=member;User ID=sa;Password=123456;"/>
</connectionStrings>

 

해당 연결정보를 connectionStringName으로 설정하였습니다(sqlprovider).

 

이제 DB구성을 해야 하는데 연결정보생성부분에서는 member라는 DB를 지정했습니다. 이 DB에 다음과 같은 형식의 사용자 테이블을 생성하겠습니다.

 

 

 

여기까지 하면 이제 신규로 만든 공급자를 활용할 준비가 된것이고 공급자클래스의 메소드를 수정하여 필요한 기능을 정의하면 됩니다. 예로 CreateUser메소드를 수정하여 새로운 사용자추가에 대한 처리를 진행해 보도록 하겠습니다.

 

우선 클래스의 Initialize메소드를 재정의하여 web.config에 설정한 값을 가져와야 하는데 가져올 정보로는 mssql 서버연결문자열에 대한 connectionStringName속성값입니다.

 

private SqlConnection con;

public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
    base.Initialize(name, config);

    con = new SqlConnection(WebConfigurationManager.ConnectionStrings[config["connectionStringName"]].ConnectionString);
}

 

일단 config["connectionStringName"] 을 통해서 web.config에 지정한 connectionStringName값을 가져오면 sqlprovider가 반환될 것입니다. 이 반환된 값을 다시 WebConfigurationManager클래스에 전달하여 sqlprovider에 대항하는 연결문자열 정보를 가져옵니다. 확인된 연결문자열 정보는 SqlConnection 객체에 전달하여 DB로의 연결정보를 수립하도록 하였습니다.

 

이제 CreateUser 메소드를 수정하기 이전에 사용자정보에 관한 클래스를 다음과 같이 생성합니다.

 

public class membershipUser : MembershipUser
{
    public string UName
    {
        get;
        set;
    }
}

 

간단히 사용자 이름값을 가지는 클래스인데 이 클래스는 MembershipUser 클래스를 상속받도록 합니다. CreateUser뿐만 아니라 몇몇 메소드에서 MembershipUser형식을 반환하도록 되어 있는데 이때문에 위와 같은 클래스를 생성하고 반환처리를 해야하기 때문입니다. (물론 귀찮으면 그냥 null을 반환해도 되긴 합니다....만...)

 

public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, 

bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
    string query = string.Empty;
    query = string.Format("Insert Into TUser (UserID, UserPassword) Values('{0}', '{1}')", username, password);

    SqlCommand cmd = new SqlCommand(query, con);
    con.Open();
    cmd.ExecuteNonQuery();
    con.Close();

    status = MembershipCreateStatus.Success;

    membershipUser mu = new membershipUser();
    mu.UName = username;

    return mu;
}

 

CreaeUser메소드에서는 전달받은 username과 password를 이전에 생성한 SqlConnection객체로 DB서버에 접속한 후 쿼리를 실행해 사용자를 생성하도록 합니다. 그리고 사용자정보클래스의 인스턴스에 username값을 전달하고 return처리합니다.

 

물론 그 전에 사용자 중복확인이라던가 비밀번호암호화등의 유효성검사가 선행되어야 하지만 예제는 간결화를 위해 생략하였으므로 참고하시기 바랍니다.

 

공급자에 대한 작업이 완료되었으므로 이제 웹애플리케이션에서 해당 공급자를 활용하여 사용자를 생성합니다.

 

membership ms = (membership)Membership.Providers["Mymembership"];

MembershipCreateStatus mcs;
membershipUser mu = (membershipUser)ms.CreateUser("aaa""1234"string.Empty, string.Empty, string.Empty, falsenullout mcs);

Response.Write(mu.UName + " 환영합니다.");

 

실제 DB에서 사용자 추가여부를 확인해 보면 정상적으로 사용자가 추가된 것을 확인할 수 있을 것입니다.

 

참고로 생성한 공급자에서는 내부에 정의된 모든 메소드를 반드시 사용해야 하는것은 아닙니다. 만일 필요없는 메소드의 경우 아래처럼 NotSupportedException() 예외처리를 하시기 바랍니다.

 

public override MembershipUser GetUser(string username, bool userIsOnline)
{
    throw new NotSupportedException();
}

'Programming > .NET' 카테고리의 다른 글

[ASP.NET] 사이트 네비게이션 (sitemap)  (0) 2016.04.19
[ASP.NET] XSLT  (0) 2016.04.05
[ASP.NET] 공급자 모델 - 3  (0) 2016.03.30
[ASP.NET] 공급자 모델 - 2  (0) 2016.03.22
[ASP.NET] 공급자 모델 - 1  (0) 2016.03.17
[ASP.NET] Menu  (0) 2016.03.10
0 0