배움터  
  HOME > 배움터 > Daily Tip
Daily Tip

제품:   Access 버전:   2003
검색어:   보안, 공유, 키, AllowBypassKey, 로그인, 보안, 권한, 모듈, 개체
제목:   공유 그리고 보안…여덟번째
     
 

STEP
  STEP> 따라하기
 
※ 아래 Daily Tip은 최천군님이 제공해주신 내용입니다.

이전에 아래의 코드를 소개 했었습니다. 간단히 짚고 넘어 가겠습니다.

1. AllowBypassKey

Sub SetBypassProperty()
Const DB_Boolean As Long = 1
    ChangeProperty "AllowBypassKey", DB_Boolean, False
End Sub

이 서브 프로시져는 아래의 함수 프로시져를 실행 하기 위한 프로시져 입니다.


ChangeProperty "AllowBypassKey", DB_Boolean, False

위와 같이 ChangeProperty함수 프로시져에 세가지 인수를 주어 실행을 시킵니다. 첫번째 인수 “AllowBypassKey”는 mdb파일의 Property명 입니다.

Function ChangeProperty(strPropName As String, varPropType As Variant, varPropValue As Variant) As Integer
    Dim dbs As Object, prp As Variant
    Const conPropNotFoundError = 3270
    Set dbs = CurrentDb
    On Error GoTo Change_Err
    dbs.Properties(strPropName) = varPropValue
    ChangeProperty = True
Change_Bye:
    Exit Function
Change_Err:
    If Err = conPropNotFoundError Then    ' Property not found.
        Set prp = dbs.CreateProperty(strPropName, _
            varPropType, varPropValue)
        dbs.Properties.Append prp
        Resume Next
    Else
        ' Unknown error.
        ChangeProperty = False
        Resume Change_Bye
    End If
End Function

위의 함수가 작동되면 다음과 같은 작업을 수행합니다.

1. 현재의 mdb파일의 속성에서 “AllowBypassKey”라는 이름의 속성을 찾아 속성값을 False로 변경합니다.

2. 만약 “AllowBypassKey”라는 속성이 현재 mdb파일에 없다면 그 이름으로 새로운 Property 개체를 만듭니다.

3. 만든 Property개체를 mdb파일의 Properties 컬렉션에 추가합니다.

위와 같은 작업을 해주는 것이 상기의 ChangeProperty() 함수 코드입니다.

이 함수 프로시져를 응용하면 파일의 버전을 기록할 Property를 생성하여 버전관리에 사용하는 등에 편리하게 사용할 수 있습니다.

이렇게 여러 가지 사용자가 임의로 파일의 Property를 생성 삭제할 수 있는데 그 중 “AllowBypassKey”라는 Property만이 값에 의해 파일을 열 때 Shift키를 사용할 수 있게 할 것인가 못하게 할 것인가를 결정해 주게 됩니다.

그렇다면 위와 같은 서브 프로시져로 Shift키 사용을 완벽하게 막을 수 있는가? 위의 코드는 자신의 Property 뿐만 아니라 다른 mdb 파일의 Property 값도 바꿀 수 있습니다.

예를 들면 Set dbs = CurrentDb 이 부분을
Set dbs = OpenDatabase(“경로 및 파일명”,False,False) 이렇게 다른 파일을 불러내어 그 속성값을 변경할 수 있습니다.

그렇다면 아무짝에도 쓸데없는 기능 아닌가?

2. 로그인 시스템

불특정 다수의 사용자에 대한 권한 관리하기 위해서는 먼저 자체적인 로그인 시스템이 필요합니다. 포털 사이트에 회원 가입을 하고 적절한 권한을 부여 받는 것과 같은 형식의 로그인 시스템을 개발하면 될 것입니다. 이것을 위해서는 다음과 같은 형식의 테이블이 필요할 것 입니다.

또한 사용자 등록폼로그인 폼이 필요하겠지요.

로그인 창을 통해 확인된 사용자의 정보를 테이블에 저장하거나 위에서 언급된 Property를 이용하거나 전역변수에 저장해 두거나 컨트롤의 Tag 속성 등에 기록해 두고 폼이나 메뉴에 접근할 때 권한이 있는가 여부를 확인하여 제한할 수 있을 것입니다.

예를 들어 사용자의 ‘권한1’ 필드의 정보로 BypassKey (Shift ) 사용할 수 있게 할 것인가 아닌가의 권한을 제한 한다고 하면 로그인한 사용자의 ‘권한1’에 대한 정보와 현재 파일의 AllowBypassKey Property의 값이 상응하는가를 확인하여 BypassKey (Shift ) 사용할 권한이 없는 사용자이고 현재 파일의 AllowBypassKey 속성이 True 일 때, 아래와 같이 예의 함수를 사용하면 될 것입니다.

ChangeProperty "AllowBypassKey", DB_Boolean, False
DoCmd.Quit

그러나 외부에서 현재 파일의 AllowBypassKey 값을 True로 바꾸고 바로 Shift 를 이용하여 파일을 열면 모든 데이터 베이스 정보가 노출되는 것이 아닌가?

3. 작업그룹파일 보안

불특정 다수의 사용자에 대한 권한을 제어하기 위해 다음과 같이 작업 그룹 보안을 설정 하십시오. <새 개체(테이블 쿼리 등)>에 대한 권한설정도 똑같이 해 줍니다.

1. Admin계정을 Users그룹에만 소속되게 합니다.

2. Admin계정의 모든 권한을 삭제합니다.

3. Users그룹계정의 권한을 아래와 같이 설정합니다.
   1) ‘데이터베이스’의 권한 중 ‘열기/실행’ 권한에만 체크 합니다.
   2) 모든 테이블의 권한을 삭제합니다.
   3) 모든 쿼리의 권한에서 ‘디자인 수정’과 ‘관리’항목의 권한을 삭제합니다.
      나머지는 모두 체크 합니다.
   4) 나머지 개체들의 권한을 모두 체크 합니다. ‘관리’항목의 권한은 삭제 해
      도 무방합니다.

4. 모든 권한을 가지고 있는 계정으로 파일을 다시 엽니다.

5. 지난번 팁에서 소개한 요령과 같이 모든 권한을 가지고 있는 계정이 모든 개체의 소유자가 되게 합니다.

이렇게 하면 Admin 계정으로 접근하는 불특정한 사용자가 AllowBypassKey의 속성을 변경하고 Shift키를 사용하여 파일을 열었을 때 어떠한 일이 발생할까요?

모든 테이블을 열 수 없습니다. 그러나 쿼리를 통해 접근하는 정보를 그대로 노출됩니다.

이것이 문제라면 다음과 같은 방법을 적용하면 됩니다.

1. 쿼리를 생성하지 않고 폼의 레코드 원본에 직접 SQL을 만들어 줍니다. 물론 WITH OWNERACCESS OPTION 문장이 포함되어야 합니다. 이처럼 쿼리만이 아니라 폼의 레코드 원본에도 소유자 권한 위임 방식을 사용할 수 있습니다. 이 때 주의하실 것은 필터링을 하기 위해 코드를 통하여 폼의 레코드 원본을 수정하면 소유자가 Admin이 되어버리기 때문에 데이터베이스에 접근 할 수 없게 됩니다.

2. 쿼리를 생성하되 폼에 의해 매개변수가 주어지는 QBF(Query By Form)형식의 쿼리를 생성하고 쿼리에 바운딩 된 폼의 On Open/On Load 이벤트에 위에서 언급한 바와 같이 현재 사용자가 AllowBypassKey를 사용할 권한이 있는지 여부를 확인한 뒤 아니라면 설정을 바꾸고 종료하는 코딩을 해 줍니다. 이와 같이 하면 다음과 같은 일이 발생할 것입니다.

쿼리를 통해 데이터에 접근하려고 더블 클릭하면 매개변수 값 입력 창이 열리고 적절한 값을 입력해야만 데이터가 나타날 것입니다. 폼을 열고 쿼리의 데이터를 확인하려고 폼을 열면 작성해 둔 코드가 실행 되면서 AllowBypassKey 값을 바꾸고 종료될 것입니다.

3. 그러나 이런 방법을 응용하면 쿼리를 생성하더라도 더욱 세부적으로 견고하고 간편하게 보안을 설정할 수 있습니다.

4. 권한에 따라 레코드별로 접근을 제한하기

레코드마다 권한에 따라 접근을 허용하게 하려면 우선 레코드마다 어느 정도의 권한이 필요한지에 대한 정보가 있어야 할 것입니다. 때문에 아래와 같이 권한 정보를 설정해 둘 필드 하나를 생성합니다. 기본값은 0 으로 하였습니다.

그리고 아래와 같이 권한을 설정하였습니다. 중요한 레코드에만 설정해 주면 될 것입니다.

이제 전역변수나, 컨트롤의 Tag속성이나 테이블 등에 저장해 둔 사용자의 정보 중 권한2의 값을 찾아서 반환하는 함수를 아래와 같이 모듈에서 작성합니다.

Function Cur권한2()
Cur권한2=Forms!HiddenForm!권한2.Tag
End Function

위의 함수는 예제일 뿐입니다. 실제 내용은 어떻게 로그인 시스템을 작성하였는가에 따라 달라질 것입니다.

이제 다음과 같이 쿼리를 작성합니다.

Select * From 테이블 Where 권한2=Cur권한2()

AllowBypassKey를 사용하여 파일을 열었다면 위의 쿼리에서 아무런 데이터도 볼 수 없을 것입니다.

그런데 위와 같이 하면 레코드가 많을 경우 레코드 마다 값을 찾는 코드가 실행 되기 때문에 느려지고 비효율적이지 않을까요?

이전에 ‘무작위로 레코드 추출하기’에서 말씀 드린 바와 같이 함수의 인수 내용이 바뀌지 않는 한 계산은 한 번만 합니다. 그러므로 전혀 느려지지 않습니다.

또한 위와 같은 방법을 응용하여 AllowBypassKey 값을 변경하여 파일을 연 사용자에게 모든 쿼리의 데이터를 숨길 수 있습니다.

5. 전체 데이터 숨기기

위와 같은 방법들을 응용하여 보다 적극인 보안장치를 설치할 수 있습니다.

아래와 같이 함수를 작성합니다.

Function MyPass()
    MyPass=1
End Function

Function Cur
권한1()
    Cur권한1= Forms!HiddenForm!권한1.Tag
End Function

이제 아래와 같이 쿼리를 작성합니다.

SELECT * FROM 테이블
WHERE Mypass()=Cur권한1()

쿼리를 열 때, HiddenForm 이 열려져 있지 않다면 에러만 발생할 것이고 폼을 연다면 폼의 On Open 코드에 의해 사용자의 권한을 확인할 것입니다.

Function Cur권한1()
    Cur권한1= Forms!HiddenForm!권한1.Tag
End Function

위의 함수는 폼의 컨트롤을 이용했는데 전역변수를 사용 한다고 해도 문제 되지 않습니다. 권한이 없는 사용자가 쿼리를 열면 아무 데이터도 나타나지 않을 것입니다.

필요한 경우 암호를 한번 가르쳐 주고 암호를 자동으로 변경하여 데이터를 보호 하려면 아래의 코드를 응용해 보십시오.

Function MyPass()
    Dim CurPass
    Dim CrtPass As Integer
    CurPass = Forms!CrChk.Tag
    CrtPass = Int(Rnd() * 9999)
    Forms!CrChk.Tag = CrtPass
    MyPass = CurPass
End Function

쿼리에서는 다음과 같은 식으로 사용하면 됩니다.

SELECT *
FROM Menu
WHERE Mypass()=[Forms]![CrChk].Tag

쿼리가 열릴 때 마다 암호가 바뀌게 됩니다.

6. 모듈 보안

모듈이나 폼의 디자인이나 매크로 디자인을 숨기는 것은 간단합니다. VB 에디트 창에서 프로텍트를 거는 방법도 있지만 간단히 도구-데이터베이스 유틸리티-MDE파일 만들기를 차례로 실행해 주면 됩니다. 이것을 실행하기 전에 압축 및 복구를 실행해 주는 것이 좋습니다.

이렇게 MDE 파일로 만들면 여러 가지 이점이 있으며 절대적으로 모듈의 내용을 보거나 변경할 수 없게 됩니다.

7. 개체 가져오기

일전에 말씀 드린 바와 같이 개체 가져오기를 하면 모든 정보가 그대로 노출되게 됩니다. 위와 같은 보안 설정이 이루어 지면 어떻게 될까요?

어떤 테이블을 가져오지 못합니다. 때문에 나머지 모든 개체를 가져 오더라도 어떠한 정보도 노출되지 않습니다. 

이러한 방법들의 중심에는 작업그룹파일을 이용한 액세스 자체의 강력한 보안 장치가 뒷받침 되고 있기에 가능한 것입니다.

아직도 반은 남은 것 같습니다. 그 나머지 반은 여러분의 상상력에 있습니다. 
상상력을 멋지게 발휘한다면 더 좋고 편리한 보안 장치들을 개발할 수 있을 것입니다. 또한 이러한 것은 비단 보안장치에 국한 되는 것은 아니겠지요. 

위의 방법들을 보안에만 국한되지 않고 다른 부분에도 적용할 수 있을 것입니다. 문제는 상상력이지요. 상상력을 발휘하여 응용력을 펼쳐 보이십시오. ^^