출처 : http://blog.naver.com/tit99hds?Redirect=Log&logNo=130017643620


ASP.NET 보안.

 

1. 개요.

 

사용자를 확인하고 리소스에 대한 액세스를 제어하는 기능은 많은 웹 응용 프로그램에서 중요한 부분에 속합니다.

요청 엔터티의 ID를 확인하는 것을 인증이라고 합니다.

일반적으로 인증을 받기 위해 이름/암호 쌍 같은 자격 증명을 입력해야 합니다.

ID를 인증한 다음에는 해당 ID가 특정 리소스에 액세스할 수 있는지 여부를 확인해야 합니다.

이러한 과정을 권한 부여라고 합니다.

ASP.NET IIS와 함께 응용 프로그램에 대한 인증 및 권한 부여 서비스를 제공합니다.

COM 개체에는 ID를 제어할 수 있는 중요한 기능이 있습니다.

COM 개체 코드는 이 ID 아래에서 실행됩니다.

COM 개체가 요청 엔터티의 ID를 사용하여 코드를 실행하는 것을 가장이라고 합니다.

ASP.NET Framework 응용 프로그램은 필요에 따라 요청을 가장하도록 선택할 수 있습니다.

일부 응용 프로그램에서는 요청 ID에 따라 또는 요청 ID가 속한 역할 집합에 따라 표시되는 내용이 동적으로 변경되도록 할 수 있습니다.

ASP.NET Framework 응용 프로그램은 현재 요청 ID가 특정 역할에 참여하는지 여부를 동적으로 확인할 수 있습니다.

예를 들어, 응용 프로그램은 관리자에 대한 내용을 조건에 따라 생성하기 위해 현다시 사용자가 관리자 역할에 속하는지 여부를 확인할 수도 있습니다.

 

 

2. 인증 및 권한 부여.

 

ASP.NET IIS와 함께 사용되어 기본, 다이제스트 및 Windows 인증 방식을 지원합니다.

또한 ASP.NET에서는 단일 로그온 서비스와 사용자 프로필 서비스를 사용할 수 있는 Microsoft Passport 인증 서비스를 지원하며,

폼 기반의 인증을 사용하는 응용 프로그램에 강력한 서비스도 제공합니다.

폼 기반의 인증은 쿠키를 사용하여 사용자를 인증하고 응용 프로그램 자체에서 자격 증명 확인을 수행할 수 있게 합니다.

ASP.NET 인증 서비스는 IIS에서 제공하는 인증 서비스를 따른다는 사실을 이해할 필요가 있습니다.

예를 들어, IIS 응용 프로그램에서 기본 인증을 사용하려면 인터넷 서비스 관리자 도구를 사용하는 응용 프로그램에 맞게 기본 인증을 구성하여 사용해야 합니다.

ASP.NET에는 다음 두 가지 방식의 인증 서비스가 있습니다.

(1) 리소스에 대한 ACL이나 사용 권한을 검사하여 인증된 사용자 계정이 해당 리소스에 액세스할 수 있는지 여부를 확인하는 방식

(2) 웹 공간에 대해 ID를 인증하는 URL 인증 방식

IUSR_MYMACHINE 계정을 사용하여 익명으로 액세스할 수 있도록 응용 프로그램을 구성하는 시나리오를 만들면 차이점을 쉽게 이해할 수 있습니다.

ASP.NET 페이지(: "/default.aspx")에 대한 요청이 인증되면 IUSR_MYMACHINE 계정에 파일을 읽을 수 있는 권한이 있는지 여부를 확인하기 위해

해당 파일(: "c:\inetpub\wwwroot\default.aspx") ACL을 검사합니다.

권한이 있으면 액세스가 인증되고, 파일 인증은 자동으로 수행됩니다.

URL 인증의 경우에는 ASP.NET 응용 프로그램에서 사용하기 위해 계산된 구성 데이터에 익명 사용자가 액세스할 수 있는지 여부를 검사합니다.

요청된 URL에 액세스할 수 있으면 요청이 인증됩니다.

이 경우, ASP.NET에서는 익명 사용자가 /Default.aspx에 액세스할 수 있는지 여부를 확인하기 위한 검사를 수행합니다.

이 검사의 대상은 해당 URL이 가리키는 파일이 아니라 URL 자체입니다.

미세한 차이 같지만, 이를 통해 사용자가 시스템 또는 도메인 계정에 해당되지 않는

폼 기반의 인증이나 Passport 인증 같은 인증 스키마를 응용 프로그램에서 사용할 수 있게 됩니다.

또한 해당 리소스를 원본으로 사용하는 물리적 파일이 없는 가상 리소스에 대해서도 인증할 수 있습니다.

예를 들어, .stk로 끝나는 파일에 대한 모든 요청을 쿼리 문자열에 있는 변수에 따라 주식 시세를 보여 주는 처리기에 매핑하도록 응용 프로그램에서 선택할 수 있습니다.

이러한 경우 ACL 검사를 수행할 물리적 .stk 파일이 없으므로 가상 리소스에 대한 액세스를 제어하는 데 URL 인증이 사용됩니다.

IIS에서 제공하는 인증 계정에서는 항상 파일 인증을 수행합니다.

익명 액세스가 허용되면 이 인증 계정은 구성된 익명 계정이 되며, 허용되지 않으면 NT 계정이 사용됩니다. 이 방식은 ASP에서도 동일합니다.

Explorer 속성 페이지의 보안 탭에서 지정한 파일이나 디렉터리에 대한 파일 ACL을 설정합니다.

URL 인증은 ASP.NET Framework 응용 프로그램의 일부로 구성됩니다.

ASP.NET 인증 서비스를 사용하려면 응용 프로그램의 구성 파일에서 <authentication> 요소를 구성해야 합니다.

이 요소는 다음 표에 나열된 값을 가질 수 있습니다.

 

설명

없음

사용할 수 있는 ASP.NET 인증 서비스는 없지만, IIS 인증 서비스는 여전히 사용할 수 있습니다.

Windows

ASP.NET 인증 서비스에서는 NT 사용자나 그룹을 인증하기 위해 현재 요청에 WindowsPrincipal(System.Security.Principal.WindowsPrincipal)을 첨부합니다.

Form

ASP.NET 인증 서비스에서는 쿠키를 관리하여 인증되지 않은 사용자를 로그온 페이지로 리디렉션합니다. 이 서비스는 대개 응용 프로그램에 익명으로 액세스하기 위해 IIS 옵션과 함께 사용됩니다.

Passport

Passport SDK를 시스템에 설치하면 ASP.NET 인증 서비스에서는 Passport SDK에서 제공하는 서비스에 대한 편리한 래퍼를 제공합니다.

 

예를 들어, 다음 구성 파일에서는 응용 프로그램에 대해 폼 기반(쿠키) 인증을 사용할 수 있습니다.

 

<configuration>

  <system.web>

    <authentication mode="Forms"/>

  </system.web>

</configuration>

 

 

3. Windows 기반 인증.

 

ASP.NET Windows 인증을 사용할 때 ASP.NET에서는 WindowsPrincipal 개체를 현재 요청에 연결합니다.

이 개체는 URL 권한 부여에 사용됩니다.

또한 응용 프로그램에서는 요청하는 ID가 특정 역할을 가지고 있는지 확인하는 데 이 개체를 사용합니다.

 

if(User.IsInRole("Administrators")) {

    DisplayPrivilegedContent();

}

 

If User.IsInRole("Administrators") Then

    DisplayPrivilegedContent()

End If

 

if(User.IsInRole("Administrators")) {

    DisplayPrivilegedContent();

}

 

WindowsPrincipal 클래스는 NT 그룹 등록에 따라 역할을 확인합니다.

자체의 역할을 확인하려는 응용 프로그램에서는 다음 예제에서 보여 주는 것처럼

Global.asax 파일에서 WindowsAuthentication_OnAuthenticate 이벤트를 처리하고

System.Security.Principal.IPrincipal을 구현하는 해당 응용 프로그램의 클래스를 요청에 연결하면 역할을 확인할 수 있습니다.

 

// Create a class that implements IPrincipal

public class MyPrincipal : IPrincipal {

  // implement application-defined role mappings

}

 

// In a Global.asax file:

public void WindowsAuthentication_OnAuthenticate(Object Source, WindowsAuthenticationEventArgs e) {

  // Attach a new application-defined class that implements IPrincipal to

  // the request.

  // Note that since IIS has already performed authentication, the provided

  // identity is used.

  e.User = new MyPrincipal(e.Identity);

}

 

' Create a class that implements IPrincipal

Public Class MyPrincipal : Inherits IPrincipal

  ' Implement application-defined role mappings

End Class

 

' In a Global.asax file

Public Sub WindowsAuthentication_OnAuthenticate(Source As Object, e As WindowsAuthenticationEventArgs)

  ' Attach a new application-defined class that implements IPrincipal to

  ' the request.

  ' Note that since IIS has already performed authentication, the provided

  ' identity is used.

  e.User = New MyPrincipal(e.Identity)

End Sub

 

// Create a class that implements IPrincipal.

public class MyPrincipal implements IPrincipal {

  // Implement application-defined role mappings.

}

 

// In a Global.asax file

public function WindowsAuthentication_OnAuthenticate(Source:Object, e:WindowsAuthenticationEventArgs) : void {

  // Attach a new application-defined class that implements IPrincipal to

  // the request.

  // Note that since IIS has already performed authentication, the provided

  // identity is used.

  e.User = new MyPrincipal(e.Identity);

}

 

다음 샘플에서는 User.Identity.Name으로 사용할 수 있는 인증된 사용자 이름에 액세스하는 방법을 보여 줍니다.

ASP에 익숙한 프로그래머라면 이 값을 AUTH_USER 서버 변수로도 사용할 수 있음을 주목해야 합니다.

 

 

<html>

 

  <script language="C#" runat=server>

 

    void Page_Load(Object Src, EventArgs E ) {

 

      AuthUser.Text = User.Identity.Name;

      AuthType.Text = User.Identity.AuthenticationType;

    }

 

  </script>

 

  <body>

 

    <h3><font face="굴림">Windows 인증 사용</font></h3>

 

    <table Width="700" rules="all" bordercolor="Black" style="background-color:#ccccff;bordercolor:black;font-family:굴림;font-size:9pt;border-collapse:collapse;">

      <tr>

        <td>사용자:</td>

        <td><asp:label id=AuthUser runat=server/>

      </tr>

      <tr>

        <td>인증 형식:</td>

        <td><asp:label id=AuthType runat=server/>

      </tr>

    </table>

 

  </body>

 

</html>

 

/* web.config */

 

<configuration>

  <system.web>

    <authentication mode="Windows" />

    <globalization requestEncoding="UTF-8" responseEncoding="UTF-8" />

  </system.web>

</configuration>

 

 

 

4. Form 기반 인증.

 

ASP.NET의 인증 서비스는 폼 기반의 인증으로, 이 인증 방식을 사용하면 응용 프로그램에서

해당 응용 프로그램 고유의 로그온 UI를 제공하고, 고유한 자격 증명을 확인할 수 있습니다.

ASP.NET은 인증되지 않은 사용자를 로그온 페이지로 리디렉션하고 필요한 모든 쿠키를 관리하는 방식으로 사용자를 인증합니다.

이 인증 방식은 많은 웹 사이트에서 사용되는 인기 있는 기술입니다.

익명 사용자가 액세스할 수 없게 <authentication>Forms으로 설정한 폼 기반의 인증을 사용하도록 응용 프로그램을 구성해야 합니다.

다음 예제에서는 해당 응용 프로그램의 Web.config 파일에서 이 작업을 수행하는 방법을 보여 줍니다.

 

<configuration>

  <system.web>

    <authentication mode="Forms"/>

    <authorization>

        <deny users="?" />

    </authorization>

  </system.web>

</configuration>

 

폼 기반의 인증을 사용하여 관리자는 사용할 쿠키의 이름, 보호 유형, 로그온 페이지에 사용할 URL, 쿠키 유효 기간 및 발생한 쿠키에 사용할 경로를 구성합니다.

다음 표에서는 아래 예제에 나와 있는 <authentication> 요소의 하위 요소인 <Forms> 요소에 유효한 특성을 보여 줍니다.

 

<authentication mode="Forms">

   <forms name=".ASPXCOOKIEDEMO" loginUrl="login.aspx" protection="all" timeout="30" path="/">

      <!-- protection="[All|None|Encryption|Validation]" -->

   </forms>

</authentication>

 

특성

설명

loginUrl

인증되지 않은 사용자가 리디렉션되는 로그온 URL, 같은 컴퓨터나 원격 컴퓨터에 있습니다. 원격 컴퓨터에 있으면 양쪽 컴퓨터에서는 decryptionkey 특성에 대해 같은 값을 사용해야 합니다.

name

인증을 위해 사용할 HTTP 쿠키의 이름입니다. 여러 응용 프로그램에서 한 컴퓨터에 있는 폼 기반의 인증 서비스를 사용하려면 응용 프로그램마다 고유한 쿠키 값을 구성해야 합니다. URL에 종속 관계가 생기는 것을 방지하기 위해 ASP.NET에서는 인증 쿠키 설정 시 경로 값으로 "/"를 사용하여 사이트의 모든 응용 프로그램에 인증 쿠키를 다시 보냅니다.

timeout

쿠키가 만료되기까지의 시간()으로 정수로 표시됩니다. 기본값은 30입니다. timeout 특성은 마지막 요청을 받은 뒤 n분 후에 만료되는 슬라이딩 값입니다. 성능 저하를 방지하고 쿠키 경고를 설정한 사용자에게 브라우저 경고가 여러 번 표시되는 것을 방지하기 위해 시간이 반 이상 지나면 쿠키가 업데이트됩니다. 따라서 일부의 경우에 정밀도가 떨어질 수도 있습니다.

path

발생된 쿠키에 사용할 경로로, 기본값은 "/"입니다. 쿠키가 반환될 때 브라우저에서 대소문자를 구분하기 때문에 "/"를 사용하면 경로의 대소문자가 일치하지 않아 발생하는 문제를 방지할 수 있습니다. 공유 서버 환경의 응용 프로그램에서는 이 지시문을 사용하여 개인 쿠키를 관리해야 합니다. 또는 쿠키를 발생시키기 위해 API를 사용하여 런타임에 경로를 지정할 수도 있습니다.

protection

쿠키 데이터를 보호하는 데 사용되는 메서드로, 유효한 값은 다음과 같습니다.

All: 데이터 유효성 검사와 암호화를 사용하여 쿠키를 보호합니다. 구성된 데이터 유효성 검사 알고리즘은 요소를 기반으로 합니다. Triple DES를 사용할 수 있고 키가 48바이트이면 암호화에 Triple DES가 사용됩니다. 기본(권장)값은 All입니다.

None: 맞춤 정보를 제공하기 위해서만 쿠키를 사용하는 사이트와 보안 요구 사항이 낮은 사이트에 사용합니다. 암호화와 유효성 검사를 비활성화할 수 있습니다. 이처럼 쿠키를 사용하는 경우 주의가 필요하지만 이렇게 설정하면 .NET Framework를 사용하여 맞춤 정보를 제공하는 모든 방법에서 성능을 향상시킬 수 있습니다.

Encryption: TripleDES DES를 사용하여 쿠키를 암호화합니다. 그러나 해당 쿠키의 데이터 유효성을 검사하지는 않습니다. 이러한 유형의 쿠키는 일반 텍스트 공격의 대상이 되기 쉽습니다.

Validation: 쿠키의 내용을 암호화하지 않지만 전환 시 쿠키 데이터가 변경되지 않았는지 확인합니다. 쿠키를 만들기 위해 유효성 검사 키가 버퍼에서 쿠키 데이터와 연결되고 MAC가 계산되어 나가는 쿠키에 추가됩니다.

 

응용 프로그램이 구성되면 로그온 페이지를 만들어야 합니다.

다음 샘플에서는 간단한 로그온 페이지를 보여 줍니다.

이 샘플이 실행되면 Default.aspx 페이지가 요청됩니다.

인증되지 않은 요청의 경우에는 전자 메일 주소와 암호를 묻는 간단한 폼이 있는 로그온 페이지(Login.aspx)로 리디렉션됩니다.

로그온 페이지가 표시되면 사용자 이름 "jdoe@somewhere.com"과 암호 "password"를 사용하여 로그온하십시오.

액세스 권한이 있는지 확인한 다음 응용 프로그램에서 다음을 호출합니다.

 

FormsAuthentication.RedirectFromLoginPage(UserEmail.Value, PersistCookie.Checked);

FormsAuthentication.RedirectFromLoginPage(UserEmail.Value, PersistCookie.Checked);

 

이 샘플에서는 원래 요청한 URL로 사용자를 다시 리디렉션합니다.

응용 프로그램에서 리디렉션하지 않는 경우 FormsAuthentication.GetAuthCookie를 호출하여 쿠키 값을 검색하거나

FormsAuthentication.SetAuthCookie를 호출하여 올바르게 암호화된 쿠키를 나가는 응답에 연결할 수 있습니다.

포함하는 페이지에 로그온 UI를 삽입하거나 사용자가 리디렉션되는 위치를 세부적으로 제어할 응용 프로그램에는 이 기술이 유용합니다.

인증 쿠키는 임시 쿠키와 영구 쿠키로 나뉩니다.

임시 쿠키는 현재 브라우저의 세션 동안에만 지속됩니다.

따라서, 브라우저를 닫으면 쿠키도 없어집니다.

영구 쿠키는 브라우저에 의해 저장되어 사용자가 명시적으로 삭제하지 않는 한 여러 브라우저 세션에 걸쳐 다시 보내집니다.

 

/* default.aspx */

<%@ Import Namespace="System.Web.Security " %>

<html>

  <script language="C#" runat=server>

    void Page_Load(Object Src, EventArgs E ) {

      Welcome.Text = "Hello, " + User.Identity.Name;

    }

    void Signout_Click(Object sender, EventArgs E) {

      FormsAuthentication.SignOut();

      Response.Redirect("login.aspx");

    }

  </script>

  <body>

    <h3><font face="굴림">쿠키 인증 사용</font></h3>

    <form runat=server>

      <h3><asp:label id="Welcome" runat=server/></h3>

      <asp:button text="로그아웃" OnClick="Signout_Click" runat=server/>

    </form>

  </body>

</html>

 

/* login.aspx */

<%@ Import Namespace="System.Web.Security " %>

<html>

  <script language="C#" runat=server>

    void Login_Click(Object sender, EventArgs E) {

      // authenticate user: this samples accepts only one user with

      // a name of jdoe@somewhere.com and a password of 'password'

      if ((UserEmail.Value == "jdoe@somewhere.com") && (UserPass.Value == "password")) {

        FormsAuthentication.RedirectFromLoginPage(UserEmail.Value, PersistCookie.Checked);

      }

      else {

        Msg.Text = "Invalid Credentials: Please try again";

      }

    }

  </script>

  <body>

    <form runat=server>

      <h3><font face="굴림">로그인 페이지</font></h3>

      <table>

        <tr>

          <td>전자 메일:</td>

          <td><input id="UserEmail" type="text" runat=server/></td>

          <td><ASP:RequiredFieldValidator ControlToValidate="UserEmail" Display="Static" ErrorMessage="*" runat=server/></td>

        </tr>

        <tr>

          <td>암호:</td>

          <td><input id="UserPass" type=password runat=server/></td>

          <td><ASP:RequiredFieldValidator ControlToValidate="UserPass" Display="Static" ErrorMessage="*" runat=server/></td>

        </tr>

        <tr>

          <td>지속적 쿠키:</td>

          <td><ASP:CheckBox id=PersistCookie runat="server" /> </td>

          <td></td>

        </tr>

      </table>

      <asp:button text="로그인" OnClick="Login_Click" runat=server/>

      <p>

      <asp:Label id="Msg" ForeColor="red" Font-Name="Verdana" Font-Size="10" runat=server />

    </form>

  </body>

</html>

 

/* web.config */

<configuration>

  <system.web>

      <authentication mode="Forms">

        <forms name=".ASPXUSERDEMO" loginUrl="login.aspx" protection="All" timeout="60" />

      </authentication>

      <authorization>

        <deny users="?" />

      </authorization>

    <globalization requestEncoding="UTF-8" responseEncoding="UTF-8" />

  </system.web>

</configuration>

 

폼 인증에서 사용되는 인증 쿠키는 선형 버전의 System.Web.Security.FormsAuthenticationTicket 클래스로 구성되어 있습니다.

이 정보에는 사용자 이름, 사용된 폼 인증 버전, 쿠키가 발생된 날짜, 선택적 응용 프로그램 관련 데이터 필드 등이 포함되지만 암호는 포함되지 않습니다.

응용 프로그램 코드에서 FormsAuthentication.SignOut 메서드를 사용하여 인증 쿠키를 해지하거나 제거할 수 있습니다.

이 메서드는 인증 쿠키가 임시 쿠키인지 또는 영구 쿠키인지에 관계 없이 인증 쿠키를 제거합니다.

또한 다음 샘플처럼 구성을 사용하여 폼 기반의 인증 서비스에 유효한 자격 증명 목록을 포함할 수도 있습니다.

 

<authentication>

    <credentials passwordFormat="SHA1" >

        <user name="Mary" password="GASDFSA9823598ASDBAD"/>

        <user name="John" password="ZASDFADSFASD23483142"/>

    </credentials>

</authentication>

 

이렇게 하면 사용자 이름과 암호를 제공하는 FormsAuthentication.Authenticate를 응용 프로그램에서 호출할 수 있게 되고,

ASP.NET에서는 자격 증명을 확인합니다.

자격 증명은 passwordFormat 특성의 다음 값에 따라 일반 텍스트, SHA1 또는 MD5 해시로 저장될 수 있습니다.

 

해시 유형

설명

Clear

암호가 일반 텍스트로 저장됩니다

SHA1

암호가 SHA1 다이제스트로 저장됩니다.

MD5

암호가 MD5 다이제스트로 저장됩니다.

 

 

5. 사용자 및 역할 권한 부여.

 

ASP.NET URL 리소스에 대한 클라이언트 액세스를 제어하는 데 사용됩니다.

이 인증은 GET이나 POST같은 요청을 수행하는 데 사용되는 HTTP 메서드를 위해 구성될 수 있으며

사용자 그룹이나 역할에 액세스를 허용하거나 거부하도록 구성될 수도 있습니다.

다음 예제에서는 John이라는 사용자와 Admins라는 역할에 부여되는 액세스 권한을 보여 줍니다.

다른 모든 사용자는 액세스할 수 없습니다.

 

<authorization>

    <allow users="jdoe@somewhere.com" />

    <allow roles="Admins" />

    <deny users="*" />

</authorization>

 

인증 지시문에서 사용할 수 있는 요소는 allow 또는 deny입니다.

allow 또는 deny 요소에는 usersroles 특성이 들어 있어야 합니다.

쉼표로 구분하여 한 요소에 여러 사용자나 역할을 지정할 수 있습니다.

 

<allow users="John,Mary" />

 

Verb 특성을 사용하여 HTTP 메서드를 나타낼 수 있습니다.

 

<allow VERB="POST" users="John,Mary" />

<deny VERB="POST" users="*" />

<allow VERB="GET" users="*" />

 

이 예제에서는 Mary John만 보호된 리소스에 POST를 사용할 수 있으며, 다른 사용자는 모두 GET만 사용할 수 있습니다.

다음과 같은 두 가지의 특별한 사용자 이름이 있습니다.

 

*: 모든 사용자

?: 인증되지 않은 익명 사용자

 

다음 예제에 나와 있는 것처럼, 이러한 특별한 사용자 이름은 대개 폼 기반의 인증을 사용하는

응용 프로그램에서 인증되지 않은 사용자의 액세스를 거부하는 데 사용됩니다.

 

<authorization>

    <deny users="?" />

</authorization>

 

URL 인증은 계층적으로 지정되며 액세스 여부를 결정하는 데 사용되는 규칙은 다음과 같습니다.

 

(1) URL과 관련된 규칙이 여러 계층에서 수집되어 병합 규칙 목록이 구성됩니다.

(2) 가장 최근의 규칙이 목록의 맨 위에 놓입니다.

따라서, 목록의 맨 위에는 현재 디렉터리의 구성이 위치하게 되고 그 다음에는 바로 위 부모의 구성이 위치합니다.

이러한 방식으로 마지막에는 해당 컴퓨터의 최상위 파일이 위치합니다.

(3) 일치하는 항목을 찾을 때까지 규칙을 검사합니다.

일치하는 규칙을 찾을 수 있으면 액세스 권한이 부여되고, 찾을 수 없으면 액세스 권한이 부여되지 않습니다.

 

따라서, 구성을 상속 받지 않는 응용 프로그램은 자신의 응용 프로그램과 관련된 가능한 모든 항목을 명시적으로 구성해야 합니다.

지정된 컴퓨터의 기본 최상위 Web.config 파일에는 모든 사용자가 액세스할 수 있습니다.

사용자가 인증되어 파일 인증 ACL 검사가 통과된다고 가정할 때 응용 프로그램을 이와 반대로 구성하지 않는 한 권한이 부여됩니다.

역할이 검사되는 경우, URL 인증은 효율성을 높이기 위해 구성된 역할 목록의 아래쪽으로 일치 여부를 확인하며, 다음 의사(pseudo) 코드와 유사한 작업을 수행합니다.

 

if(User.IsInRole("ConfiguredRole")) {

  ApplyRule();

}

 

사용자 응용 프로그램에서는 System.Security.Principal.IPrincipal을 구현하는 사용자 자신의 클래스를 사용하여 자신의 역할 매핑 의미론을 부여합니다.

다음 예제에서는 폼 기반의 인증 서비스를 사용합니다.

이 예제에서는 jdoe@somewhere.com과 익명 사용자에 대해 명시적으로 액세스가 거부됩니다.

, 사용자 이름 "jdoe@somewhere.com"과 암호 "password"를 사용하여 샘플에 로그인하면

액세스가 거부되고 로그온 페이지로 리디렉션됩니다.

사용자 이름 "mary@somewhere.com"과 암호 "password"로 로그인하면 액세스가 허가됩니다.

 

/* default.aspx */

<%@ Import Namespace="System.Web.Security " %>

<html>

  <script language="C#" runat=server>

    void Page_Load(Object Src, EventArgs E ) {

      Welcome.Text = "Hello, " + User.Identity.Name;

    }

    void Signout_Click(Object sender, EventArgs E) {

      FormsAuthentication.SignOut();

      Response.Redirect("login.aspx");

    }

  </script>

  <body>

    <h3><font face="굴림">쿠키 인증 사용</font></h3>

    <form runat=server>

      <h3><asp:label id="Welcome" runat=server/></h3>

      <asp:button text="로그아웃" OnClick="Signout_Click" runat=server/>

    </form>

  </body>

</html>

 

/* login.aspx */

<%@ Import Namespace="System.Web.Security " %>

<html>

  <script language="C#" runat=server>

    void Login_Click(Object sender, EventArgs E) {

      if (((UserEmail.Value == "jdoe@somewhere.com") && (UserPass.Value == "password")) || ((UserEmail.Value == "mary@somewhere.com") && (UserPass.Value == "password"))) {

        FormsAuthentication.RedirectFromLoginPage(UserEmail.Value, PersistCookie.Checked);

      }

      else {

        Msg.Text = "Invalid Credentials: Please try again";

      }

    }

  </script>

  <body>

    <form runat=server>

      <h3><font face="굴림">로그인 페이지</font></h3>

      <table>

        <tr>

          <td>전자 메일:</td>

          <td><input id="UserEmail" type="text" runat=server/></td>

          <td><ASP:RequiredFieldValidator ControlToValidate="UserEmail" Display="Static" ErrorMessage="*" runat=server/></td>

        </tr>

        <tr>

          <td>암호:</td>

          <td><input id="UserPass" type=password runat=server/></td>

          <td><ASP:RequiredFieldValidator ControlToValidate="UserPass" Display="Static" ErrorMessage="*" runat=server/></td>

        </tr>

        <tr>

          <td>지속적 쿠키:</td>

          <td><ASP:CheckBox id=PersistCookie runat="server" /> </td>

          <td></td>

        </tr>

      </table>

      <asp:button text="로그인" OnClick="Login_Click" runat=server/>

      <p>

      <asp:Label id="Msg" ForeColor="red" Font-Name="Verdana" Font-Size="10" runat=server />

    </form>

  </body>

</html>

 

/* web.config */

<configuration>

  <system.web>

      <authentication mode="Forms">

        <forms name=".ASPXUSERDEMO" loginUrl="login.aspx" protection="All" timeout="60" />

      </authentication>

      <authorization>

        <deny users="jdoe@somewhere.com" />

        <deny users="?" />

      </authorization>

    <globalization requestEncoding="UTF-8" responseEncoding="UTF-8" />

  </system.web>

</configuration>

 

 

6. 보안 및 웹 서비스.

이 단원에서는 XML Web services 보안 방법에 대해 설명합니다

 

6.1. Windows 인증 및 권한 부여

.aspx 페이지에 사용한 Windows 인증 XML Web services 보안에도 사용합니다.

인증을 사용하려면 응용 프로그램에 대해 Windows 통합 인증을 활성화하고 IIS 관리 콘솔에서 익명 액세스를 비활성화합니다.

특정 사용자의 서비스 액세스를 허용하거나 거부하려면 다음 예제와 같이 ASP.NET 구성 시스템을 사용하거나 서비스 파일 자체에서 ACL을 설정하십시오.

 

<configuration>

  <system.web>

    <authentication mode="Windows"/>

  </system.web>

  <location path="secureservice.asmx">

    <system.web>

      <authorization>

        <allow users="Administrator"/>

        <allow users="DOMAIN\Bradley"/>

        <deny roles="BUILTIN\Power Users"/>

      </authorization>

    </system.web>

  </location>

</configuration>

 

XML Web services의 클라이언트가 특정 Windows 사용자로 실행되는 것이 확실한 경우 이 방식이 적합합니다.

특이한 점은 클라이언트가 한 사용자로 실행되지만 다른 사용자의 역할을 대신한다는 것입니다.

자신에 액세스하는 클라이언트를 가장하지 않는 보안 XML Web services에 액세스하는 ASP.NET 페이지의 경우,

웹 서비스에 연결하기 전에 사용자 이름과 암호를 프로그래밍 방식으로 설정해야 합니다.

다음 예제에서는 기본 인증을 사용하고 간단한 WebService를 설명합니다.

 

<%@ WebService language="C#" Class="SecureService" %>

 

using System.Web.Services;

using System;

 

class SecureService : WebService {

 

    [WebMethod]

    public String SecureTest() {

        return "Hello from the secure web service";

    }

}

 

<%@ WebService language="VB" Class="SecureService" %>

 

Imports System.Web.Services

Imports System

 

Class SecureService : Inherits WebService

 

 

    <WebMethod()> Public Function SecureTest As String

        Return "Hello from the secure web service"

    End

End Class

 

<%@ WebService language="JScript" Class="SecureService" %>

 

import System.Web.Services;

import System;

 

class SecureService extends WebService {

 

 

    WebMethodAttribute function SecureTest() : String {

        return "Hello from the secure web service";

    }

}

 

다음 단계에 따라 IIS에서 적절하게 설정하면 이 서비스에 대해 기본 인증을 사용할 수 있습니다.

 

(1) IIS MMC 콘솔을 엽니다.  ( Start->Run "inetmgr" )

(2) 왼쪽 창에서 트리를 확장하여 가상 디렉터리를 찾습니다.

(3) 오른쪽 창에서 Secureservice.asmx를 마우스 오른쪽 단추로 클릭하고 속성을 선택합니다.

(4) 파일 보안 탭을 선택합니다. 익명 액세스 및 인증 제어 아래에서 편집을 클릭합니다.

(5) 익명 액세스를 비활성화합니다.

(6) Windows 통합 인증을 비활성화합니다.

(7) 기본 인증을 활성화합니다.

(8) 확인을 눌러 이 설정을 저장하고 MMC 콘솔을 종료합니다.

 

기본 WebService 프록시 클래스에는 UsernamePassword라는 두 개의 속성이 있습니다.

원격 웹 서비스에 연결할 때 이 두 속성을 사용하여 자격 증명을 지정할 수 있습니다.

이들 속성은 해당 웹 서비스의 컴퓨터나 도메인에서 유효한 Windows 자격 증명으로 설정되어야 합니다.

 

<%@ Import Namespace="SecureService" %>

<html>

<script language="C#" runat="server">

    public void Page_Load(Object sender, EventArgs e) {

        SecureService s = new SecureService();

        s.Credentials = new System.Net.NetworkCredential("Administrator", "test123");

        Message.Text = s.SecureTest();

    }

</script>

<body>

  <h4><font face="verdana">

    <asp:Label id="Message" runat="server"/>

  </font></h4>

</body>

</html>

 

또한 기본 WebService 클래스에는 클라이언트 사용자에 대한 정보를 검색하는 데 사용할 수 있는

System.Security.Principal.IPrincipal 형식의 User 속성이 있습니다.

다시 ASP.NET 구성 시스템의 Authorization 섹션을 사용하여 웹 서비스에 액세스하는 권한을 부여할 수 있습니다.

 

6.2. Soap Header를 사용한 사용자 지정 인증 및 권한 부여

Windows 인증은 해당 도메인에 속한 사용자에 대해 인증하는 인트라넷 시나리오에 적합합니다.

그러나 인터넷에서는 SQL 데이터베이스에 대해 사용자 지정 인증과 권한 부여를 수행할 수 있습니다.

이러한 경우 서비스에 사용자 지정 자격 증명(: 사용자 이름과 암호)을 전달하여 해당 서비스가

스스로 인증과 권한 부여를 처리할 수 있도록 해야 합니다.

SOAP header를 사용하면 요청과 함께 추가 정보를 XML Web services에 간단하게 전달할 수 있습니다.

이렇게 하려면 SOAPHeader에서 파생된 클래스를 서비스에 정의한 다음 서비스의 공용 필드를 해당 형식으로 선언합니다.

다음 예제와 같이 이 클래스는 서비스에 대한 공용 계약에 노출되며 WebServiceUtil.exe에서 프록시가 만들어지면 클라이언트에서 사용할 수 있게 됩니다.

 

using System.Web.Services;

using System.Web.Services.Protocols;

 

// AuthHeader class extends from SoapHeader

public class AuthHeader : SoapHeader {

    public string Username;

    public string Password;

}

 

public class HeaderService : WebService {

    public AuthHeader sHeader;

    ...

}

 

Imports System.Web.Services

Imports System.Web.Services.Protocols

 

' AuthHeader class extends from SoapHeader

Public Class AuthHeader : Inherits SoapHeader

    Public Username As String

    Public Password As String

End Class

 

Public Class HeaderService : Inherits WebService

    Public sHeader As AuthHeader

    ...

End Class

 

import System.Web.Services;

import  System.Web.Services.Protocols;

 

// AuthHeader class extends from SoapHeader

public class AuthHeader extends SoapHeader {

    public var Username:String;

    public var Password:String;

}

 

public class HeaderService extends WebService {

    public var sHeader:AuthHeader;

    ...

}

 

서비스의 각 WebMethodSoapHeader 사용자 지정 특성을 사용하여 관련 헤더 집합을 정의할 수 있습니다.

기본적으로 헤더는 필수이지만 선택적인 헤더도 정의할 수 있습니다.

SoapHeader 특성은 공용 필드의 이름이나 Client 또는 Server 클래스(이 항목에서는 Headers 속성이라고 함)의 속성을 지정합니다.

WebServices는 입력 헤더에 대해 메서드가 호출되기 전에 Headers 속성의 값을 설정하고 출력 헤더에 대해 메서드가 반환하는 값을 검색합니다.

출력 또는 선택적 헤더에 대한 자세한 내용은 NET Framework SDK 설명서를 참조하십시오.

 

[WebMethod(Description="This method requires a custom soap header set by the caller")]

[SoapHeader("sHeader")]

public string SecureMethod() {

    if (sHeader == null)

        return "ERROR: Please supply credentials";

    else

        return "USER: " + sHeader.Username;

}

 

그러면 다음 예제와 같이 헤더를 필요로 하는 메서드를 호출하기 전에 클라이언트가 직접 프록시 클래스의 헤더를 설정합니다.

 

HeaderService h = new HeaderService();

AuthHeader myHeader = new AuthHeader();

myHeader.Username = "JohnDoe";

myHeader.Password = "password";

h.AuthHeader = myHeader;

String result = h.SecureMethod();

 

전체 코드는 아래와 같습니다.

 

/* SoapHeader.asmx */

<%@ WebService Language="C#" Class="SoapHeadersCS.HeaderService" %>

using System;

using System.Web.Services;

using System.Web.Services.Protocols;

// Note the namespace has to be different from the one used

// on the proxy dll or we get errors about AuthHeader being

// defined in multiple places.

namespace SoapHeadersCS {

     // AuthHeader class extends from SoapHeader

    public class AuthHeaderCS : SoapHeader {

        public string Username;

        public string Password;

    }

    [WebService(Description="헤더의 사용 방법을 보여주는 단순 샘플입니다.")]

    public class HeaderService {

        public AuthHeaderCS sHeader;

        [WebMethod(Description="이 메서드에는 호출자가 설정한 사용자 지정 soap 헤더가 필요합니다.")]

        [SoapHeader("sHeader")]

        public string SecureMethod() {

            if (sHeader == null)

              return "오류: 자격 증명을 입력하십시오.";

            string usr = sHeader.Username;

            string pwd = sHeader.Password;

            if (AuthenticateUser(usr, pwd)) {

                 return "성공: " + usr + "," + pwd;

            }

            else {

                 return "오류: 인증할 수 없습니다.";

            }

        }

        private bool AuthenticateUser(string usr, string pwd) {

            if ((usr != null)&&(pwd != null)) {

                // could query a database here for credentials...

                return true;

             }

            return false;

        }

    }

}

 

/* SoapHeader.aspx */

<%@ Import Namespace="SoapHeaders" %>

  <script language="C#" runat="server">

    public void Page_Load(Object sender, EventArgs e) {

        Response.Write("<h4><font face=\"verdana\">Using Soap Headers for Custom Authentication</font></h4>");

        // Create a new instance of the UsingSoapHeaders

        // proxy class used to call the remote .asmx file

        HeaderService h = new HeaderService();

        // Call the secure method without credentials

        Response.Write("First call result: <p>");

        try {

          Response.Write(h.SecureMethod() + "<p>");

        }

        catch (Exception ex) {

          Response.Write("<pre>" + ex.StackTrace + "</pre><p>");

        }

        // Create a new instance of the AuthHeader class

        AuthHeaderCS myHeader = new AuthHeaderCS();

        // Set the value of myHeader

        myHeader.Username = "JohnDoe";

        myHeader.Password = "password";

        // Set the AuthHeader public member of the

        // UsingSoapHeaders class to myHeader

        h.AuthHeaderCSValue = myHeader;

        // Call the secure method with credentials

        Response.Write("Second call result: <p><pre>" + h.SecureMethod() + "</pre>");

    }

  </script>

 

 

6.3. 단원요약.

1. .aspx 페이지에서 Windows 인증을 사용한 것처럼 서버의 XML Web services 보안에도 이 인증 방식이 사용됩니다.

 

2. 또한 WebService 프록시 클래스의 Username Password 속성을 사용하여 프로그래밍 방식으로 Windows 자격 증명을 설정할 수도 있습니다.

 

3.마지막으로, 인증이 필요한 메서드에 대한 SOAP 요청과 함께 자격 증명 정보를 SOAPHeaders로 전달하여 사용자 지정 인증을 수행할 수 있습니다.

+ Recent posts