외부 역할 매핑

Private Cloud용 Edge v. 4.17.05

외부 역할 매핑을 사용하면 Apigee Edge에 생성된 역할 기반 액세스 제어 (RBAC) 역할 및 그룹에 자체 그룹 또는 역할을 매핑할 수 있습니다. 

기본 요건

  • 이 구성을 수행하려면 전역 시스템 관리자 사용자 인증 정보가 있는 Apigee Private Cloud 시스템 관리자여야 합니다. 
  • Apigee Edge 프라이빗 클라우드 설치의 루트 디렉터리를 알아야 합니다. 기본 루트 디렉터리는 /opt입니다. Apigee Edge 프라이빗 클라우드 설치 중에 다른 루트 디렉터리를 선택한 경우 이 안내에 따라 /opt 대신 해당 디렉터리를 사용합니다.
  • Apigee에서 필요한 JAR 파일을 가져옵니다.

사용자가 Edge 및 디렉터리 서비스에 등록되어 있는지 확인하세요.

역할 매핑을 사용하는 경우 Edge에 액세스하는 모든 사용자는 외부 디렉터리 서비스와 Edge 사용자 저장소 모두에 있어야 합니다. 즉, 외부 디렉터리 서비스에 사용자를 추가할 때 동일한 사용자를 Apigee 사용자 저장소에 추가해야 합니다.

예를 들어 a01@company.com 사용자는 외부 디렉터리 그룹 'apiadmin'에 있습니다. 그런 다음 사용자 a01@company.com을 Edge의 orgadmin 역할에 매핑하려고 합니다. 따라서 먼저 a01@company.com 사용자를 Edge의 orgadmin 그룹에 추가해야 합니다. 

Edge 사용자를 만들어 역할에 할당하는 방법에 대한 자세한 내용은 전역 사용자 만들기를 참고하세요.

기본 구성

외부 역할 매핑은 기본적으로 사용 중지되어 있습니다.

외부 역할 매핑 사용 설정

  1. 다음 구성을 완료하려면 먼저 ExternalRoleMapperService 인터페이스를 구현하는 Java 클래스를 만들어야 합니다. 이 구현에 관한 자세한 내용은 아래 샘플 구현을 참고하세요.
  2. Apigee Edge 관리 서버에 로그인한 후 관리 서버를 중지합니다.
    > /opt/apigee/apigee-service/bin/apigee-service Edge-management-server stop
  3. 서버 상태를 확인합니다. 관리 서버가 중지되었거나 실행되고 있지 않은지 확인합니다.
    > /opt/apigee/apigee-service/bin/apigee-all status
  4. 텍스트 편집기에서 /opt/apigee/customer/application/management-server.properties를 엽니다.
  5. 다음 설정으로 management-server.properties 파일을 수정합니다.
    conf_security_authentication.user.store=externalized.authentication
    conf_security_externalized.authentication.role.mapper.enabled=true
    conf_security_externalized.authentication.role.mapper.implementation.class=com.customer.authorization.impl.impl.mapper.implementation.class=com.customer.authorization.impl.impl.mapper.implementation.class=com.customer.authorization.impl.impl.mapperImpl
    패키지 이름만 패키징할 수 있는 클래스, 클래스 이름만 구현해야 합니다.

    중요: 구현: 이 클래스 구현에 관한 자세한 내용은 아래 샘플 구현을 참고하세요. 
  6. management-server.properties 파일을 저장합니다.
  7. 관리 서버를 시작합니다.
    > /opt/apigee/apigee-service/bin/apigee-serviceedge-management-server start
  8. 서버가 실행 중인지 확인합니다.
    > /opt/apigee/apigee-service/bin/apigee-all status

외부 승인 사용 중지

외부 승인을 사용 중지하려면 다음 단계를 따르세요.

  1. 텍스트 편집기에서 /opt/apigee/customer/application/management-server.properties를 엽니다.
  2. 인증 사용자 저장소를 ldap로 변경합니다.
    conf_security_authentication.user.store=ldap
  3. 다음 속성을 false로 설정합니다.
    conf_security_externalized.authentication.role.mapper.enabled=false
  4. 관리 서버를 다시 시작합니다.
    > /opt/apigee/apigee-service/bin/apigee-serviceedge-management-server restart

ExternalRoleMapperImpl 샘플 구현 정보

위에 설명된 management-server.properties 구성 파일에서 다음 줄을 확인합니다.

conf_security_externalized.authentication.role.mapper.implementation.class=com.customer.authorization.impl.ExternalRoleMapperImpl

이 클래스는 ExternalRoleMapperService 인터페이스를 구현하며 필수입니다. 각 그룹을 반영하는 이 클래스의 자체 구현을 만들어야 합니다. 완료되면 컴파일된 클래스를 JAR에 배치하고 해당 JAR을 /<install_dir>/apigee/edge-gateway/lib/infra/libraries에 넣습니다. 

클래스와 패키지가 ExternalRoleMapperService를 구현하며 클래스 경로에서 액세스 가능하고 management-server.properties 구성 파일에서 올바르게 참조되기만 하면 원하는 클래스 및 패키지의 이름을 지정할 수 있습니다. 

다음은 ExternalRoleMapperImpl 클래스의 주석이 달린 샘플 구현입니다. 이 클래스를 컴파일하려면 Edge에 포함된 다음 JAR 파일을 참조해야 합니다.

/<install_dir>/apigee/edge-gateway/lib/infra/libraries/authentication-1.0.0.jar 
package com.apigee.authenticate;

import com.apigee.authentication.ConfigBean;
import com.apigee.authentication.ConnectionException;
import com.apigee.authentication.ExternalRoleMapperService;
import com.apigee.authentication.NameSpace;
import com.apigee.authentication.NameSpacedRole;
import com.apigee.authorization.namespace.OrganizationNamespace;
import com.apigee.authorization.namespace.SystemNamespace;
import java.util.Collection;
import java.util.HashSet;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

/** * 
 * Sample Implementation constructed with dummy roles with required namespaces.
 * 
 * Created by GopiAlagar on 6/12/15.
 */

public class ExternalRoleMapperImpl implements ExternalRoleMapperService {

    InitialDirContext dirContext = null;

    @Override
    public void stop() throws Exception {
    }

    /**
    * 
    * This method would be implemented by the customer, Below is the basic
    * example. 
    * 
    * If User has sysadmin role then it's expected to set SystemNameSpace 
    * along with the
    * res\quested NameSpace. Otherwise role's requestedNameSpace to be set 
    * for the NameSpacedRole.
    * 
    * Collection<NameSpacedRole> results = new HashSet<NameSpacedRole>();
    * 
    * NameSpacedRole sysNameSpace = new NameSpacedRole("sysadmin",
    * SystemNamespace.get());
    * 
    * String orgName =
    * ((OrganizationNamespace)requestedNameSpace).getOrganization();
    * 
    * NameSpacedRole orgNameSpace = new NameSpacedRole ("orgadmin",
    * requestedNameSpace);
    * 
    * results.add(sysNameSpace);
    * 
    * results.add(orgNameSpace);
    */

public Collection<NameSpacedRole> getUserRoles(String userName,
    String password, NameSpace requestedNameSpace) {

    /*
    * There are 3 actions performed in the below implementation
    * 1. Authenticate Given User against ADS
    * 2. Fetch the internal groups from the ADS
    * 3. Map the internal group into the apigee-edge roles
    */

    /*************************************************************/
    /******************* Authenticate Given User *******************/
    /*************************************************************/

    // Customer Specific Implementation will override this method
    // implementation.

    // Obtain dnName for given username or email address.
    String dnName = ImplementDnameLookupLogic();

    if (dnName == null) {
        System.out.println("Error ");
    }

    DirContext dirContext = null;

    Collection<NameSpacedRole> results = new HashSet<NameSpacedRole>();

    try {

        // Verify the credentials for a given username or dnName 
        // and password in order to create a directory context.
        dirContext = ImplementDirectoryContextCreationLogic();

        /****************************************************/
        /********** Fetch internal groups *******************/
        /****************************************************/

        String groupDN = "OU=Groups,DC=corp,DC=wacapps,DC=net";
        SearchControls controls = new SearchControls();
        controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
        NamingEnumeration<SearchResult> groups = dirContext.search(groupDN,"(objectClass=*)", new Object[] { "", "" }, controls);

        if (groups.hasMoreElements()) {
            while (groups.hasMoreElements()) {
                SearchResult searchResult = groups.nextElement();
                Attributes attributes = searchResult.getAttributes();
                String groupName = attributes.get("name").get().toString();

                 /**************************************/
                 /** Map the internal group into the ***/
                 /** apigee-edge roles               ***/
                 /**************************************/

                if (groupName.equals("BusDev")) {
                    results.add(new NameSpacedRole("businessAdmin",SystemNamespace.get()));

                } else if (groupName.equals("DevSupport")) {
                    results.add(new NameSpacedRole("devOpsAdmin",SystemNamespace.get()));

                } else if (groupName.equals("Engineering")) {
                    if (requestedNameSpace instanceof OrganizationNamespace) {
                        String orgName = ((OrganizationNamespace) requestedNameSpace).getOrganization();
                        results.add(new NameSpacedRole("orgadmin", new OrganizationNamespace(orgName)));
                    }

                } else if (groupName.equals("Operations") || groupName.equals("IT")) {
                    results.add(new NameSpacedRole("sysadmin",SystemNamespace.get()));

                } else if (groupName.equals("Marketing")) {
                    results.add(new NameSpacedRole("marketAdmin",SystemNamespace.get()));

                } else {
                    results.add(new NameSpacedRole("readOnly",SystemNamespace.get()));
                }
            }

        } else {

            /** 
            * In case of no group found or exception found we throw empty
            * roles.
            */
            System.out.println(" !!!!! NO  GROUPS FOUND !!!!!");
        }

    } catch (Exception ex) {
        ex.printStackTrace();
        System.out.println("Error in authenticating User: {}" + new Object[] { userName });

    } finally {
        // Customer implementation to close 
        // ActiveDirectory/LDAP context.
    }

    return results;

}

@Override
public void start(ConfigBean arg0) throws ConnectionException {

    try {
        // Create InitialDirContext.
        // Create a directory context based on the 
        // system admin user credentials.
        dirContext = ImplementDirContextCreationLogicForSysAdmin();

        } catch (NamingException e) {
            // TODO Auto-generated catch block

            throw new ConnectionException(e);

        }

    }

}