웹 컨테이너에서 JAX-RS 애플리케이션 보안 설정

웹 컨테이너에서 사용 가능한 보안 서비스를 사용하여 REST(Representational State Transfer) 자원을 보안 설정할 수 있습니다. 역할 맵핑에 대해 사용자 인증, 전송 보안, 권한 제어 및 사용자를 정의하는 보안 메커니즘을 구성할 수 있습니다.

시작하기 전에

보안 제한조건을 올바르게 정의하려면 애플리케이션 및 애플리케이션이 노출시키는 RESTful 자원에 익숙해야 합니다. 이러한 지식을 통해 애플리케이션 및 애플리케이션이 노출시키는 개별 자원에 필요한 적합한 보안 역할을 판별할 수 있습니다.

REST 애플리케이션을 보안 설정하는 방법을 보여주기 위해 이 주제에서는 AddressBookApp이라고 하는 샘플 REST 애플리케이션을 사용합니다.

애플리케이션 서버에서 애플리케이션의 설치를 완료해야 합니다. 예를 들어, AddressBookApp 애플리케이션을 설치한 후에 profile_root/config/cells/cellName/applications/applicationName.ear/deployments/applicationName_war/applicationName.war/WEB-INF 디렉토리에 있는 AddressBookApp 배치 디스크립터는 다음 예와 같이 표시됩니다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app id="WebApp_1255468655347">
 <display-name>Sample REST Web Application</display-name>
  	<servlet>
    <servlet-name>AddressBookApp</servlet-name>
    <servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>com.test.AddressBookApplication</param-value>
</init-param>
    		<load-on-startup>1</load-on-startup>
  	</servlet>
  	<servlet-mapping>
    <servlet-name>AddressBookApp</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  	</servlet-mapping>
</web-app>
이 예제에서 서블릿 맵핑은 REST 자원이 /app_root_context/rest 디렉토리에서 제공됨을 나타냅니다. 여기서, app_root_context는 애플리케이션 설치 중 구성한 것입니다. 기본 루트 컨텍스트는 /입니다.

WebSphere Application Server에 대해 보안을 사용으로 설정해야 합니다.

이 태스크 정보

웹 컨테이너를 사용하여 인증 및 권한 부여 제한조건을 애플리케이션 서버 환경에서 실행되고 있는 REST 애플리케이션에 적용할 수 있습니다. 인증은 최소 레벨의 보안이 필요하고 호출자의 ID를 기반으로 하여 추가로 보호해야 하는 비즈니스 REST 자원의 기본 보안 요구사항입니다.

REST 자원에 대해 다음 보안 메커니즘을 구성할 수 있습니다.
  • 사용자는 HTTP 기본 인증 또는 양식 로그인을 사용하여 애플리케이션에 대해 인증해야 합니다.
  • REST 자원 호출 시 전송에 SSL 채널을 사용하도록 애플리케이션을 구성합니다.
  • REST 자원 패턴에서 역할 기반 권한 부여 제한조건을 정의합니다.
  • 사용자 ID 및 역할을 판별하기 위해 어노테이션이 있는 SecurityContext 오브젝트의 프로그래밍 방식 사용을 구현합니다.

프로시저

  1. 애플리케이션 서버에 대해 보안이 사용으로 설정되는지 확인하십시오.
    1. WebSphere Application Server 관리 콘솔을 시작하십시오.

      배치 관리자를 시작하고 브라우저에 WebSphere Application Server, Network Deployment 서버 주소를 입력하십시오. 기본적으로 콘솔은 http://your_host.your_domain:9060/ibm/console에 있습니다.

      보안이 현재 사용 안함으로 설정되어 있는 경우 사용자 ID에 대한 프롬프트가 표시됩니다. 사용자 ID로 로그인하십시오. 그러나 현재 보안이 사용으로 설정되어 있는 경우 사용자 ID 및 비밀번호 둘 다에 대한 프롬프트가 표시됩니다. 사전 정의된 관리 사용자 ID 및 비밀번호를 사용하여 로그인하십시오.

    2. 보안 > 글로벌 보안을 클릭하십시오.

      애플리케이션 보안 사용을 선택하십시오.

      문제점 방지 문제점 방지: 관리 보안을 사용으로 설정해야 합니다. 관리 보안이 사용으로 설정되어 있는 경우 애플리케이션 보안이 사용으로 설정되게 할 수 있습니다. gotcha
  2. 보안 제한조건을 추가하십시오.
    애플리케이션의 web.xml 파일을 편집하거나 어셈블리 도구를 사용하여 애플리케이션에 보안 제한조건을 추가하십시오. 다음 코드 스니펫은 AddressBookApp 샘플 애플리케이션에 적용되는 보안 제한조건입니다.
    <!-- Security constraint for the sample application -->
      <security-constraint id="SecurityConstraint_1">
        <!-- This defines the REST resource associated with the constraint. -->
        <web-resource-collection id="WebResourceCollection_1">
          <web-resource-name>AddressBookApp</web-resource-name>
          <description>Protection area for Rest resource /addresses </description>
          <url-pattern>/rest/addresses</url-pattern>
          <http-method>GET</http-method>
          <http-method>POST</http-method>
        </web-resource-collection>
    
        <!—This defines an authorization constraint by requiring Role1 for the resource. -->
        <auth-constraint id="AuthConstraint_1">
          <description>Used to guard resources under this url-pattern </description>
          <role-name>Role1</role-name>
        </auth-constraint>
      </security-constraint>

    이 예에서 /root_context/rest/addresses에는 HTTP GET 또는 POST 요청에 응답할 수 있는 웹 자원이 있습니다. 보안 제한조건 AuthConstraint_1은 웹 자원에 적용됩니다. 권한 제한조건은 사용자가 자원에 액세스하려면 Role1 역할이 필요함을 지정합니다.

  3. 다음 보안 메커니즘 중 하나 이상을 선택하여 REST 애플리케이션에 대해 구성하십시오.
    • 기본 HTTP 인증을 사용으로 설정하십시오.
      1. 이전에 설명한 대로 web.xml 파일을 편집하여 보안 제한조건을 추가하십시오.
      2. 기본 HTTP 인증을 사용으로 설정하도록 web.xml 파일을 구성하십시오.
        애플리케이션의 web.xml 파일을 편집하고 다음 요소를 추가하여 기본 HTTP 인증의 사용을 지정하십시오. 기본적으로 애플리케이션 서버 보안 런타임 환경은 이 인증 메소드를 사용합니다.
        <!-- This defines a HTTP basic authentication login configuration. -->
         <login-config>
                <auth-method>BASIC</auth-method>
                <realm-name>test realm</realm-name>
         </login-config>
        HTTP기본 인증 메소드가 정의되었습니다. 자원에 액세스하려는 사용자는 신임 정보를 사용하여 로그인해야 합니다.
    • 양식 로그인을 사용으로 설정하십시오.
      1. 이전에 설명한 대로 web.xml 파일을 편집하여 보안 제한조건을 추가하십시오.
      2. 애플리케이션의 web.xml 파일을 편집하고 다음 요소를 추가하여 양식 로그인의 사용을 지정하십시오.
        <login-config>
              <auth-method>FORM</auth-method>
              <form-login-config>
                 <form-login-page>/logon.jsp</form-login-page>
                 <form-error-page>/logonError.jsp</form-error-page>
              </form-login-config>
        </login-config>
        logon.jsp 및 logonError.jsp 웹 페이지 값을 각각 양식 로그인과 오류 처리로 대체해야 합니다. 애플리케이션에 액세스할 때 사용자는 인증을 위한 logon.jsp 웹 페이지를 통해 경로가 재지정됩니다. 인증에 실패하면 사용자는 logonError.jsp 웹 페이지로 경로 재지정됩니다. 다음 예는 애플리케이션 웹 애플리케이션 아카이브(WAR) 파일에서 logon.jsp 및 logonError.jsp 페이지의 배치를 보여줍니다.
        META-INF
              logon.jsp
              logonError.jsp
              WEB-INF/classes/
              WEB-INF/classes/
              WEB-INF/classes/com/
              WEB-INF/classes/com/test/   
              WEB- NF/classes/com/test/AddressBookApplication.class
              WEB-INF/classes/com/test/AddressBookResource.class
        다음 코드 스니펫은 샘플 로그인 양식을 보여줍니다.
        <html>
        <head>
            <title>Login Page</title>
        </head>
        <h2>Hello, please log in:</h2>
        <br><br>
        <form action="j_security_check" method=post>
            <p><strong>Please Enter Your User Name: </strong>
            <input type="text" name="j_username" size="25">
            <p><p><strong>Please Enter Your Password: </strong>
            <input type="password" size="15" name="j_password">
            <p><p>
            <input type="submit" value="Submit">
            <input type="reset" value="Reset">
        </form>
        </html>
    • 애플리케이션에 대해 SSL을 사용으로 설정하십시오.
      1. 이전에 설명한 대로 web.xml 파일을 편집하여 보안 제한조건을 추가하십시오.
      2. 애플리케이션의 web.xml 파일을 편집하고 보안 제한조건 요소에서 다음 요소를 추가하십시오.
        <user-data-constraint id="UserDataConstraint_1">
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
         </user-data-constraint>
        SSL 사용이 필요하지 않은 경우 이 제한조건을 건너뛰거나 CONFIDENTIAL 값을 NONE으로 대체할 수 있습니다.
    • URL 패턴을 사용하여 권한 제어가 자원을 보호할 수 있게 합니다.
      1. 이전에 설명한 대로 web.xml 파일을 편집하여 보안 제한조건을 추가하십시오.
      2. 애플리케이션의 web.xml 파일을 편집하고 보안 제한조건 요소에서 다음 요소를 추가하십시오. 다음 예에서 Role1Role2는 각각 REST 자원 /rest/addresses/rest/resources/{i}를 각각 보호하도록 지정합니다.
        <security-constraint id="SecurityConstraint_1">
            <web-resource-collection id="WebResourceCollection_1">
              <web-resource-name>AddressBookApp</web-resource-name>
              <description>Protection area for Rest Servlet</description>
              <url-pattern>/rest/addresses</url-pattern>
              <http-method>GET</http-method>
              <http-method>POST</http-method>
            </web-resource-collection>
            <auth-constraint id="AuthConstraint_1">
                 <description> Role1 for this rest resource </description>
                 <role-name>Role1</role-name>
              </auth-constraint> 
        </security-constraint>
        
        <security-constraint id="SecurityConstraint_2">
            <web-resource-collection id="WebResourceCollection_2">
              <web-resource-name>AddressBookApp</web-resource-name>
              <description>Protection area for Rest Servlet</description>
              <url-pattern>/rest/addresses/*</url-pattern>
              <http-method>GET</http-method>
              <http-method>POST</http-method>
            </web-resource-collection>
            <auth-constraint id="AuthConstraint_2">
                 <description> Role2 for this rest resource </description>
                 <role-name>Role2</role-name>
              </auth-constraint>
        </security-constraint>

        이 예에서 Role1의 구성원인 사용자만 root-context/rest/addresses에 액세스할 수 있으며 Role2의 구성원인 사용자만 root-context/rest/addresses/{i} 자원에 액세스할 수 있습니다.

        문제점 방지 문제점 방지: 정의한 보안 제한의 서블릿 맵핑을 사용하여 보호 설정된 자원의 경로에 접두부를 지정해야 합니다. 액세스 검사 생략을 방지하기 위해 서블릿을 /* 경로에 맵핑하도록 선택할 수 있습니다. 이 맵핑은 루트 컨텍스트 아래 모든 자원을 보호합니다. gotcha
        <web-app> 요소에 역할 정의 요소를 삽입하여 역할을 정의해야 합니다. 예를 들면, 다음과 같습니다.
        <security-role id="SecurityRole_1">
            <description>This is Role1</description>
            <role-name>Role1</role-name>
        </security-role>
        <security-role id="SecurityRole_2">
            <description>This is Role2</description>
            <role-name>Role2</role-name>
        </security-role>

        배치 디스크립터에 대해 작성한 변경사항은 애플리케이션 서버 런타임 환경에서 자동으로 적용되므로 애플리케이션 또는 서버를 다시 시작하지 않아도 됩니다. 맵핑 URL와 같이 다른 유형의 변경사항은 애플리케이션 서버를 다시 시작해야 합니다. 변경사항이 확실히 적용되도록 애플리케이션을 다시 시작하는 것이 권장됩니다.

    • 어노테이션이 있는 보안 컨텍스트를 프로그래밍 방식으로 사용합니다.
      애플리케이션 개발자는 JAX-RS @SecurityContext 어노테이션을 사용하여 보안 컨텍스트를 서버 측의 자원까지 프로그램 방식으로 전달하고 런타임 중 보안 속성 정의를 사용으로 설정할 수 있습니다. 다음은 SecurityContext 인터페이스에서 제공하는 기능입니다.
      public String getAuthenticationScheme()
      public Principal getUserPrincipal()
      public boolean isUserInRole(String role)
      다음 예는 SecurityContext 인터페이스를 보여줍니다.
      package com.test;
      
      import javax.ws.rs.GET; 
      import javax.ws.rs.Consumes;
      import javax.ws.rs.POST;
      import javax.ws.rs.Path;
      import javax.ws.rs.PathParam;
      import javax.ws.rs.Produces;
      import javax.ws.rs.ext.*;
      import javax.ws.rs.core.SecurityContext;
      import javax.ws.rs.core.Context;
      
      /**   
       * A sample resource that provides access to an address book. 
       * 
       */
      @Path(value="/addresses")
      public class AddressBookResource {
      	
      	@Context private SecurityContext securityContext;
          
          private static String[] list = new String[] {
              "Michael",
              "Ron",
              "Jane",
              "Sam"
          };
          
          @GET
          @Produces(value="text/plain")
          public String getList() {
             // retrieve the authentication scheme that was used(e.g. BASIC)
             String authnScheme = securityContext.getAuthenticationScheme());
             // retrieve the name of the Principal that invoked the resource
             String username = securityContext.getUserPrincipal().getName());
             // check if the current user is in Role1 
              Boolean isUserInRole = securityContext.isUserInRole(“Role1”);
          	 
              StringBuffer buffer = new StringBuffer();
              buffer.append("{");
              for (int i = 0; i < list.length; ++i) {
                  if (i != 0) 
                      buffer.append(", ");
                  buffer.append(list[i]);
              }
              buffer.append("}");
              
              return buffer.toString();
          }
      }
    • 보안 클라이언트 핸들러를 사용하여 기본 HTTP 인증 수행
      선택적으로 보안 클라이언트 핸들러를 사용하여 보안 JAX-RS 자원으로 기본 HTTP 인증을 수행할 수 있습니다. 다음 예는 이 태스크를 수행하기 위한 단순 프로그래밍 모델을 보여줍니다.
      /**
       * This snippet illustrates the use of the JAX-RS SecurityHandler by a
       * client to perform HTTP basic authentication with a target service.
       */ 
       
       import org.apache.wink.client.ClientConfig;
       import org.apache.wink.client.Resource;
       import org.apache.wink.client.RestClient;
       import org.apache.wink.client.handlers.BasicAuthSecurityHandler;
      
       ClientConfig config = new ClientConfig();
        BasicAuthSecurityHandler secHandler = new    
       BasicAuthSecurityHandler();
      
       // Set the user credential.
       secHandler.setUsername("user1");
       secHandler.setPassword("security");
      
       // Add this security handler to the handlers chain.
       config.handlers(secHandler);
      
       // Create the REST client instance. 
       RestClient client = new RestClient(config);
      
       // Create the resource instance to interact with 
       // substitute for your resource address
       resource =  
        client.resource("http://localhost:8080/path/to/resource");
      
      // Now you are ready to call your resource.
      BasicAuthSecurityHandler 클래스를 사용하는 경우 URL에 맞는 https 스킴을 사용하는 자원을 대상으로 하고 대상 애플리케이션이 SSL 사용으로 설정되어 있는지 확인하십시오. 사용자 신임 정보를 전송할 때 SSL 연결을 사용하도록 권장됩니다. 보안 핸들러에서 false 값으로 setSSLRequired 메소드를 호출하여 BasicAuthSecurityHandler 클래스에서 SSL에 대한 요구사항을 명시적으로 끌 수 있습니다. 기본적으로 이 값은 true입니다.
      secHandler.setSSLRequired(false);
      선택적으로 다음과 같이 클라이언트의 Java™ 명령행에서 사용자 신임 정보를 제공할 수도 있습니다.
      java -Duser=test_user -Dpassword=your_password  your_client_program
      다음과 같이 Java 명령행에 위치가 지정되는 특성 파일에서 선택적으로 사용자 신임 정보를 검색할 수 있습니다.
      java -Dclientpropsdir=directory_for_your_properties_file  your_client_program
      여기서, directory_for_your_properties_file에는 userpassword 특성이 설정된 wink.client.props 파일이 있습니다.

결과

보안 제한조건을 정의한 후 애플리케이션에서 정의되는 REST 자원에 대한 액세스는 사용자 인증에 성공한 경우에만 가능합니다. 또한 다양한 자원 URL 패턴에 역할 제한조건을 적용했으므로 이러한 자원에 대한 역할 기반 액세스가 가능합니다.

다음 예에서는 이전 프로시저 단계를 사용하여 보안 제한이 정의된 AddressBookApp 샘플 애플리케이션의 web.xml 배치 디스크립터를 보여줍니다.
<web-app id="WebApp_1255468655347">
    <display-name>Sample REST Web Application</display-name>
    	<servlet>
        <servlet-name>AddressBookApp</servlet-name>
        <servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.test.AddressBookApplication</param-value>
        </init-param>
        		<load-on-startup>1</load-on-startup>
    	</servlet>
    	<servlet-mapping>
        <servlet-name>AddressBookApp</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    	</servlet-mapping>
    <security-constraint id="SecurityConstraint_1">
      <web-resource-collection id="WebResourceCollection_1">
        <web-resource-name>AddressBookApp</web-resource-name>
        <description>Protection area for Rest Servlet</description>
        <url-pattern>/rest/addresses</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
      </web-resource-collection>
      <auth-constraint id="AuthConstraint_1">
         <description>Role1 for this rest servlet</description>
         <role-name>Role1</role-name>
      </auth-constraint> 
      <user-data-constraint id="UserDataConstraint_1">
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
      </user-data-constraint>
    </security-constraint>
    <security-constraint id="SecurityConstraint_2">
      <web-resource-collection id="WebResourceCollection_2">
        <web-resource-name>AddressBookApp</web-resource-name>
        <description>Protection area for Rest Servlet</description>
        <url-pattern>/rest/addresses/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
      </web-resource-collection>
      <auth-constraint id="AuthConstraint_2">
         <description>Role2 for this rest servlet</description>
         <role-name>Role2</role-name>
      </auth-constraint> 
      <user-data-constraint id="UserDataConstraint_1">
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
      </user-data-constraint>
    </security-constraint>
    <security-role id="SecurityRole_1">
         <description>This is Role1</description>
         <role-name>Role1</role-name>
    </security-role>
    <security-role id="SecurityRole_2">
         <description>This is Role2</description>
         <role-name>Role2</role-name>
    </security-role>
    <login-config>
      <auth-method>FORM</auth-method>
      <form-login-config>
         <form-login-page>/logon.jsp</form-login-page>
         <form-error-page>/logonError.jsp</form-error-page>
      </form-login-config>
    </login-config>
</web-app>

다음에 수행할 작업

관리 콘솔을 사용하여 JAX-RS 애플리케이션에 대한 보안을 관리할 수 있습니다.


주제 유형을 표시하는 아이콘 태스크 주제



시간소인 아이콘 마지막 업데이트 날짜: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_jaxrs_impl_securejaxrs_webcont
파일 이름:twbs_jaxrs_impl_securejaxrs_webcont.html