역할 기반 권한 부여(VB)

작성자 : Scott Mitchell

참고

이 문서가 작성된 이후 ASP.NET 멤버 자격 공급자는 ASP.NET ID로 대체되었습니다. 이 문서를 작성할 때 추천한 멤버 자격 공급자가 아닌 ASP.NET ID 플랫폼을 사용하도록 앱을 업데이트하는 것이 좋습니다. ASP.NET ID는 를 포함하여 ASP.NET 멤버 자격 시스템에 비해 여러 가지 이점이 있습니다.

  • 성능 향상
  • 향상된 확장성 및 테스트 가능성
  • OAuth, OpenID Connect 및 2단계 인증 지원
  • 클레임 기반 ID 지원
  • ASP.Net Core와의 상호 운용성 향상

코드 다운로드 또는 PDF 다운로드

이 자습서는 역할 프레임워크가 사용자의 역할을 보안 컨텍스트와 연결하는 방법을 살펴보는 것으로 시작합니다. 그런 다음 역할 기반 URL 권한 부여 규칙을 적용하는 방법을 검토합니다. 그런 다음, 표시된 데이터와 ASP.NET 페이지에서 제공하는 기능을 변경하기 위해 선언적 및 프로그래밍 방식의 수단을 사용하는 방법을 살펴보겠습니다.

소개

사용자 기반 권한 부여 자습서에서는 URL 권한 부여를 사용하여 특정 페이지 집합을 방문할 수 있는 사용자를 지정하는 방법을 알아보았습니다. 에서 Web.config약간의 태그를 사용하면 인증된 사용자만 페이지를 방문할 수 있도록 ASP.NET 지시할 수 있습니다. 또는 Tito 및 Bob 사용자만 허용되었음을 지시하거나 Sam을 제외한 모든 인증된 사용자가 허용되었음을 나타낼 수 있습니다.

URL 권한 부여 외에도 표시되는 데이터와 방문하는 사용자를 기반으로 페이지에서 제공하는 기능을 제어하기 위한 선언적 및 프로그래밍 방식의 기술도 살펴보았습니다. 특히 현재 디렉터리의 내용을 나열하는 페이지를 만들었습니다. 누구나 이 페이지를 방문할 수 있지만 인증된 사용자만 파일의 콘텐츠를 볼 수 있으며 Tito만 파일을 삭제할 수 있습니다.

사용자별로 권한 부여 규칙을 적용하면 부기 악몽으로 커질 수 있습니다. 더 유지 관리하기 쉬운 방법은 역할 기반 권한 부여를 사용하는 것입니다. 좋은 소식은 권한 부여 규칙을 적용하기 위한 도구가 사용자 계정과 마찬가지로 역할과 동일하게 잘 작동한다는 것입니다. URL 권한 부여 규칙은 사용자 대신 역할을 지정할 수 있습니다. 인증된 사용자와 익명 사용자에 대해 다른 출력을 렌더링하는 LoginView 컨트롤은 로그인한 사용자의 역할에 따라 다른 콘텐츠를 표시하도록 구성할 수 있습니다. 또한 역할 API에는 로그인한 사용자의 역할을 결정하는 메서드가 포함되어 있습니다.

이 자습서는 역할 프레임워크가 사용자의 역할을 보안 컨텍스트와 연결하는 방법을 살펴보는 것으로 시작합니다. 그런 다음 역할 기반 URL 권한 부여 규칙을 적용하는 방법을 검토합니다. 그런 다음, 표시된 데이터와 ASP.NET 페이지에서 제공하는 기능을 변경하기 위해 선언적 및 프로그래밍 방식의 수단을 사용하는 방법을 살펴보겠습니다. 그럼 시작하겠습니다.

역할이 사용자의 보안 컨텍스트와 연결되는 방법 이해

요청이 ASP.NET 파이프라인에 들어갈 때마다 요청자를 식별하는 정보가 포함된 보안 컨텍스트와 연결됩니다. 양식 인증을 사용하는 경우 인증 티켓이 ID 토큰으로 사용됩니다. 양식 인증 개요 자습서 FormsAuthenticationModule 에서 설명한 것처럼 은 이벤트 중에 AuthenticateRequest수행하는 요청자의 ID를 결정합니다.

만료되지 않은 유효한 인증 티켓이 발견 FormsAuthenticationModule 되면 는 요청자의 ID를 확인하기 위해 디코딩합니다. 새 GenericPrincipal 개체를 만들고 이를 개체에 HttpContext.User 할당합니다. 과 같은 GenericPrincipal보안 주체의 목적은 인증된 사용자의 이름과 자신이 속한 역할을 식별하는 것입니다. 이 목적은 모든 주체 개체에 속성과 메서드가 Identity 있다는 사실에 의해 분명합니다 IsInRole(roleName) . 그러나 는 FormsAuthenticationModule역할 정보를 기록하는 데 관심이 없으며 만든 개체는 GenericPrincipal 역할을 지정하지 않습니다.

역할 프레임워크를 사용하도록 설정한 RoleManagerModule 경우 HTTP 모듈은 의 FormsAuthenticationModule 단계를 수행하고 이벤트 이후에 발생하는 AuthenticateRequest 이벤트 중에 PostAuthenticateRequest인증된 사용자의 역할을 식별합니다. 요청이 인증된 사용자의 요청인 경우 는 RoleManagerModule 에서 만든 FormsAuthenticationModule 개체를 GenericPrincipal 덮어쓰고 개체로 RolePrincipal바꿉니다. 클래스는 RolePrincipal 역할 API를 사용하여 사용자가 속한 역할을 결정합니다.

그림 1에서는 양식 인증 및 역할 프레임워크를 사용할 때 ASP.NET 파이프라인 워크플로를 보여 줍니다. 는 FormsAuthenticationModule 먼저 실행되고, 인증 티켓을 통해 사용자를 식별하고, 새 GenericPrincipal 개체를 만듭니다. 다음으로, RoleManagerModule 의 단계를 수행하고 개체를 GenericPrincipal 개체로 RolePrincipal 덮어씁니다.

익명 사용자가 사이트를 방문하는 경우 도 는 보안 주체 개체를 생성하지 FormsAuthenticationModule 않습니다 RoleManagerModule .

양식 인증 및 역할 프레임워크를 사용하는 경우 인증된 사용자에 대한 ASP.NET 파이프라인 이벤트

그림 1: 양식 인증 및 역할 프레임워크를 사용할 때 인증된 사용자에 대한 ASP.NET 파이프라인 이벤트(전체 크기 이미지를 보려면 클릭)

개체의 메서드는 RolePrincipal 를 호출합니다Roles.IsInRole(roleName)GetRolesForUser 사용자가 roleName의 멤버인지 여부를 확인하기 위해 사용자의 역할을 가져옵니다. 를 SqlRoleProvider사용하는 경우 역할 저장소 데이터베이스에 대한 쿼리가 발생합니다. 역할 기반 URL 권한 부여 규칙을 RolePrincipal사용하는 경우 역할 기반 URL 권한 부여 규칙으로 보호되는 페이지에 대한 모든 요청에서 의 IsInRole 메서드가 호출됩니다. 프레임워크에는 모든 요청 Roles 에서 데이터베이스의 역할 정보를 조회할 필요가 없으므로 쿠키에 사용자의 역할을 캐시하는 옵션이 포함되어 있습니다.

역할 프레임워크가 쿠키 RoleManagerModule 에서 사용자의 역할을 캐시하도록 구성된 경우 는 ASP.NET 파이프라인 이벤트EndRequest 중에 쿠키를 만듭니다. 이 쿠키는 개체를 PostAuthenticateRequest만들 때 RolePrincipal 인 의 후속 요청에 사용됩니다. 쿠키가 유효하고 만료되지 않은 경우 쿠키의 데이터가 구문 분석되어 사용자의 역할을 채우는 데 사용되므로 은 사용자의 역할을 결정하기 위해 클래스를 Roles 호출할 필요가 없도록 저장 RolePrincipal 합니다. 그림 2에서는 이 워크플로를 보여 줍니다.

사용자의 역할 정보를 쿠키에 저장하여 성능을 향상시킬 수 있습니다.

그림 2: 사용자의 역할 정보를 쿠키에 저장하여 성능을 향상시킬 수 있습니다(전체 크기 이미지를 보려면 클릭).

기본적으로 역할 캐시 쿠키 메커니즘은 사용하지 않도록 설정됩니다. 의 구성 태그Web.config<roleManager>통해 사용하도록 설정할 수 있습니다. 요소를 사용하여 <roleManager>역할 만들기 및 관리 자습서에서 역할 공급자를 지정하는 방법을 설명했으므로 애플리케이션 Web.config 파일에 이 요소가 이미 있어야 합니다. 역할 캐시 쿠키 설정은 ; 요소의 <roleManager>특성으로 지정되며 표 1에 요약되어 있습니다.

참고

표 1에 나열된 구성 설정은 결과 역할 캐시 쿠키의 속성을 지정합니다. 쿠키, 작동 방식 및 다양한 속성에 대한 자세한 내용은 이 쿠키 자습서를 참조하세요.

속성 설명
cacheRolesInCookie 쿠키 캐싱이 사용되는지 여부를 나타내는 부울 값입니다. 기본값은 false입니다.
cookieName 역할 캐시 쿠키의 이름입니다. 기본값은 "입니다. ASPXROLES".
cookiePath 역할 이름 쿠키의 경로입니다. 경로 특성을 사용하면 개발자가 쿠키의 scope 특정 디렉터리 계층 구조로 제한할 수 있습니다. 기본값은 "/"로, 도메인에 대한 모든 요청에 인증 티켓 쿠키를 보내도록 브라우저에 알립니다.
cookieProtection 역할 캐시 쿠키를 보호하는 데 사용되는 기술을 나타냅니다. 허용 가능한 값은 All (기본값); Encryption; NoneValidation.md입니다.

| cookieRequireSSL | 인증 쿠키를 전송하는 데 SSL 연결이 필요한지 여부를 나타내는 부울 값입니다. 기본값은 false cookieSlidingExpiration | A Boolean value that indicates whether the cookie's timeout is reset each time the user visits the site during a single session. The default value isfalse. This value is only pertinent when createPersistentCookieis set totrue. | | cookieTimeout | Specifies the time, in minutes, after which the authentication ticket cookie expires. The default value is30. This value is only pertinent when createPersistentCookie true. | | createPersistentCookieis set to | A Boolean value that specifies whether the role cache cookie is a session cookie or persistent cookie. Iffalse(the default), a session cookie is used, which is deleted when the browser is closed. Iftrue, a persistent cookie is used; it expires cookieTimeoutnumber of minutes after it has been created or after the previous visit, depending on the value ofcookieSlidingExpiration. | | 도메인| Specifies the cookie's domain value. The default value is an empty string, which causes the browser to use the domain from which it was issued (such as www.yourdomain.com). In this case, the cookie will <strong>not</strong> be sent when making requests to subdomains, such as admin.yourdomain.com. If you want the cookie to be passed to all subdomains you need to customize the도메인attribute, setting it to "yourdomain.com". | | maxCachedResults | Specifies the maximum number of role names that are cached in the cookie. The default is 25. TheRoleManagerModuledoes not create a cookie for users that belong to more thanmaxCachedResultsroles. Consequently, theRolePrincipalobject'sIsInRolemethod will use theRolesclass to determine the user's roles. The reasonmaxCachedResultsexists is because many user agents do not permit cookies larger than 4,096 bytes. So this cap is meant to reduce the likelihood of exceeding this size limitation. If you have extremely long role names, you may want to consider specifying a smaller. | | maxCachedResults 값; 반대로 역할 이름이 매우 짧은 경우 이 값을 늘릴 수 있습니다. |

표 1: 역할 캐시 쿠키 구성 옵션

비영구 역할 캐시 쿠키를 사용하도록 애플리케이션을 구성해 보겠습니다. 이렇게 하려면 다음 쿠키 관련 특성을 포함하도록 의 Web.config 요소를 업데이트 <roleManager> 합니다.

<roleManager enabled="true" 
          defaultProvider="SecurityTutorialsSqlRoleProvider"
          cacheRolesInCookie="true"
          createPersistentCookie="false"
          cookieProtection="All">

     <providers>
     ...
     </providers>
</roleManager>

, 및 의 <roleManager>세 가지 cacheRolesInCookie특성을 추가하여 ; 요소를 업데이트했습니다cookieProtection. createPersistentCookie 로 설정 cacheRolesInCookietrue하면 는 RoleManagerModule 이제 각 요청에 대한 사용자의 역할 정보를 조회하지 않고 쿠키에서 사용자의 역할을 자동으로 캐시합니다. 및 특성을 각각 및 cookieProtectionAllfalse 명시적으로 설정합니다createPersistentCookie. 기술적으로 이러한 특성에 대한 값을 방금 기본값에 할당했기 때문에 지정할 필요가 없었지만, 영구 쿠키를 사용하지 않고 쿠키가 암호화되고 유효성이 검사되었음을 명시적으로 명확히 하기 위해 여기에 배치했습니다.

이제 모든 작업을 마쳤습니다. 이제부터 역할 프레임워크는 쿠키에서 사용자의 역할을 캐시합니다. 사용자의 브라우저에서 쿠키를 지원하지 않거나 쿠키가 삭제되거나 손실된 경우 큰 문제가 RolePrincipal 되지 않습니다. 개체는 쿠키(또는 유효하지 않거나 만료된 쿠키)를 사용할 수 없는 경우 클래스만 사용합니다 Roles .

참고

Microsoft의 패턴 & 사례 그룹은 영구 역할 캐시 쿠키를 사용하지 않는 것이 좋습니다. 역할 캐시 쿠키를 소유하는 것으로 역할 멤버 자격을 입증하기에 충분하므로 해커가 유효한 사용자의 쿠키에 액세스할 수 있는 경우 해당 사용자를 가장할 수 있습니다. 쿠키가 사용자의 브라우저에 유지되면 이러한 일이 발생할 가능성이 높아집니다. 이 보안 권장 사항 및 기타 보안 문제에 대한 자세한 내용은 ASP.NET 2.0 보안 질문 목록을 참조하세요.

1단계: Role-Based URL 권한 부여 규칙 정의

사용자 기반 권한 부여 자습서에서 설명한 대로 URL 권한 부여는 사용자별 또는 역할별로 페이지 집합에 대한 액세스를 제한하는 수단을 제공합니다. URL 권한 부여 규칙은 및 <deny> 자식 요소와 함께 <allow> 요소를 사용하여 <authorization> 에서 철자가 지정 Web.config 됩니다. 이전 자습서에서 설명한 사용자 관련 권한 부여 규칙 외에도 각 <allow> 요소와 <deny> 자식 요소에는 다음이 포함될 수 있습니다.

  • 특정 역할
  • 쉼표로 구분된 역할 목록

예를 들어 URL 권한 부여 규칙은 관리자 및 감독자 역할의 해당 사용자에게 액세스 권한을 부여하지만 다른 모든 사용자에 대한 액세스는 거부합니다.

<authorization>

     <allow roles="Administrators, Supervisors" />
     <deny users="*" />
</authorization>

<allow> 위의 태그에 있는 요소는 관리자 및 감독자 역할이 허용<deny>됨을 나타냅니다. ; 요소는 모든 사용자가 거부되도록 지시합니다.

관리자 역할 RoleBasedAuthorization.aspx 의 사용자만 , UsersAndRoles.aspx및 페이지에 액세스할 수 있도록 애플리케이션ManageRoles.aspx을 구성하고 CreateUserWizardWithRoles.aspx 모든 방문자가 페이지에 액세스할 수 있도록 하겠습니다.

이렇게 하려면 먼저 폴더에 Web.config 파일을 추가합니다 Roles .

역할 디렉터리에 Web.config 파일 추가

그림 3: 디렉터리에 파일 Roles 추가Web.config(전체 크기 이미지를 보려면 클릭)

다음으로 다음 구성 태그를 에 추가합니다 Web.config.

<?xml version="1.0"?>

<configuration>
     <system.web>
          <authorization>
               <allow roles="Administrators" />
               <deny users="*"/>
          </authorization>

     </system.web>

     <!-- Allow all users to visit RoleBasedAuthorization.aspx -->
     <location path="RoleBasedAuthorization.aspx">
          <system.web>
               <authorization>
                    <allow users="*" />

               </authorization>
          </system.web>
     </location>
</configuration>

<authorization> 섹션의 <system.web> 요소는 관리자 역할의 사용자만 디렉터리의 ASP.NET 리소스에 Roles 액세스할 수 있음을 나타냅니다. 요소는 <location> 페이지에 대한 URL 권한 부여 규칙의 대체 집합을 RoleBasedAuthorization.aspx 정의하여 모든 사용자가 페이지를 방문할 수 있도록 합니다.

변경 내용을 에 Web.config저장한 후 관리자 역할에 없는 사용자로 로그인한 다음 보호된 페이지 중 하나를 방문해 보세요. 는 UrlAuthorizationModule 요청된 리소스를 방문할 수 있는 권한이 없음을 감지합니다. 따라서 FormsAuthenticationModule 는 로그인 페이지로 리디렉션됩니다. 그러면 로그인 페이지가 UnauthorizedAccess.aspx 페이지로 리디렉션됩니다(그림 4 참조). 로그인 페이지에서 로 UnauthorizedAccess.aspx 의 최종 리디렉션은 사용자 기반 권한 부여 자습서의 2 단계에서 로그인 페이지에 추가한 코드 때문에 발생합니다. 특히 이 매개 변수는 사용자가 볼 권한이 없는 페이지를 보려고 시도한 후 로그인 페이지에 도착했음을 나타내기 때문에 쿼리 문자열에 매개 변수가 포함된 ReturnUrl 경우 로그인 페이지에서 인증된 사용자를 로 자동으로 리디렉션 UnauthorizedAccess.aspx 합니다.

관리자 역할의 사용자만 보호된 페이지를 볼 수 있습니다.

그림 4: 관리자 역할의 사용자만 보호된 페이지를 볼 수 있습니다(전체 크기 이미지를 보려면 클릭).

로그오프한 다음 관리자 역할에 있는 사용자로 로그인합니다. 이제 보호된 세 페이지를 볼 수 있습니다.

Tito는 관리자 역할에 있으므로 UsersAndRoles.aspx 페이지를 방문할 수 있습니다.

그림 5: Tito가 관리자 역할에 있으므로 페이지를 방문할 UsersAndRoles.aspx 수 있음(전체 크기 이미지를 보려면 클릭)

참고

역할 또는 사용자에 대한 URL 권한 부여 규칙을 지정할 때는 위에서 아래로 규칙을 한 번에 하나씩 분석한다는 규칙을 염두에 두어야 합니다. 일치 항목이 발견되는 즉시 일치 항목이 또는 <deny> 요소에 있는지 <allow> 여부에 따라 사용자에게 액세스 권한이 부여되거나 거부됩니다. 일치하는 항목이 없으면 사용자에게 액세스 권한이 부여됩니다. 따라서 하나 이상의 사용자 계정에 대한 액세스를 제한하려면 요소를 URL 권한 부여 구성의 마지막 요소로 사용해야 <deny> 합니다. URL 권한 부여 규칙에 가 포함되지<deny> 않은 경우요소, 모든 사용자에게 액세스 권한이 부여됩니다. URL 권한 부여 규칙을 분석하는 방법에 대한 자세한 내용은 사용자 기반 권한 부여 자습서의 "권한 부여 규칙을 사용하여 액세스 권한을 부여하거나 거부하는 방법 UrlAuthorizationModule 살펴보기" 섹션을 참조하세요.

2단계: 현재 로그인한 사용자의 역할에 따라 기능 제한

URL 권한 부여를 사용하면 허용되는 ID와 특정 페이지(또는 폴더 및 하위 폴더의 모든 페이지)를 볼 수 없는 ID를 나타내는 거친 권한 부여 규칙을 쉽게 지정할 수 있습니다. 그러나 경우에 따라 모든 사용자가 페이지를 방문하도록 허용하지만 방문하는 사용자의 역할에 따라 페이지의 기능을 제한할 수 있습니다. 이를 위해 사용자의 역할에 따라 데이터를 표시하거나 숨기거나 특정 역할에 속한 사용자에게 추가 기능을 제공할 수 있습니다.

이러한 세분화된 역할 기반 권한 부여 규칙은 선언적 또는 프로그래밍 방식으로(또는 둘의 일부 조합을 통해) 구현할 수 있습니다. 다음 섹션에서는 LoginView 컨트롤을 통해 선언적 세분화 권한 부여를 구현하는 방법을 알아보세요. 그런 다음 프로그래밍 기법을 살펴봅니다. 그러나 세분화된 권한 부여 규칙 적용을 살펴보려면 먼저 방문하는 사용자의 역할에 따라 기능이 달라지는 페이지를 만들어야 합니다.

GridView에서 시스템의 모든 사용자 계정을 나열하는 페이지를 만들어 보겠습니다. GridView에는 각 사용자의 사용자 이름, 이메일 주소, 마지막 로그인 날짜 및 사용자에 대한 메모가 포함됩니다. GridView에는 각 사용자의 정보를 표시하는 것 외에도 편집 및 삭제 기능이 포함됩니다. 처음에는 모든 사용자가 사용할 수 있는 편집 및 삭제 기능을 사용하여 이 페이지를 만듭니다. "LoginView 컨트롤 사용" 및 "프로그래밍 방식으로 기능 제한" 섹션에서 방문하는 사용자의 역할에 따라 이러한 기능을 사용하거나 사용하지 않도록 설정하는 방법을 알아봅니다.

참고

빌드하려는 ASP.NET 페이지에서는 GridView 컨트롤을 사용하여 사용자 계정을 표시합니다. 이 자습서 시리즈는 양식 인증, 권한 부여, 사용자 계정 및 역할에 중점을 두므로 GridView 컨트롤의 내부 작업에 대해 논의하는 데 너무 많은 시간을 할애하고 싶지 않습니다. 이 자습서에서는 이 페이지를 설정하기 위한 특정 단계별 지침을 제공하지만 특정 선택 항목이 만들어진 이유 또는 특정 속성이 렌더링된 출력에 미치는 영향에 대한 자세한 내용은 자세히 알아보지 않습니다. GridView 컨트롤을 철저히 검사하려면 ASP.NET 2.0 자습서 시리즈에서 데이터 작업을 검사.

먼저 폴더에서 RoleBasedAuthorization.aspxRoles 페이지를 엽니다. 페이지에서 Designer GridView를 끌어 로 설정합니다 IDUserGrid. 잠시 후에 를 호출 Membership하는 코드를 작성합니다.GetAllUsers 메서드를 사용하여 결과 개체를 MembershipUserCollection GridView에 바인딩합니다. MembershipUserCollection 에는 MembershipUser 시스템의 MembershipUser 각 사용자 계정에 대한 개체가 포함됩니다. 개체에는 와LastLoginDateEmail 같은 UserName속성이 있습니다.

사용자 계정을 그리드에 바인딩하는 코드를 작성하기 전에 먼저 GridView의 필드를 정의해 보겠습니다. GridView의 스마트 태그에서 "열 편집" 링크를 클릭하여 필드 대화 상자를 시작합니다(그림 6 참조). 여기에서 왼쪽 아래 모서리에 있는 "필드 자동 생성" 확인란의 선택을 취소합니다. 이 GridView에 편집 및 삭제 기능이 포함되도록 하려면 CommandField를 추가하고 및 ShowEditButtonShowDeleteButton 속성을 True로 설정합니다. 다음으로 , , EmailLastLoginDateComment 속성을 표시하기 UserName위한 4개의 필드를 추가합니다. 편집 가능한 두 필드EmailComment( 및 )에 대해 읽기 전용 속성(UserNameLastLoginDate) 및 TemplateFields에 BoundField를 사용합니다.

첫 번째 BoundField가 UserName 속성을 표시하도록 하고 해당 HeaderTextDataField 속성을 "UserName"으로 설정합니다. 이 필드는 편집할 수 없으므로 해당 ReadOnly 속성을 True로 설정합니다. BoundField를 LastLoginDate "Last Login"으로 설정하고 이를 DataField "LastLoginDate"로 설정 HeaderText 하여 구성합니다. 날짜와 시간 대신 날짜만 표시되도록 이 BoundField의 출력 형식을 지정해 보겠습니다. 이렇게 하려면 이 BoundField의 HtmlEncode 속성을 False로 설정하고 해당 DataFormatString 속성을 "{0:d}"로 설정합니다. 또한 속성을 True로 설정합니다 ReadOnly .

HeaderText 두 TemplateFields의 속성을 "Email" 및 "주석"으로 설정합니다.

GridView의 필드는 필드 대화 상자를 통해 구성할 수 있습니다.

그림 6: 필드 대화 상자를 통해 GridView의 필드를 구성할 수 있습니다(전체 크기 이미지를 보려면 클릭).

이제 "Email" 및 "주석" TemplateFields에 대해 및 EditItemTemplate 를 정의 ItemTemplate 해야 합니다. 각 에 레이블 웹 컨트롤을 ItemTemplates 추가하고 해당 Text 속성을 각각 및 Comment 속성에 Email 바인딩합니다.

"Email" TemplateField의 경우 라는 Email TextBox를 에 EditItemTemplate 추가하고 양방향 데이터 바인딩을 사용하여 속성에 Email 속성을 바인딩 Text 합니다. RequiredFieldValidator 및 RegularExpressionValidator를 에 EditItemTemplate 추가하여 Email 속성을 편집하는 방문자가 유효한 이메일 주소를 입력했는지 확인합니다. "Comment" TemplateField의 경우 라는 Comment 여러 줄 TextBox를 해당 에 추가합니다 EditItemTemplate. TextBox ColumnsRows 속성을 각각 40과 4로 설정한 다음 양방향 데이터 바인딩을 사용하여 속성에 Comment 속성을 Text 바인딩합니다.

이러한 TemplateFields를 구성한 후 선언적 태그는 다음과 유사하게 표시됩니다.

<asp:TemplateField HeaderText="Email">
     <ItemTemplate>
          <asp:Label runat="server" ID="Label1" Text='<%# Eval("Email")%>'></asp:Label>

     </ItemTemplate>
     <EditItemTemplate>
          <asp:TextBox runat="server" ID="Email" Text='<%# Bind("Email")%>'></asp:TextBox>

          <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" 
               ControlToValidate="Email" Display="Dynamic"
               ErrorMessage="You must provide an email address."
               SetFocusOnError="True">*</asp:RequiredFieldValidator>

          <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server"
               ControlToValidate="Email" Display="Dynamic"
               ErrorMessage="The email address you have entered is not valid. Please fix 
               this and try again."
               SetFocusOnError="True"

               ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">*
          </asp:RegularExpressionValidator>
     </EditItemTemplate>
</asp:TemplateField>

<asp:TemplateField HeaderText="Comment">
     <ItemTemplate>
          <asp:Label runat="server" ID="Label2" Text='<%# Eval("Comment")%>'></asp:Label>

     </ItemTemplate>
     <EditItemTemplate>
          <asp:TextBox runat="server" ID="Comment" TextMode="MultiLine"
               Columns="40" Rows="4" Text='<%# Bind("Comment")%>'>

          </asp:TextBox>
     </EditItemTemplate>
</asp:TemplateField>

사용자 계정을 편집하거나 삭제할 때는 해당 사용자의 UserName 속성 값을 알아야 합니다. GridView의 컬렉션을 통해 이 정보를 사용할 수 있도록 GridView DataKeysDataKeyNames 속성을 "UserName"으로 설정합니다.

마지막으로 페이지에 ValidationSummary 컨트롤을 추가하고 해당 ShowMessageBox 속성을 True로 설정하고 해당 ShowSummary 속성을 False로 설정합니다. 이러한 설정을 사용하면 사용자가 누락되거나 잘못된 전자 메일 주소로 사용자 계정을 편집하려고 하면 ValidationSummary에 클라이언트 쪽 경고가 표시됩니다.

<asp:ValidationSummary ID="ValidationSummary1"
               runat="server"
               ShowMessageBox="True"
               ShowSummary="False" />

이제 이 페이지의 선언적 태그를 완료했습니다. 다음 작업은 사용자 계정 집합을 GridView에 바인딩하는 것입니다. 에서 반환된 를 GridView에 RoleBasedAuthorization.aspx 바인딩하는 페이지의 코드 숨김 클래스에 Membership.GetAllUsers 라는 BindUserGrid 메서드를 UserGrid 추가합니다MembershipUserCollection. 첫 번째 페이지 방문의 Page_Load 이벤트 처리기에서 이 메서드를 호출합니다.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
     If Not Page.IsPostBack Then
          BindUserGrid()
     End If
End Sub

Private Sub BindUserGrid()
     Dim allUsers As MembershipUserCollection = Membership.GetAllUsers()
     UserGrid.DataSource = allUsers
     UserGrid.DataBind()
End Sub

이 코드를 사용하면 브라우저를 통해 페이지를 방문합니다. 그림 7에서 볼 수 있듯이 시스템의 각 사용자 계정에 대한 정보를 나열하는 GridView가 표시됩니다.

UserGrid GridView는 시스템의 각 사용자에 대한 정보를 나열합니다.

그림 7: GridView는 UserGrid 시스템의 각 사용자에 대한 정보를 나열합니다(전체 크기 이미지를 보려면 클릭).

참고

GridView는 UserGrid 페이징되지 않은 인터페이스의 모든 사용자를 나열합니다. 이 간단한 그리드 인터페이스는 수십 명 이상의 사용자가 있는 시나리오에는 적합하지 않습니다. 한 가지 옵션은 페이징을 사용하도록 GridView를 구성하는 것입니다. 메서드에는 Membership.GetAllUsers 두 개의 오버로드가 있습니다. 하나는 입력 매개 변수를 허용하지 않고 모든 사용자를 반환하고 하나는 페이지 인덱스 및 페이지 크기에 대한 정수 값을 사용하고 지정된 사용자 하위 집합만 반환합니다. 두 번째 오버로드는 모든 사용자 계정이 아닌 사용자 계정의 정확한 하위 집합만 반환하므로 사용자를 보다 효율적으로 페이저닝하는 데 사용할 수 있습니다. 수천 개의 사용자 계정이 있는 경우 필터 기반 인터페이스를 고려할 수 있습니다. 이 인터페이스는 UserName이 선택한 문자로 시작하는 사용자만 표시하는 인터페이스로 instance. Membership.FindUsersByName 메서드는 필터 기반 사용자 인터페이스를 빌드하는 데 적합합니다. 향후 자습서에서는 이러한 인터페이스를 빌드하는 것을 살펴보겠습니다.

GridView 컨트롤은 컨트롤이 SqlDataSource 또는 ObjectDataSource와 같이 올바르게 구성된 데이터 원본 컨트롤에 바인딩되는 경우 기본 제공 편집 및 삭제 지원을 제공합니다. UserGrid 그러나 GridView에는 프로그래밍 방식으로 바인딩된 데이터가 있으므로 이러한 두 작업을 수행하는 코드를 작성해야 합니다. 특히 방문자가 GridView의 RowEditing편집, 취소, 업데이트 또는 삭제 단추를 클릭할 때 발생하는 GridView의 , RowCancelingEdit, RowUpdatingRowDeleting 이벤트에 대한 이벤트 처리기를 만들어야 합니다.

먼저 GridView의 RowEditing, RowCancelingEditRowUpdating 이벤트에 대한 이벤트 처리기를 만든 다음, 다음 코드를 추가합니다.

Protected Sub UserGrid_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles UserGrid.RowEditing
     ' Set the grid's EditIndex and rebind the data

     UserGrid.EditIndex = e.NewEditIndex
     BindUserGrid()
End Sub

Protected Sub UserGrid_RowCancelingEdit(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCancelEditEventArgs) Handles UserGrid.RowCancelingEdit
     ' Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1
     BindUserGrid()
End Sub
    
Protected Sub UserGrid_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles UserGrid.RowUpdating
     ' Exit if the page is not valid
     If Not Page.IsValid Then
          Exit Sub
     End If

     ' Determine the username of the user we are editing
     Dim UserName As String = UserGrid.DataKeys(e.RowIndex).Value.ToString()

     ' Read in the entered information and update the user
     Dim EmailTextBox As TextBox = CType(UserGrid.Rows(e.RowIndex).FindControl("Email"),TextBox)
     Dim CommentTextBox As TextBox= CType(UserGrid.Rows(e.RowIndex).FindControl("Comment"),TextBox)

     ' Return information about the user
     Dim UserInfo As MembershipUser = Membership.GetUser(UserName)

     ' Update the User account information
     UserInfo.Email = EmailTextBox.Text.Trim()
     UserInfo.Comment = CommentTextBox.Text.Trim()

     Membership.UpdateUser(UserInfo)

     ' Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1
     BindUserGrid()
End Sub

RowEditingRowCancelingEdit 이벤트 처리기는 GridView의 EditIndex 속성을 설정한 다음 사용자 계정 목록을 그리드에 다시 바인딩하기만 하면 됩니다. 흥미로운 내용은 이벤트 처리기 RowUpdating 에서 발생합니다. 이 이벤트 처리기는 데이터가 유효한지 확인한 다음 컬렉션에서 DataKeys 편집된 사용자 계정의 값을 가져옵니다UserName. Email 그런 다음 두 TemplateFields의 EditItemTemplateComment TextBoxes가 프로그래밍 방식으로 참조됩니다. 해당 Text 속성에는 편집된 전자 메일 주소와 메모가 포함됩니다.

멤버 자격 API를 통해 사용자 계정을 업데이트하려면 먼저 에 대한 호출을 통해 수행하는 사용자의 정보를 가져와야 합니다 Membership.GetUser(userName). 반환된 MembershipUser 개체의 EmailComment 속성은 편집 인터페이스에서 두 TextBoxes에 입력된 값으로 업데이트됩니다. 마지막으로 이러한 수정 사항은 에 대한 호출 Membership.UpdateUser과 함께 저장됩니다. RowUpdating 이벤트 처리기는 GridView를 사전 편집 인터페이스로 되돌려서 완료합니다.

다음으로 RowDeleting 이벤트 처리기를 만든 RowDeleting 다음, 다음 코드를 추가합니다.

Protected Sub UserGrid_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles UserGrid.RowDeleting

     ' Determine the username of the user we are editing
     Dim UserName As String = UserGrid.DataKeys(e.RowIndex).Value.ToString()

     ' Delete the user
     Membership.DeleteUser(UserName)

     ' Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1
     BindUserGrid()
End Sub

위의 이벤트 처리기는 GridView의 DataKeys 컬렉션에서 값을 가져와 UserName 서 시작합니다. 이 UserName 값은 Membership 클래스의 DeleteUser 메서드에 전달됩니다. 메서드는 DeleteUser 관련 멤버 자격 데이터(예: 이 사용자가 속한 역할)를 포함하여 시스템에서 사용자 계정을 삭제합니다. 사용자를 삭제한 후 그리드는 EditIndex -1로 설정되고 BindUserGrid (다른 행이 편집 모드에 있는 동안 사용자가 삭제를 클릭한 경우) 메서드가 호출됩니다.

참고

삭제 단추는 사용자 계정을 삭제하기 전에 사용자에게 어떤 종류의 확인도 요구하지 않습니다. 실수로 계정이 삭제될 가능성을 줄이도록 어떤 형태의 사용자 확인을 추가하는 것이 좋습니다. 작업을 확인하는 가장 쉬운 방법 중 하나는 클라이언트 쪽 확인 대화 상자를 사용하는 것입니다. 이 기술에 대한 자세한 내용은 삭제 시 Client-Side 확인 추가를 참조하세요.

이 페이지가 예상대로 작동하는지 확인합니다. 사용자의 전자 메일 주소와 메모를 편집하고 사용자 계정을 삭제할 수 있어야 합니다. RoleBasedAuthorization.aspx 모든 사용자가 페이지에 액세스할 수 있으므로 익명 방문자까지도 이 페이지를 방문하여 사용자 계정을 편집하고 삭제할 수 있습니다. 감독자 및 관리자 역할의 사용자만 사용자의 전자 메일 주소와 메모를 편집할 수 있고 관리자만 사용자 계정을 삭제할 수 있도록 이 페이지를 업데이트해 보겠습니다.

"LoginView 컨트롤 사용" 섹션에서는 LoginView 컨트롤을 사용하여 사용자의 역할과 관련된 지침을 보여 줍니다. 관리자 역할의 사용자가 이 페이지를 방문하는 경우 사용자를 편집하고 삭제하는 방법에 대한 지침을 보여 줍니다. 감독자 역할의 사용자가 이 페이지에 도달하면 사용자 편집에 대한 지침이 표시됩니다. 방문자가 익명이거나 감독자 또는 관리자 역할에 없는 경우 사용자 계정 정보를 편집하거나 삭제할 수 없음을 설명하는 메시지가 표시됩니다. "프로그래밍 방식으로 기능 제한" 섹션에서는 사용자의 역할에 따라 편집 및 삭제 단추를 프로그래밍 방식으로 표시하거나 숨기는 코드를 작성합니다.

LoginView 컨트롤 사용

이전 자습서에서 살펴본 것처럼 LoginView 컨트롤은 인증된 사용자와 익명 사용자에 대해 서로 다른 인터페이스를 표시하는 데 유용하지만 LoginView 컨트롤을 사용하여 사용자의 역할에 따라 다른 태그를 표시할 수도 있습니다. LoginView 컨트롤을 사용하여 방문한 사용자의 역할에 따라 다른 지침을 표시해 보겠습니다.

먼저 GridView 위에 LoginView를 추가합니다 UserGrid . 앞에서 설명한 대로 LoginView 컨트롤에는 및 LoggedInTemplate의 두 가지 기본 제공 템플릿이 있습니다AnonymousTemplate. 사용자에게 사용자 정보를 편집하거나 삭제할 수 없음을 알리는 간단한 메시지를 두 템플릿 모두에 입력합니다.

<asp:LoginView ID="LoginView1" runat="server">
     <LoggedInTemplate>
          You are not a member of the Supervisors or Administrators roles. Therefore you
           cannot edit or delete any user information.
     </LoggedInTemplate>
     <AnonymousTemplate>

          You are not logged into the system. Therefore you cannot edit or delete any user
           information.
     </AnonymousTemplate>
</asp:LoginView>

LoggedInTemplate외에도 AnonymousTemplate LoginView 컨트롤에는 역할별 템플릿인 RoleGroups가 포함될 수 있습니다. 각 RoleGroup에는 RoleGroup이 적용되는 역할을 지정하는 단일 속성 Roles이 포함되어 있습니다. 속성은 Roles 단일 역할(예: "관리자") 또는 쉼표로 구분된 역할 목록(예: "관리자, 감독자")으로 설정할 수 있습니다.

RoleGroups를 관리하려면 컨트롤의 스마트 태그에서 "RoleGroups 편집" 링크를 클릭하여 RoleGroup 컬렉션 편집기를 표시합니다. 두 개의 새 RoleGroup을 추가합니다. 첫 번째 RoleGroup의 Roles 속성을 "관리자"로 설정하고 두 번째 속성을 "감독자"로 설정합니다.

RoleGroup 컬렉션 편집기를 통해 LoginView의 Role-Specific 템플릿 관리

그림 8: RoleGroup 컬렉션 편집기를 통해 LoginView의 Role-Specific 템플릿 관리(전체 크기 이미지를 보려면 클릭)

확인을 클릭하여 RoleGroup 컬렉션 편집기를 닫습니다. 이렇게 하면 LoginView의 선언적 태그가 업데이트되어 RoleGroup 컬렉션 편집기에서 정의된 각 RoleGroup에 대한 자식 요소가 있는 <asp:RoleGroup> 섹션이 포함 <RoleGroups> 됩니다. 또한 처음에 및 LoggedInTemplateAnonymousTemplate 나열한 LoginView의 스마트 태그에 있는 "보기" 드롭다운 목록에 추가된 RoleGroups도 포함됩니다.

감독자 역할의 사용자에게 사용자 계정을 편집하는 방법에 대한 지침이 표시되고 관리자 역할의 사용자에게는 편집 및 삭제에 대한 지침이 표시되도록 RoleGroups를 편집합니다. 이러한 변경 후 LoginView의 선언적 태그는 다음과 유사하게 표시됩니다.

<asp:LoginView ID="LoginView1" runat="server">
     <RoleGroups>
          <asp:RoleGroup Roles="Administrators">

               <ContentTemplate>
                    As an Administrator, you may edit and delete user accounts. 
                    Remember: With great power comes great responsibility!
               </ContentTemplate>
          </asp:RoleGroup>
          <asp:RoleGroup Roles="Supervisors">
               <ContentTemplate>
                    As a Supervisor, you may edit users&#39; Email and Comment information. 
                    Simply click the Edit button, make your changes, and then click Update.
               </ContentTemplate>

          </asp:RoleGroup>
     </RoleGroups>
     <LoggedInTemplate>
          You are not a member of the Supervisors or Administrators roles. 
          Therefore you cannot edit or delete any user information.
     </LoggedInTemplate>
     </AnonymousTemplate>
          You are not logged into the system. 
          Therefore you cannot edit or delete any user information.
     </AnonymousTemplate>
</asp:LoginView>

이러한 변경 내용을 변경한 후 페이지를 저장한 다음 브라우저를 통해 방문합니다. 먼저 익명 사용자로 페이지를 방문합니다. "시스템에 로그인하지 않았습니다. 따라서 사용자 정보를 편집하거나 삭제할 수 없습니다." 그런 다음 인증된 사용자로 로그인하지만 감독자 또는 관리자 역할에 없는 사용자로 로그인합니다. 이번에는 "감독자 또는 관리자 역할의 구성원이 아닙니다. 따라서 사용자 정보를 편집하거나 삭제할 수 없습니다."

다음으로 감독자 역할의 멤버인 사용자로 로그인합니다. 이번에는 감독자 역할 관련 메시지가 표시됩니다(그림 9 참조). 관리자 역할에서 사용자로 로그인하는 경우 관리자 역할 관련 메시지가 표시됩니다(그림 10 참조).

감독자 Role-Specific 메시지가 표시됩니다.

그림 9: Bruce가 감독자 Role-Specific 메시지를 표시합니다(전체 크기 이미지를 보려면 클릭).

Tito가 관리자 Role-Specific 메시지를 표시합니다.

그림 10: Tito가 관리자 Role-Specific 메시지를 표시합니다(전체 크기 이미지를 보려면 클릭).

그림 9와 10의 스크린샷이 표시되면 LoginView는 여러 템플릿이 적용되는 경우에도 하나의 템플릿만 렌더링합니다. Bruce와 Tito는 모두 사용자에 로그인되어 있지만 LoginView는 일치하는 RoleGroup만 렌더링하고 는 렌더링하지 않습니다 LoggedInTemplate. 또한 Tito는 관리자 및 감독자 역할 모두에 속하지만 LoginView 컨트롤은 감독자 역할 대신 관리자 역할별 템플릿을 렌더링합니다.

그림 11에서는 LoginView 컨트롤에서 렌더링할 템플릿을 결정하는 데 사용하는 워크플로를 보여 줍니다. 둘 이상의 RoleGroup이 지정된 경우 LoginView 템플릿은 일치하는 첫 번째 RoleGroup을 렌더링합니다. 즉, 감독자 역할 그룹을 첫 번째 RoleGroup으로 배치하고 관리자를 두 번째로 배치한 경우 Tito가 이 페이지를 방문했을 때 감독자 메시지가 표시됩니다.

렌더링할 템플릿을 결정하기 위한 LoginView 컨트롤의 워크플로

그림 11: 렌더링할 템플릿을 결정하기 위한 LoginView 컨트롤의 워크플로(전체 크기 이미지를 보려면 클릭)

프로그래밍 방식으로 기능 제한

LoginView 컨트롤은 페이지를 방문하는 사용자의 역할에 따라 다른 지침을 표시하지만 편집 및 취소 단추는 모두에게 계속 표시됩니다. 감독자 또는 관리자 역할이 아닌 익명 방문자 및 사용자에 대한 편집 및 삭제 단추를 프로그래밍 방식으로 숨겨야 합니다. 관리자가 아닌 모든 사용자에 대해 삭제 단추를 숨겨야 합니다. 이를 위해 CommandField의 LinkButton 편집 및 삭제를 프로그래밍 방식으로 참조하고 필요한 경우 해당 Visible 속성을 False로 설정하는 약간의 코드를 작성합니다.

CommandField에서 프로그래밍 방식으로 컨트롤을 참조하는 가장 쉬운 방법은 먼저 템플릿으로 변환하는 것입니다. 이렇게 하려면 GridView의 스마트 태그에서 "열 편집" 링크를 클릭하고 현재 필드 목록에서 CommandField를 선택하고 "이 필드를 TemplateField로 변환" 링크를 클릭합니다. 이렇게 하면 CommandField가 및 EditItemTemplate가 있는 TemplateField로 ItemTemplate 바뀝니다. ItemTemplate 에는 LinkButton 편집 및 삭제가 포함되고, 에 EditItemTemplate Update 및 Cancel LinkButtons가 있습니다.

CommandField를 TemplateField로 변환

그림 12: CommandField를 TemplateField로 변환(전체 크기 이미지를 보려면 클릭)

에서 LinkButton 편집 및 삭제를 ItemTemplate업데이트하고 해당 ID 속성을 각각 및 DeleteButtonEditButton 으로 설정합니다.

<asp:TemplateField ShowHeader="False">
     <EditItemTemplate>
          <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="True" 
               CommandName="Update" Text="Update"></asp:LinkButton>

           <asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
               CommandName="Cancel" Text="Cancel"></asp:LinkButton>

     </EditItemTemplate>
     <ItemTemplate>
          <asp:LinkButton ID="EditButton" runat="server" CausesValidation="False" 
               CommandName="Edit" Text="Edit"></asp:LinkButton>

           <asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
               CommandName="Delete" Text="Delete"></asp:LinkButton>

     </ItemTemplate>
</asp:TemplateField>

데이터가 GridView에 바인딩되면 GridView는 해당 DataSource 속성의 레코드를 열거하고 해당 GridViewRow 개체를 생성합니다. 각 GridViewRow 개체가 만들어지면 RowCreated 이벤트가 발생합니다. 권한이 없는 사용자에 대한 편집 및 삭제 단추를 숨기려면 이 이벤트에 대한 이벤트 처리기를 만들고 프로그래밍 방식으로 LinkButton 편집 및 삭제를 참조하여 해당 Visible 속성을 적절하게 설정해야 합니다.

이벤트 처리기를 RowCreated 만든 다음, 다음 코드를 추가합니다.

Protected Sub UserGrid_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles UserGrid.RowCreated
     If e.Row.RowType = DataControlRowType.DataRow AndAlso e.Row.RowIndex <> UserGrid.EditIndex Then
          ' Programmatically reference the Edit and Delete LinkButtons
          Dim EditButton As LinkButton = CType(e.Row.FindControl("EditButton"), LinkButton)

          Dim DeleteButton As LinkButton = CType(e.Row.FindControl("DeleteButton"), LinkButton)

          EditButton.Visible = (User.IsInRole("Administrators") OrElse User.IsInRole("Supervisors"))
          DeleteButton.Visible = User.IsInRole("Administrators")
     End If
End Sub

RowCreated 헤더, 바닥글, 호출기 인터페이스 등을 비롯한 모든 GridView 행에 대해 이벤트가 발생합니다. 편집 모드의 행에는 편집 및 삭제 대신 업데이트 및 취소 단추가 있으므로 편집 모드가 아닌 데이터 행을 처리하는 경우에만 프로그래밍 방식으로 LinkButtons 편집 및 삭제를 참조하려고 합니다. 이 검사 문에 If 의해 처리됩니다.

편집 모드가 아닌 데이터 행을 처리하는 경우 LinkButton 편집 및 삭제가 참조되고 해당 Visible 속성은 개체의 IsInRole(roleName) 메서드에서 반환된 User 부울 값에 따라 설정됩니다. 개체는 User 에서 만든 보안 주체를 RoleManagerModule참조합니다. 따라서 IsInRole(roleName) 메서드는 역할 API를 사용하여 현재 방문자가 roleName에 속하는지 여부를 확인합니다.

참고

Roles 클래스를 직접 사용하여 호출 User.IsInRole(roleName) 을 메서드 호출로 Roles.IsUserInRole(roleName)대체했을 수 있습니다. 이 예제에서는 역할 API를 직접 사용하는 것보다 더 효율적이므로 주체 개체의 IsInRole(roleName) 메서드를 사용하기로 결정했습니다. 이 자습서의 앞부분에서는 사용자의 역할을 쿠키에 캐시하도록 역할 관리자를 구성했습니다. 이 캐시된 쿠키 데이터는 보안 주체의 IsInRole(roleName) 메서드가 호출될 때만 활용됩니다. 역할 API에 대한 직접 호출에는 항상 역할 저장소로의 이동이 포함됩니다. 역할이 쿠키에 캐시되지 않더라도 요청 중에 처음으로 호출되면 결과가 캐시되므로 주체 개체의 IsInRole(roleName) 메서드를 호출하는 것이 일반적으로 더 효율적입니다. 반면 역할 API는 캐싱을 수행하지 않습니다. 이 이벤트는 GridView의 RowCreated 모든 행에 대해 한 번 발생하므로 를 사용하면 User.IsInRole(roleName) 역할 저장소에 대한 한 번의 여행만 포함되는 반면 Roles.IsUserInRole(roleName)N 은 그리드에 표시되는 사용자 계정 수인 N 개의 여행이 필요합니다.

이 페이지를 방문하는 사용자가 관리자 또는 감독자 역할에 있으면 편집 단추의 Visible 속성이 로 설정 True 되고, 그렇지 않으면 로 설정 False됩니다. 삭제 단추의 Visible 속성은 사용자가 관리자 역할에 있는 경우에만 로 설정 True 됩니다.

브라우저를 통해 이 페이지를 테스트합니다. 익명 방문자 또는 감독자나 관리자가 아닌 사용자로 페이지를 방문하는 경우 CommandField는 비어 있습니다. 여전히 존재하지만 편집 또는 삭제 단추가 없는 씬 슬라이버입니다.

참고

관리자가 아닌 관리자와 관리자가 아닌 사용자가 페이지를 방문할 때 CommandField를 모두 숨길 수 있습니다. 나는 이것을 독자를위한 운동으로 남겨 둡니다.

편집 및 삭제 단추는 비관리자 및 비관리자를 위해 숨겨집니다.

그림 13: 편집 및 삭제 단추는 비감독자 및 비관리자를 위해 숨겨집니다(전체 크기 이미지를 보려면 클릭).

관리자 역할이 아닌 감독자 역할에 속한 사용자가 방문하는 경우 편집 단추만 표시됩니다.

감독자가 편집 단추를 사용할 수 있는 동안 삭제 단추가 숨겨집니다.

그림 14: 편집 단추를 감독자가 사용할 수 있는 동안 삭제 단추가 숨겨집니다(전체 크기 이미지를 보려면 클릭).

관리자가 방문하는 경우 편집 및 삭제 단추 모두에 액세스할 수 있습니다.

편집 및 삭제 단추는 관리자만 사용할 수 있습니다.

그림 15: 편집 및 삭제 단추는 관리자만 사용할 수 있습니다(전체 크기 이미지를 보려면 클릭).

3단계: 클래스 및 메서드에 Role-Based 권한 부여 규칙 적용

2단계에서는 감독자 및 관리자 역할의 사용자로 편집 기능을 제한하고 관리자에게만 기능을 삭제했습니다. 이는 프로그래밍 기술을 통해 권한이 없는 사용자에 대한 연결된 사용자 인터페이스 요소를 숨김으로써 수행되었습니다. 이러한 조치는 권한이 없는 사용자가 권한 있는 작업을 수행할 수 없음을 보장하지 않습니다. 나중에 추가되거나 권한이 없는 사용자를 위해 숨기는 것을 잊어버린 사용자 인터페이스 요소가 있을 수 있습니다. 또는 해커가 원하는 메서드를 실행하기 위해 ASP.NET 페이지를 가져오는 다른 방법을 발견할 수 있습니다.

권한이 없는 사용자가 특정 기능에 액세스할 수 없도록 하는 쉬운 방법은 해당 클래스 또는 메서드를 특성으로 PrincipalPermission데코레이트하는 것입니다. .NET 런타임에서 클래스를 사용하거나 해당 메서드 중 하나를 실행하는 경우 현재 보안 컨텍스트에 권한이 있는지 확인합니다. 특성은 PrincipalPermission 이러한 규칙을 정의할 수 있는 메커니즘을 제공합니다.

사용자 기반 권한 부여 자습서에서 특성을 다시 사용하는 PrincipalPermission 것을 살펴보았습니다. 특히 인증된 사용자와 Tito만 실행할 수 있도록 GridView SelectedIndexChangedRowDeleting 이벤트 처리기를 데코레이팅하는 방법을 알아보았습니다. 특성은 PrincipalPermission 역할에서도 작동합니다.

GridView RowUpdatingRowDeleting 이벤트 처리기에서 특성을 사용하여 PrincipalPermission 권한이 없는 사용자에 대한 실행을 금지하는 방법을 보여 봅시다. 각 함수 정의 위에 적절한 특성을 추가하기만 하면됩니다.

<PrincipalPermission(SecurityAction.Demand, Role:="Administrators")>_
<PrincipalPermission(SecurityAction.Demand, Role:="Supervisors")>_
Protected Sub UserGrid_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles UserGrid.RowUpdating
     ...
End Sub

<PrincipalPermission(SecurityAction.Demand, Role:="Administrators")>_
Protected Sub UserGrid_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles UserGrid.RowDeleting
     ...
End Sub

이벤트 처리기의 특성 RowUpdating 은 관리자 또는 감독자 역할의 사용자만 이벤트 처리기를 실행할 수 있음을 나타냅니다. 여기서 이벤트 처리기의 특성 RowDeleting 은 관리자 역할의 사용자로 실행을 제한합니다.

참고

특성은 PrincipalPermission 네임스페이스의 System.Security.Permissions 클래스로 표시됩니다. 코드 숨김 클래스 파일의 맨 위에 문을 추가하여 Imports System.Security.Permissions 이 네임스페이스를 가져와야 합니다.

관리자가 아닌 사용자가 이벤트 처리기를 실행 RowDeleting 하려고 시도하거나 비관리자 또는 비관리자가 이벤트 처리기를 실행 RowUpdating 하려고 하면 .NET 런타임에서 가 SecurityException발생합니다.

보안 컨텍스트가 메서드를 실행할 권한이 없는 경우 SecurityException이 throw됩니다.

그림 16: 보안 컨텍스트가 메서드 SecurityException 를 실행할 수 있는 권한이 없는 경우 이 Throw됨(전체 크기 이미지를 보려면 클릭)입니다.

ASP.NET 페이지 외에도 많은 애플리케이션에는 비즈니스 논리 및 데이터 액세스 계층과 같은 다양한 계층을 포함하는 아키텍처도 있습니다. 이러한 계층은 일반적으로 클래스 라이브러리로 구현되며 비즈니스 논리 및 데이터 관련 기능을 수행하기 위한 클래스 및 메서드를 제공합니다. 특성은 PrincipalPermission 이러한 계층에도 권한 부여 규칙을 적용하는 데 유용합니다.

특성을 사용하여 PrincipalPermission 클래스 및 메서드에 대한 권한 부여 규칙을 정의하는 방법에 대한 자세한 내용은 를 사용하여 PrincipalPermissionAttributes비즈니스 및 데이터 계층에 권한 부여 규칙 추가Scott Guthrie의 블로그 항목을 참조하세요.

요약

이 자습서에서는 사용자의 역할에 따라 거칠고 세분화된 권한 부여 규칙을 지정하는 방법을 살펴보았습니다. Asp. NET의 URL 권한 부여 기능을 사용하면 페이지 개발자가 어떤 페이지에 대한 액세스가 허용되거나 거부되는지 지정할 수 있습니다. 사용자 기반 권한 부여 자습서에서 살본 것처럼 URL 권한 부여 규칙은 사용자 단위로 적용할 수 있습니다. 이 자습서의 1단계에서 살본 것처럼 역할별로 적용할 수도 있습니다.

세분화된 권한 부여 규칙은 선언적 또는 프로그래밍 방식으로 적용될 수 있습니다. 2단계에서는 LoginView 컨트롤의 RoleGroups 기능을 사용하여 방문하는 사용자의 역할에 따라 다른 출력을 렌더링하는 방법을 살펴보았습니다. 또한 사용자가 특정 역할에 속하는지 여부를 프로그래밍 방식으로 확인하는 방법과 그에 따라 페이지의 기능을 조정하는 방법도 살펴보았습니다.

행복한 프로그래밍!

추가 정보

이 자습서에서 설명하는 topics 대한 자세한 내용은 다음 리소스를 참조하세요.

저자 정보

여러 ASP/ASP.NET 책의 저자이자 4GuysFromRolla.com 설립자인 Scott Mitchell은 1998년부터 Microsoft 웹 기술을 사용하고 있습니다. Scott은 독립 컨설턴트, 트레이너 및 작가로 일합니다. 그의 최신 책은 샘스 자신을 가르친다 ASP.NET 2.0 24 시간. Scott은 에서 mitchell@4guysfromrolla.com 또는 에서 자신의 블로그 http://ScottOnWriting.NET를 통해 연락할 수 있습니다.

특별한 감사...

이 자습서 시리즈는 많은 유용한 검토자가 검토했습니다. 이 자습서의 수석 검토자는 Suchi Banerjee 및 Teresa Murphy를 포함합니다. 예정된 MSDN 문서를 검토하시겠습니까? 그렇다면 에서 줄을 놓습니다. mitchell@4GuysFromRolla.com