Accounts Ver 2.7.1 (bug fix)

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (9/10/2007 3:41:00 PM) Viewing : 2858

PasswordRecovery 컨트롤을 사용하면서 
버그가 발견되어 수정하였다.

CustomSqlMembershipProvider 클래스의 ResetPassword 메서드에서 실패시 기존의 예외를 throw 했던 부분을 null을 리턴 하는 것으로 변경하였다.

이는  PasswordRecovery 컨트롤에서 받은 데이터의 유효성을 체크 하는 부분에 null 체크를 하기 때문이다.
즉 입력받은 사용자의 질문이 틀릴 경우에 null을 리턴 하여야 하므로....ㅡ.ㅡ;;

변경하였다.

  876       db.ExecuteNonQuery(false, CommandType.StoredProcedure, "uspAccountsMembershipResetPassword", param, userName, this.EncryptPassword(newPassword), this.MaxInvalidPasswordAttempts, this.PasswordAttemptWindow, DateTime.Now, this.RequiresQuestionAndAnswer ? answer : "");

  877 

  878       status = (MembershipStatus)(db.GetReturnValue<int>(param[0]));

  879       if (status == MembershipStatus.Success)

  880       {

  881         return newPassword;

  882       }

  883       else

  884       {

  885         return null;

  886         //2007.09.10

  887         //PasswordRecovery 컨트롤에서 사용하기 위해서는 값이 실패 할때 null을 반환해야 한다.

  888         //throw new Exception(new MembershipStatusMessage(status).ToString());

  889       }


마지막 업데이트 : (9/10/2007 3:41:00 PM)

TAG : 없음



첨부 파일 보기 (1)
Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기

Accounts Ver 2.7 입니다.

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (7/16/2007 6:04:50 PM) Viewing : 2556
음 조금씩 조금씩 오류들이 수정되고 보완되고 있네요..^^;;
각 클래스의 히스토리를 참고 하세요..

마지막 업데이트 : (7/16/2007 6:04:50 PM)

TAG : 없음



첨부 파일 보기 (1)
Trackback 보기 (0)
댓글 보기 (2)
황금산님의 글 (7/31/2007 11:07:44 AM)
데브피아 들렸다가..자료 다운로드해 보았습니다..많은 도움이 될 것 같습니다..감사..



이방은님의 글 (7/31/2007 11:27:17 AM)
다행이네요..^^;



댓글 쓰기

[수정] CustomSqlProfileProvider Ver 1.0.1

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (1/13/2007 3:15:51 PM) Viewing : 2255
이 글은 수정본임을 밝혀 둔다.(원본 내용이 잘못되었길래.. RSS 사용자를 위하여 새로운 글로 작성했다.ㅡ.ㅠ; 죄송합니다.)
먼저 이 글을 보기 전에 아래 글을 보기 바란다.

Profile에 대하여 첫번째 
Profile에 대하여 두번째 
Profile에 대하여 그 마지막 이야기

  이전 글의 오류에 대해 잠깐 얘기를 해보자면 (이전 글을 못 본 사람은 볼 필요가 없다..ㅡ.ㅡ;)
잘 못된 부분은 SP1 의 적용 부분인 Custom으로 만든 ProfileCommon클래스에 대한 부분이 정상적인 작동을 하지 않았다.

Web.Config의 설정 부분을 먼저 보도록 하자.
다른 Provider와 마찬 가지로 providers 요소에 아래와 같이 세팅 하도록 한다.
그 외에 설정들은 MSDN 및 위의 글에서 참고 하도록 한다.

    1     <anonymousIdentification enabled="true"/>

    2     <profile defaultProvider="CustomSqlProfileProvider">

    3       <providers>

    4         <clear/>

    5         <add name="CustomSqlProfileProvider" type="BIT.Web.Accounts.CustomSqlProfileProvider" connectionStringName="con"/>

    6       </providers>

    7       <properties>

    8         <add name="Role" defaultValue="Anonymous" type="String" allowAnonymous="true" serializeAs="String"/>

    9         <add name="RealName" type="String" allowAnonymous="true" serializeAs="String"/>

   10         <add name="EMail" type="String" allowAnonymous="true" serializeAs="String"/>

   11         <add name="ViewType" type="String" allowAnonymous="true" serializeAs="String"/>

   12         <add name="UserSite" type="String" allowAnonymous="false" serializeAs="String"/>

   13       </properties>

   14     </profile>

properties 요소를 보도록 하자.
defaultValue 라는 것은 기본 설정 값이다. Role의 경우 인증을 하지 않으면 기본적으로 Anonymous라는 역할을 할당한다는 의미가 되겠다. 이로서 인증 하지 않은 사용자에게도 Role을 부여 할 수 있게 되었다. 역할기반 인증을 할때 깔끔하다..함 써보라..

이제 코드를 살펴 보자.

    1     public class CustomSqlProfileProvider : ProfileProvider

    2     {

    3         public CustomSqlProfileProvider();

    4 

    5         public override string ApplicationName { get; set; }

    6 

    7         public override int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate);

    8         public override int DeleteProfiles(ProfileInfoCollection profiles);

    9         public override int DeleteProfiles(string[] usernames);

   10         public override ProfileInfoCollection FindInactiveProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords);

   11         public override ProfileInfoCollection FindProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, out int totalRecords);

   12         public override ProfileInfoCollection GetAllInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords);

   13         public override ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords);

   14         public override int GetNumberOfInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate);

   15         public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext sc, SettingsPropertyCollection properties);

   16         public override void Initialize(string name, NameValueCollection config);

   17         public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection);

   18     }

다른 프로바이더보다 조금 적은 수의 메서드만 재정의 하면 되겠다.

아래 메서드는 가장 많이 호출되는 핵심 메서드이다..
사용자의 프로필 정보를 반환하는 메서드가 되겠다.

    1 /// <summary>

    2 /// 지정된 응용 프로그램 인스턴스와 설정 속성 그룹에 대한 설정 속성 값의 컬렉션을 반환합니다.

    3 /// </summary>

    4 /// <param name="sc">현재 응용 프로그램의 용도를 설명하는 SettingsContext입니다.</param>

    5 /// <param name="properties">값이 검색될 설정 속성 그룹을 포함하는 SettingsPropertyCollection입니다.</param>

    6 /// <returns>

    7 /// 지정된 설정 속성 그룹에 대한 값을 포함하는 SettingsPropertyValueCollection입니다.

    8 /// </returns>

    9 public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext sc, SettingsPropertyCollection properties)

   10 {

   11     SettingsPropertyValueCollection col = new SettingsPropertyValueCollection();

   12     if (properties.Count >= 1)

   13     {

   14         string userName = (string)sc["UserName"];

   15         foreach (SettingsProperty property in properties)

   16         {

   17             if (property.SerializeAs == SettingsSerializeAs.ProviderSpecific)

   18             {

   19                 if (property.PropertyType.IsPrimitive || (property.PropertyType == typeof(string)))

   20                 {

   21                     property.SerializeAs = SettingsSerializeAs.String;

   22                 }

   23                 else

   24                 {

   25                     property.SerializeAs = SettingsSerializeAs.Xml;

   26                 }

   27             }

   28             col.Add(new SettingsPropertyValue(property));

   29         }

   30         if (!string.IsNullOrEmpty(userName))

   31         {

   32             this.GetPropertyValuesFromDatabase(userName, col);

   33         }

   34     }

   35     return col;

   36 }

GetPropertyValuesFromDatabase 라는 메서드에서 DB에서 조회하여 프로필정보를 가져 오게 되며 GetPropertyValuesFromDatabase메서드에서 호출되는 ParseDataFromDB메서드가 DB에서 조회해온 값을 파싱한다.

ParseDataFromDB메서드에서 조회해온  긴 문자열을 각각의 속성에 맞게끔 파싱하는 작업을 한다.

소스를 보면서 따라가 보게 되면..그리 어렵지 않을듯 싶다.

Source 에 대한 설명을 하면서 항상 느끼는 거지만..참..설명이 부실하다는 것이다.
그런데..사실..소스는 스스로 분석해 보아야지..조금 보면 알겠지만..설명할 것이 별루 없다..ㅡ.ㅠ;
내가 말주변이 없는 것인지도..


마지막 업데이트 : (1/13/2007 3:15:51 PM)

TAG : 없음



Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기

CustomSqlMembershipProvider Ver 2.2

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (12/4/2006 4:30:54 PM) Viewing : 7326

CustomSqlMembershipProvider

대부분의 패턴은 앞서 설명한 CustomSqlRoleProvider와 정확히 일치한다.

먼저 클래스의 주석 부분을 보도록 하자..

[주석]

    /// <summary>
    /// CustomSqlMembershipProvider Ver 2.2
    /// </summary>
    /// <remarks>
    /// 06.04.03 - Prototype - 방실
    /// 06.07.07 - UserId라는 GUID키를 추가 - 방실
    /// 06.07.27 - partial 키워드로 override 부분과 재정의 부분을 분리 - 방실
    /// 06.10.13 - GetExceptionText에 case 8: 추가 - 방실
    /// 06.10.16 - ChangePassword 메서드의 버그 수정 - 방실
    /// </remarks>

참고로 주석을 보면 알겠지만.
처음에 이 프로바이더를 만들었을때는 UserId 항목을 만들지 않았었다.
프로필이라든지 웹파츠를 전혀 쓸 계획이 없었기 때문이다..@.@
(사실 지금도 웹파츠는 실무에서 써본 적이 없다...프로필은 애용하고 있다 ㅋ.)
추가로 프로필에 대해 조금 알게 된 후 프로필프로바이더를 구현 하면서 UserId 부분을 추가 하게 되었다.

이제 클래스의 스키마를 보도록 하자.

[클래스 스키마]

public class CustomSqlMembershipProvider : MembershipProvider
{
      // Methods
      public CustomSqlMembershipProvider();
      private string BinToHex(byte[] arrByte);
      public bool ChangePassword(string userName, string newPassword);
      public override bool ChangePassword(string userName, string oldPassword, string newPassword);
      public override bool ChangePasswordQuestionAndAnswer(string userName, string password, string newPasswordQuestion, string newPasswordAnswer);
      internal bool CheckPassword(string userName, string password, out Message msg);
      private bool CheckPassword(string userName, string password, bool updateLastLoginActivityDate, bool failIfNotApproved);
      public override MembershipUser CreateUser(string userName, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status);
      public MembershipUser CreateUser(string userName, string password, string realName, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status, string phone, string celPhone, string ssn, string position, string department, string zipcode, string address1, string address2, int cPId, string cName, string cNameEtc);
      private bool CreateUserValidate(string userName, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, out MembershipCreateStatus status, out string encryptPassword, out string encryptPasswordAnswer);
      private string DecryptPassword(string pass);
      public override bool DeleteUser(string userName, bool deleteAllRelatedData);
      private string EncryptPassword(string pass);
      public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords);
      public override MembershipUserCollection FindUsersByName(string userNameToMatch, int pageIndex, int pageSize, out int totalRecords);
      public SqlDataReader GetAddressList(string dong);
      public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords);
      private string GetEncryptPasswordAnswer(string userName, string passwordAnswer);
      private string GetExceptionText(int status);
      public override int GetNumberOfUsersOnline();
      public override string GetPassword(string userName, string answer);
      private string GetPasswordFromDB(string userName, string passwordAnswer, out int status);
      private void GetPasswordWithFormat(string userName, bool updateLastLoginActivityDate, out int status, out string password, out int failedPasswordAttemptCount, out int failedPasswordAnswerAttemptCount, out bool isApproved, out DateTime lastLoginDate);
      public CustomSqlMembershipUser GetUser(string userName);
      public override MembershipUser GetUser(object providerUserKey, bool userIsOnline);
      public override MembershipUser GetUser(string userName, bool userIsOnline);
      public override string GetUserNameByEmail(string email);
      public string GetUserNameBySSN(string realName, string ssn, out Message msg);
      public override void Initialize(string name, NameValueCollection config);
      private bool IsStatusDueToBadPassword(int status);
      public override string ResetPassword(string userName, string answer);
      public override bool UnlockUser(string userName);
      public void UpdateUser(CustomSqlMembershipUser user);
      public override void UpdateUser(MembershipUser user);
      public override bool ValidateUser(string userName, string password);
      public void ValidateUserBySSN(string userName, string realName, string ssn, out Message msg);

      // Properties
      public override string ApplicationName { get; set; }
      public override bool EnablePasswordReset { get; }
      public override bool EnablePasswordRetrieval { get; }
      public override int MaxInvalidPasswordAttempts { get; }
      public override int MinRequiredNonAlphanumericCharacters { get; }
      public override int MinRequiredPasswordLength { get; }
      public override int PasswordAttemptWindow { get; }
      public override MembershipPasswordFormat PasswordFormat { get; }
      public override string PasswordStrengthRegularExpression { get; }
      public override bool RequiresQuestionAndAnswer { get; }
      public override bool RequiresUniqueEmail { get; }

      // Fields
      private string connectionString;
      private bool enablePasswordReset;
      private bool enablePasswordRetrieval;
      private int maxInvalidPasswordAttempts;
      private int minRequiredNonalphanumericCharacters;
      private int minRequiredPasswordLength;
      private int passwordAttemptWindow;
      private MembershipPasswordFormat passwordFormat;
      private string passwordStrengthRegularExpression;
      private bool requiresQuestionAndAnswer;
      private bool requiresUniqueEmail;
}
 

조금 내용이 많다..ㅡ.ㅡ;;

필드들의 값들은 모두 MSDN에 기본 정의 되어 있는 것들을 그대로 계승했다.
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.ko/dv_ASPNETgenref/html/8423ec7f-a06d-4606-977e-a46400b2fc18.htm
해당 링크를 참고하면 된다.

1300여라인이 넘어 가는 코드지만 사실상 별로 볼만한 것이 없다.

앞에 CustomSqlRoleProvider 클래스를 설명할때에도 잠깐 언급을 하였지만.
프로젝트에 따라 테이블 스키마가 매우 다를것이다.
이것을 범용적으로 만들기는 사실상 불가능 하다.

그래서 고민한게 이런 패턴(?)을 생각해 낸건데..
불필요하다고 생각된 컬럼은 제거 하고 확장성을 부여 한것이다.
실제 프로젝트에 들어 가게 되면 기본 테이블 스키마에 프로젝트에 따라 필요한 컬럼들을 추가하고
그에 대한 프로시저를 원본 스키마와 구분하기 위해서 Custom이라는 미들네임을 부여 하여 메서드를 재정의 하는 방향으로 구현 하였다.

쉽게 이르자면.
회원 가입의 경우 CreateUser라는 메서드를 호출한다.
정의된 것과 실제 사용할 테이블 스키마가 다르기 때문에 CreateUser메서드를 재정의 한다.
이때 이 코드는 CustomSqlMembershipProvider에 구현하도록 한다..

아래는 그 예시이다.


[CreateUser]

/// <summary>
/// 속성 값이 지정되고 고유한 식별자를 가진 새 사용자를 데이터 저장소에 추가하고 사용자가 만들어졌음을 나타내거나 사용자 만들기에 실패한 이유를 나타내는 상태 매개 변수를 반환합니다.
/// </summary>
/// <param name="userName">새 사용자의 사용자 아이디입니다.</param>
/// <param name="password">새 사용자의 암호입니다.</param>
/// <param name="password">새 사용자의 이름입니다.</param>
/// <param name="email">새 사용자의 전자 메일 주소입니다.</param>
/// <param name="passwordQuestion">멤버 자격 사용자의 암호 질문 값입니다.</param>
/// <param name="passwordAnswer">멤버 자격 사용자의 암호 대답 값입니다.</param>
/// <param name="isApproved">새 사용자에 대한 로그온이 승인되는지 여부를 나타내는 부울 값입니다.</param>
/// <param name="providerUserKey">멤버 자격 정보 저장소에 저장되어야 하는 사용자 ID입니다.</param>
/// <param name="status">사용자가 만들어졌음을 나타내거나 사용자 만들기에 실패한 이유를 나타내는 MembershipCreateStatus입니다.</param>
/// <returns>새로 만든 사용자에 대한 MembershipUser 개체입니다. 사용자가 만들어지지 않았으면 이 메서드가 Null 참조를 반환합니다. </returns>
public MembershipUser CreateUser(string userName, string password, string realName, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
    string encryptPassword = "";
    string encryptPasswordAnswer = "";

    if (!this.CreateUserValidate(userName, password, email, passwordQuestion, passwordAnswer, isApproved, out status, out encryptPassword, out encryptPasswordAnswer))
    {
        return null;
    }

    SqlDB db = new SqlDB(this.connectionString);
    DateTime time1 = DateTime.Now;
    SqlParameter[] param = {
        new SqlParameter("@ReturnValue", SqlDbType.Int),
        new SqlParameter("@UserId", SqlDbType.UniqueIdentifier),
        new SqlParameter("@UserName", SqlDbType.VarChar, 64),
        new SqlParameter("@Password", SqlDbType.VarChar, 256),
        new SqlParameter("@RealName", SqlDbType.VarChar, 128),
        new SqlParameter("@Email", SqlDbType.VarChar, 256),
        new SqlParameter("@PasswordQuestion", SqlDbType.VarChar,256),
        new SqlParameter("@PasswordAnswer", SqlDbType.VarChar,256),
        new SqlParameter("@IsApproved", SqlDbType.Bit),
        new SqlParameter("@UniqueEmail", SqlDbType.Bit),
        new SqlParameter("@CurrentTime", SqlDbType.DateTime)
    };
    param[0].Direction = ParameterDirection.ReturnValue;
    param[1].Direction = ParameterDirection.InputOutput;

    db.ExecuteNonQuery(false, CommandType.StoredProcedure, "dbo.Accounts_Custom_Membership_CreateUser", param, providerUserKey, userName, encryptPassword, realName, email, passwordQuestion, encryptPasswordAnswer, isApproved ? 1 : 0, this.RequiresUniqueEmail ? 1 : 0, time1);
    int num3 = db.GetReturnValue<int>(param[0]);
    if ((num3 < 0) || (num3 > 11))
    {
        num3 = 11;
    }
    status = (MembershipCreateStatus)num3;
    if (num3 != 0)
    {
        return null;
    }
    providerUserKey = new Guid(param[1].Value.ToString());
    time1 = time1.ToLocalTime();
    return new MembershipUser(this.Name, userName, providerUserKey, email, passwordQuestion, null, isApproved, false, time1, time1, time1, time1, new DateTime(0x6da, 1, 1));
}


코드를 보면 알겠지만.
정의된 CreateUser메서드와 상당히 유사하다.
그러나 파라메터가 몇개 추가 되었다..

사용자 정의가 사실 이런게 장점이 아닐까 생각 한다.
프로젝트에 따라서 나름대로 꽤 코드를 많이 생성해야 하지만.
사실 프로젝트라는게 거의 비슷비슷해서 실상은 그리 많은 코드들을 새로 생성하지는 않는다..

더 좋은 방법이 있으면 조언 부탁한다..ㅡ.ㅠ;

<추가>
이제 보니 Web.Config 설정 부분이 누락되어 있다..ㅡ.ㅡ;;;

 

    1 <membership defaultProvider="CustomSqlMembershipProvider" hashAlgorithmType="SHA1">

    2     <providers>

    3         <clear/>

    4         <add name="CustomSqlMembershipProvider" type="BIT.Web.Accounts.CustomSqlMembershipProvider" connectionStringName="con" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" passwordAttemptWindow="0" minRequiredPasswordLength="4" minRequiredNonalphanumericCharacters="0" passwordStrengthRegularExpression=""/>

    5     </providers>

    6 </membership>

각각 Property의 내용들은 MSDN 에서 참고 하도록 한다.
100% 정확히 일치한다..고 보장한다??

ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.ko/dv_ASPNETgenref/html/8423ec7f-a06d-4606-977e-a46400b2fc18.htm

그리고 페이지에서의 사용법 예는 아래와 같다.
아래 예제는 회원 가입 메서드의 내부이다..참고하도록 한다.

    1 MembershipCreateStatus status;

    2         ((CustomSqlMembershipProvider)(Membership.Provider)).CreateUser(WebUtility.HtmlEncoding(this.txtUserId.Text.Trim()), this.txtPassword1.Text.Trim(), WebUtility.HtmlEncoding(this.txtUserName.Text.Trim()), WebUtility.HtmlEncoding(this.txtEmail.Text.Trim()), WebUtility.HtmlEncoding(this.txtQuestion.Text.Trim()), WebUtility.HtmlEncoding(this.txtAnswer.Text.Trim()), true, null, out status);

    3         switch (status)

    4         {

    5             case MembershipCreateStatus.DuplicateEmail:

    6                 JScript.AlertRedirect(this, "이미 등록된 전자 메일 주소입니다.", "Join.aspx");

    7                 break;

    8             case MembershipCreateStatus.DuplicateProviderUserKey:

    9                 break;

   10             case MembershipCreateStatus.DuplicateUserName:

   11                 JScript.AlertRedirect(this, "이미 가입된 사용자 입니다.", "Join.aspx");

   12                 break;

   13             case MembershipCreateStatus.InvalidAnswer:

   14                 JScript.AlertRedirect(this, "유효한 답변 형식이 아닙니다.", "Join.aspx");

   15                 break;

   16             case MembershipCreateStatus.InvalidEmail:

   17                 JScript.AlertRedirect(this, "유효한 전자 메일 주소가 아닙니다.", "Join.aspx");

   18                 break;

   19             case MembershipCreateStatus.InvalidPassword:

   20                 JScript.AlertRedirect(this, "암호의 형식이 잘 못 되었습니다.", "Join.aspx");

   21                 break;

   22             case MembershipCreateStatus.InvalidProviderUserKey:

   23                 break;

   24             case MembershipCreateStatus.InvalidQuestion:

   25                 JScript.AlertRedirect(this, "유효한 질문 형식이 아닙니다.", "Join.aspx");

   26                 break;

   27             case MembershipCreateStatus.InvalidUserName:

   28                 JScript.AlertRedirect(this, "유효한 사용자 아이디 형식이 아닙니다.", "Join.aspx");

   29                 break;

   30             case MembershipCreateStatus.ProviderError:

   31                 JScript.AlertRedirect(this, "프로바이더의 알수 없는 오류 입니다.", "Join.aspx");

   32                 break;

   33             case MembershipCreateStatus.Success:

   34                 Roles.AddUsersToRoles(new string[] { this.txtUserId.Text }, new string[] { "User" });

   35                 FormsAuthentication.SetAuthCookie(this.txtUserId.Text, false);

   36                 this.Profile.RealName = this.txtUserName.Text;

   37                 this.Profile.EMail = this.txtEmail.Text;

   38                 JScript.AlertRedirect(this, "회원 가입 되셨습니다.", "Default.aspx");

   39                 break;

   40             case MembershipCreateStatus.UserRejected:

   41                 JScript.AlertRedirect(this, "프로바이더의 알수 없는 오류 입니다.", "Join.aspx");

   42                 break;

   43             default:

   44                 JScript.AlertRedirect(this, "프로바이더의 알수 없는 오류 입니다.", "Join.aspx");

   45                 break;

   46         }



구현환경
.NET Framework 2.0
Microsoft SqlServer 2000
Microsoft Visual Studio.NET 2005
Microsoft Windows 2003 Standard



마지막 업데이트 : (12/7/2006 6:51:14 PM)

TAG : 없음



Trackback 보기 (0)
댓글 보기 (1)
노용석님의 글 (6/25/2007 10:31:59 AM)
여기서 보고 많은 도움이 되었습니다~
저는 모든 id를 GUID에서 int로 수정하였고, ApplicationName 파라메터를 없앴는데 무리없이 동작을 하더라구요.



댓글 쓰기

CustomSqlRoleProivder Ver 2.0

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (10/13/2006 3:28:14 PM) Viewing : 2460

CustomSqlRoleProvider

클래스 이름은 CustomSqlRoleProvider이다.
이는 MSSQL에서만 통용된다고 먼저 밝힌다.
클래스 이름은 CustomSqlRoleProvider인데 파일 이름은 SqlRoleProvider이다.

앞서 게시글에서도 말했듯이 이 클래스 재정의 패턴은
기존 클래스인 SqlRoleProvider의 기능을 모두(?) 구현하며 확장을 할 수 있게끔 하는 것이다.
그러므로 기존의 SqlRoleProvider의 기능들은 모두 SqlRoleProvider라는 파일에 정의 되어 있고
프로젝트마다 확장되어 변경되어야 하는 부분은 CustomSqlRoleProvider 파일에 있다.
이 두개의 파일은 당연히 Partial로 연결되어져 있으며
이렇게 나눈 이유는
단지 관리상의 편의성 때문이다.
어떤 프로젝트를 하든지간에 SqlRoleProvider파일은 건들 필요가 없으며 CustomSqlRoleProvider파일만 재정의 하면 되기 때문이다.

이부분은 MembershipProvider와도 동일한 패턴이다.

자 먼저 클래스의 주석을 보도록 하자.


[주석]

    /// <summary>
    /// CustomSqlRoleProvider Ver 2.0
    /// </summary>
    /// <remarks>06.03.28 - Prototype - 방실</remarks>
    /// <remarks>06.07.07 - UserId라는 GUID키를 추가 - 방실</remarks>
    /// <remarks>06.07.27 - partial 키워드로 override 부분과 재정의 부분을 분리 - 방실</remarks>

이 클래스는 RoleProvider를 상속 받았다.
이 클래스는 사이트에서 회원(멤버)들을 역할을 이용해서 관리를 하기 위함이다.

스키마는 아래와 같으며 자세한 내용은
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.ko/dv_aspnetcon/html/851671ce-bf9b-43f2-aba4-bc9d28b11c7d.htm
이 링크를 보도록 한다.

그리고 해당 메서드들과 프라퍼티들을 모두 재정의 해 본다.
해당 메서드에서 하는 일은 MSDN에 나온 설명의 기능을 모두 해야 한다..!!!

이 클래스는 ApplicationName 프라퍼티를 제외한(사용하지 않기 때문에..) 모든 멤버들을 재정의 하였으며
그 기능은 똑같다..

[클래스 스키마]

public class CustomSqlRoleProvider : RoleProvider
{
      // Methods
      public override void AddUsersToRoles(string[] userNames, string[] roleNames);
      public override void CreateRole(string roleName);
      public override bool DeleteRole(string roleName, bool deleteOnlyIfRoleIsEmpty);
      public override string[] FindUsersInRole(string roleName, string userName);
      public override string[] GetAllRoles();
      public override string[] GetRolesForUser(string userName);
      public override string[] GetUsersInRole(string roleName);
      public override void Initialize(string name, NameValueCollection config);
      public override bool IsUserInRole(string userName, string roleName);
      public override void RemoveUsersFromRoles(string[] userNames, string[] roleNames);
      public override bool RoleExists(string roleName);

      // Properties
      public override string ApplicationName { get; set; }

      // Fields
      private string connectionString;
}

먼저
web.config에서
이 프로바이더를 사용하기위해서 설정해야하는 부분을 살펴 보겠다.



[web.Config]

    <roleManager enabled="true" defaultProvider="CustomSqlRoleProvider" cacheRolesInCookie="true">
      <providers>
        <clear/>
        <add name="CustomSqlRoleProvider" connectionStringName="con" type="BIT.Web.Accounts.CustomSqlRoleProvider"/>
      </providers>
    </roleManager>

자세한 사항은
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.ko/dv_ASPNETgenref/html/4b0f6078-4824-4fc8-a5ee-4ae00ee3ceec.htm

위 링크를 확인해 보도록 하며
최소한 위와 같이 설정하도록 한다.

이제 메서드를 살펴 보도록 하겠다.
먼저 Initialize메서드를 살펴 보자.

[Initialize]

        /// <summary>
        /// 공급자를 초기화합니다. 
        /// </summary>
        /// <param name="name">공급자의 이름입니다.</param>
        /// <param name="config">이 공급자에 대해 구성에 지정된 공급자별 특성을 나타내는 이름/값 쌍의 컬렉션입니다.</param>
        public override void Initialize(string name, NameValueCollection config)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            if (name == null || name.Length == 0)
            {
                name = "CustomSqlRoleProvider";
            }

            if (String.IsNullOrEmpty(config["description"]))
            {
                config.Remove("description");
                config.Add("description", "Custom Sql Role Provider");
            }

            if (String.IsNullOrEmpty(config["connectionStringName"]))
            {
                throw new ArgumentNullException("connectionStringName");
            }
            else
            {
                this.connectionString = config["connectionStringName"];
            }

            base.Initialize(name, config);
        }

이 메서드는 딱 한번 실행된다.

처음으로 사용자가 페이지를 로드 하게 되면 AppDomain에 이 웹사이트가 로딩되면서
web.Config의 설정을 읽게 되어 메모리에 할당된다.

이때 web.Config에 설정된 해당 프로바이더의 설정값들을 검증하고 할당하는 코드들이 들어 있는 메서드이다. 아마도..프로바이더 계열에는 다 있는 메서드일 것이다.

프로바이더의 특성에 따라 프라퍼티의 값이 필수값인지 ..필수값인데 값이 없거나 틀리면 예외를 일으키기도 하며, 기본값을 제공하는 프라퍼티라면 기본값을 설정하는 부분이 들어가기도 한다.

이 부분에서 해당 클래스의 프라퍼티와 필드에 값이 할당되기 때문에
기본 생성자가 노출되어 있긴 하나 기본생성자로 프로바이더 개체를 생성하게 되면 예외를 던지게 된다.

예를 들어 connectionStringName 값은 필수값이어서 만약에 설정되지 않았다면 예외를 던지고
name은 선택값이어서 설정되지 않았다면 기본값인 CustomSqlRoleProvider를 사용한다.

다른 메서드들은 MSDN에 나온 설명으로 대체한다..

이렇게 재정의가 되었다면
이제 Roles라는 클래스를 사용 할 수 있게 된다.

테스트는 ASP.NET 구성 관리자를 클릭해서 쉽게 테스트 해볼 수가 있다.


구현환경
.NET Framework 2.0
Microsoft Visual Studio.NET 2005
Microsoft Windows XP SP2



마지막 업데이트 : (10/13/2006 3:30:27 PM)

TAG : 없음



Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기



<< < 1 2 > >>