RPNetworks.Configuration - 03

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (12/4/2010 3:39:38 PM) Viewing : 1774

이번에는 dbConnection 에 대해서 알아 보도록 하겠습니다.

config 파일 안에는 아래와 같이 구성되어 있습니다.


 
  
   
   
  
 

dbConnection 섹션에는 connectionStrings 컬렉션 밖에 없습니다.

이 컬렉션은 db연결 문자열을 가지고 있습니다.

이 섹션 값을 코드 상에서 직접 볼일은 아마도 웹폼에서는 없을 듯 합니다.윈폼에서는 있겠죠..

RPNetworks.Core - SqlDB 클래스 에서 아래와 같은 코드가 있었습니다.

public SqlDB(string connectionString)
{
    this.connection = new SqlConnection(ConfigurationHelper.GetConnectionString(connectionString));
}

 이 코드는  config에 정의된 연결문자열의 이름 (name 속성) 을 인풋으로 받으면 이를 복호화 하여 SqlConnection 개체를 만드는 코드 입니다.

여기서 사용되는 ConfigurationHelper.GetConnectionString() 메서드가 오늘 살펴볼 가장 중요한 메서드입니다.

그 전에 connectionStrings 의 요소의 속성들에 대해서 잠깐 살펴 보겠습니다.

name 은 키값입니다. 당연히 유일해야 겠죠.

connectionString은 암호화된 문자열입니다.

securityType 는 암호화할 타입입니다.

이는 RPNetworks.Security.SecurityType 열거형의 Int32값입니다. 그 내용은 아래와 같습니다.

public enum SecurityType
{
    /// 
    /// 아리아 알고리즘입니다.
    /// 
    AriaAlgorithm = 0,
    /// 
    /// 시드 알고리즘입니다.
    /// 
    SeedAlgorithm,
    /// 
    /// 128비트 MD5 알고리즘입니다.
    /// 
    MD5,
    /// 
    /// 128비트 SHA1 알고리즘입니다.
    /// 
    SHA1,
    /// 
    /// 256비트 SHA256 알고리즘입니다.
    /// 
    SHA256
}

연결 문자열은 복호화가 가능하여야 하므로 securityType 은 항상 0 아니면 1이어야 겠자만. SEED 보다는 ARIA가 더 빠릅니다.그래서 전 0을 선호합니다.

마지막으로 keySize는 암호화할 키 사이즈입니다. 암호화 형식에 따라 128, 256 등등이 있습니다.
이 부분은 각 암호화 클래스를 참고 하십시오.

이제 GetConnectionString 메서드를 살펴 보도록 하겠습니다.

public static string GetConnectionString(string connectionStringName)
{
    if (ConfigurationHelper.ConnectionHash != null)
    {
        if (ConfigurationHelper.ConnectionHash[connectionStringName] != null)
        {
            return ConfigurationHelper.ConnectionHash[connectionStringName].ToString();
        }
    }
    else
    {
        ConfigurationHelper.ConnectionHash = new Hashtable();
    }
    string returnValue = string.Empty;

    DBConnectionSection section = ConfigurationHelper.Ancestor.DbConnectionSection;
    if (section == null)
    {
        return String.Empty;
    }
    if (!String.IsNullOrEmpty(section.ConnectionStrings[connectionStringName].Parameters["securityType"]))
    {
        if (String.IsNullOrEmpty(section.ConnectionStrings[connectionStringName].Parameters["keySize"]))
        {
            section.ConnectionStrings[connectionStringName].Parameters["keySize"] = "128";
        }

        try
        {
            object secuityProviderBase = null;
            Assembly asm = ConfigurationHelper.IsWebForm 
               ? Assembly.LoadFrom(HttpContext.Current.Server.MapPath("/bin/RPNetworks.Security.dll")) 
               : Assembly.LoadFrom("RPNetworks.Security.dll");
            MethodInfo[] methodInfos = asm.GetType("RPNetworks.Security.SecurityProviderBase")
                                       .GetMethods(BindingFlags.Static | BindingFlags.Public);
            for (int i = 0; i < methodInfos.Length; i++)
            {
                if (methodInfos[i].GetParameters().Length == 2)
                {
                    secuityProviderBase = methodInfos[i].Invoke(null, new object[] { 
                         Convert.ToInt32(section.ConnectionStrings[connectionStringName]
                                                             .Parameters["securityType"]), 
                         Convert.ToInt32(section.ConnectionStrings[connectionStringName]
                                                             .Parameters["keySize"]) 
                    });
                    break;
                }
            }

            if (secuityProviderBase != null)
            {
                MethodInfo info1 = secuityProviderBase.GetType().BaseType.GetMethod("CreateMasterKey");
                info1.Invoke(secuityProviderBase, new object[] { connectionStringName });
                info1 = secuityProviderBase.GetType().BaseType.GetMethod("DecryptFromString");
                returnValue = info1.Invoke(secuityProviderBase, new object[] {
                    section.ConnectionStrings[connectionStringName].Parameters["connectionString"] 
                }).ToString();
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
    else
    {
        returnValue = section.ConnectionStrings[connectionStringName].Parameters["connectionString"];
    }
    ConfigurationHelper.ConnectionHash[connectionStringName] = returnValue;
    return returnValue;
}

ConfigurationHelper.ConnectionHash 라는 해쉬테이블은 한번 읽어온 연결 문자열을 저장해 놓기 위해 사용합니다.

30행 부터는 config에 정의된 값을 기반으로 리플렉션을 이용하여 윈폼과 웹폼일때 각 해당 폴더에 Security.dll 파일을 읽어와서 DecryptFromString() 메서드를 호출하여 복호화 하는 일련의 과정입니다.

복호화가 되면 이를 해쉬 테이블에 저장합니다.

해쉬테이블에 저장하는 이유는 연결 문자열은 아주 빈번하게 사용되지만 이를 호출시 마다 리플렉션을 이용하여 복호화 하는 것은 힘겹기 때문입니다. 이때문에 최초에 한번 복호화 하여 이를 저장한다면 이후 부터는 바로 이 값을 가져다 쓰게 되니 복호화 과정이 생략되게 되는 겁니다.

이리 하여 복호화 된 연결 문자열을 얻게 되었습니다.


마지막 업데이트 : (1/5/2011 5:22:11 PM)




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