Private Cloud용 Edge v4.18.01
외부 역할 매핑을 사용하면 자체 그룹 또는 역할을 역할 기반 액세스 제어에 매핑할 수 있습니다. Apigee Edge에서 생성된 (RBAC) 역할 및 그룹 이 기능은 Edge Private에서만 사용할 수 있습니다. 있습니다.
새로운 기능
4.18.01 이전의 Private Cloud용 Edge 출시 버전에 대한 외부 역할 매핑 서비스는 지원 중단되었습니다. 외부 역할 매핑의 버전 4.18.01은 버그가 수정된 업데이트된 버전입니다. 새로운 기능이 추가되었습니다.
- 사용자가 인증 403 금지 응답을 받을 때 발생하는 문제를 해결했습니다. 사용자를 인증합니다.
- X-Apigee-Current-User 헤더가 이제 외부 역할 매핑에서 지원됩니다. 이제 적절한 액세스 권한이 있는 사용자 (시스템 관리자)가 다른 사용자에게 할당된 역할을 볼 수 있습니다.
기본 요건
- 전역 시스템 관리자가 있는 Apigee Private Cloud 시스템 관리자여야 합니다. 사용자 인증 정보를 사용하여 이 구성을 수행할 수 있습니다.
-
Apigee Edge Private Cloud 설치의 루트 디렉터리를 알고 있어야 합니다. 이 기본 루트 디렉터리는 /opt입니다.
단계별 설정 예
를 참조하세요. 이 도움말을 참고하세요. 역할 매핑을 사용합니다
기본 구성
외부 역할 매핑은 기본적으로 사용 중지되어 있습니다.
외부 역할 매핑 사용 설정
- 다음 구성을 완료하려면 먼저 다음 구성을 완료하는 Java 클래스를 만들어야 합니다.
ExternalRoleMapperServiceV2 인터페이스를 구현하고
관리 서버 클래스 경로:
/opt/apigee/edge-management-server/lib/thirdparty/
이 구현에 대한 자세한 내용은 ExternalRoleMapperImpl 정보' 섹션을 참조하세요. 샘플 구현을 참조하세요. - Apigee Edge 관리 서버에 로그인한 다음 관리 서버를 중지합니다.
프로세스:
> /opt/apigee/apigee-service/bin/apigee-service 에지 관리 서버 중지 - /opt/apigee/customer/application/management-server.properties를 엽니다. 코드를 작성합니다 이 파일이 없으면 새로 만듭니다.
- 속성 파일을 수정하여 다음과 같이 설정합니다.
# 있습니다.
# 'externalized.authentication'을 사용합니다. LDAP 사용자 스토어용입니다.
# 승인에는 LDAP가 계속 사용됩니다.
# 외부 인증 사용 설정에 대해 자세히 알아보기 자세히 알아보세요.
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.ExternalRoleMapperImpl
중요: 위 구성에서 참조된 구현 클래스 및 패키지 이름 (ExternalRoleMapperImpl)은 예일 뿐입니다. 반드시 구현해야 하는 클래스이며 클래스 이름을 지정하고 원하는 대로 패키징할 수 있습니다. 구현에 관한 자세한 내용은 자세한 내용은 ExternalRoleMapperImpl 샘플 구현 클래스를 참조하세요. 이 강좌는 을(를) 구현해야 합니다. - management-server.properties 파일을 저장합니다.
- management-server.properties의 소유자는 다음과 같습니다.
Apigee 사용자:?
> chown apigee:apigee /opt/apigee/customer/application/management-server.properties - 관리 서버를 시작합니다.
> /opt/apigee/apigee-service/bin/apigee-service 에지 관리 서버 시작
외부 승인 사용 중지
외부 승인을 사용 중지하려면 다음 단계를 따르세요.
- /opt/apigee/customer/application/management-server.properties를 엽니다. 코드를 작성합니다 파일이 없으면 새로 만듭니다.
- 인증 사용자 스토어를 LDAP로 변경합니다.
conf_security_authentication.user.store=ldap
속성을 false로 설정합니다. conf_security_externalized.authentication.role.mapper.enabled=false- 관리 서버를 다시 시작합니다.
> /opt/apigee/apigee-service/bin/apigee-service 에지 관리 서버 시작
ExternalRoleMapperImpl 정보 샘플 구현
앞서 외부 역할 매핑 사용 설정에서 설명한 security.properties 구성 파일에서 다음 행을 확인합니다.
externalized.authentication.role.mapper.implementation.class=com.customer.authorization.impl.ExternalRoleMapperImpl
이 클래스는 ExternalRoleMapperServiceV2 인터페이스를 구현하며, 필수입니다. 해야 할 일 각 그룹을 반영하는 이 클래스의 자체 구현을 만듭니다. 완료되면 컴파일된 클래스를 JAR에 넣고 이 JAR을 관리 서버의 클래스 경로에 넣습니다.
/opt/apigee/edge-management-server/lib/thirdparty/<ph type="x-smartling-placeholder">
클래스가 구현되어 있다면 클래스 이름을 지정하고 원하는 대로 패키징할 수 있습니다. ExternalRoleMapperServiceV2를 클래스 경로에서 액세스할 수 있으며 management-server.properties 구성 파일
다음은 ExternalRoleMapperImpl 클래스의 상세한 샘플 구현입니다.
package com.customer.authorization.impl; import com.apigee.authentication.*; 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 expected namespaces. */ public class ExternalRoleMapperImpl implements ExternalRoleMapperServiceV2 { InitialDirContext dirContext = null; @Override public void start(ConfigBean arg0) throws ConnectionException { try { // Customer Specific Implementation will override the // ImplementDirContextCreationLogicForSysAdmin method implementation. // Create InitialDirContext based on the system admin user credentials. dirContext = ImplementDirContextCreationLogicForSysAdmin(); } catch (NamingException e) { // TODO Auto-generated catch block throw new ConnectionException(e); } } @Override public void stop() throws Exception { } /** * This method should be replaced with customer's implementation * For given roleName under expectedNamespace, return all users that belongs to this role * @param roleName * @param expectedNamespace * @return All users that belongs to this role. For each user, please return the username/email that is stored in Apigee LDAP * @throws ExternalRoleMappingException */ @Override public Collection<String> getUsersForRole(String roleName, NameSpace expectedNamespace) throws ExternalRoleMappingException { Collection<String> users = new HashSet<>(); if (expectedNamespace instanceof SystemNamespace) { // If requesting all users with sysadmin role if (roleName.equalsIgnoreCase("sysadmin")) { // Add sysadmin's email to results users.add("sysadmin@wacapps.net"); } } else { String orgName = ((OrganizationNamespace) expectedNamespace).getOrganization(); // If requesting all users of engRole in Apigee LDAP if (roleName.equalsIgnoreCase("engRole")) { // Get all users in corresponding groups in customer's LDAP. In this case looking for 'engGroup'; SearchControls controls = new SearchControls(); controls.setSearchScope(1); try { NamingEnumeration<SearchResult> res = dirContext.search("ou=groups,dc=corp,dc=wacapps,dc=net", "cn=engGroup", new Object[]{"",""}, controls); while (res.hasMoreElements()) { SearchResult sr = res.nextElement(); // Add all users into return users.addAll(sr.getAttributes().get("users").getAll()); } } catch (NamingException e) { // Customer needs to handle the exception here } } } return users; } /** * * This method would be implemented by the customer and would be invoked * while including using X-Apigee-Current-User header in request. * * X-Apigee-Current-User allows the customer to login as another user * * Below is the basic example. * * If User has sysadmin role then it's expected to set SystemNameSpace * along with the expected NameSpace. Otherwise role's expectedNameSpace * to be set for the NameSpacedRole. * * Collection<NameSpacedRole> results = new HashSet<NameSpacedRole>(); * * NameSpacedRole sysNameSpace = new NameSpacedRole("sysadmin", * SystemNamespace.get()); * * String orgName = * ((OrganizationNamespace) expectedNameSpace).getOrganization(); * * NameSpacedRole orgNameSpace = new NameSpacedRole ("orgadmin", * expectedNameSpace); * * results.add(sysNameSpace); * * results.add(orgNameSpace); * * * @param username UserA's username * @param password UserA's password * @param requestedUsername UserB's username. Allow UserA to request UserB's userroles with * UserA's credentials when requesting UserB as X-Apigee-Current-User * @param expectedNamespace * @return * @throws ExternalRoleMappingException */ @Override public Collection<NameSpacedRole> getUserRoles(String username, String password, String requestedUsername, NameSpace expectedNamespace) throws ExternalRoleMappingException { /************************************************************/ /******************** Authenticate UserA ********************/ /************************************************************/ // Customer Specific Implementation will override the // ImplementDnameLookupLogic method implementation. // obtain dnName for given username. String dnName = ImplementDnNameLookupLogic(username); // Obtain dnName for given requestedUsername. String requestedDnName = ImplementDnNameLookupLogic(requestedUsername); if (dnName == null || requestedDnName == null) { System.out.println("Error "); } DirContext dirContext = null; try { // Customer Specific Implementation will override the // ImplementDirectoryContextCreationLogic method implementation // Create a directory context with dnName or requestedDnName and password dirContext = ImplementDirectoryContextCreationLogic(); /************************************************/ /*** Map internal groups to apigee-edge roles ***/ /************************************************/ return apigeeEdgeRoleMapper(dirContext, requestedDnName, expectedNamespace); } catch (Exception ex) { ex.printStackTrace(); System.out.println("Error in authenticating User: {}" + new Object[] { username }); } finally { // Customer implementation to close // ActiveDirectory/LDAP context. } return null; } /** * * This method would be implemented by the customer and would be invoked * wihle using username and password for authentication and without the * X-Apigee-Current-User header * * The customer can reuse implementations in * getUserRoles(String username, String password, String requestedUsername, NameSpace expectedNamespace) * by * return getUserRoles(username, password, username, expectedNamespace) * in implementations. * * or the customer can provide new implementations as shown below. */ @Override public Collection<NameSpacedRole> getUserRoles(String username, String password, NameSpace expectedNamespace) throws ExternalRoleMappingException { /*************************************************************/ /****************** Authenticate Given User ******************/ /*************************************************************/ // Customer Specific Implementation will override the // ImplementDnameLookupLogic implementation. // Obtain dnName for given username or email address. String dnName = ImplementDnNameLookupLogic(username); if (dnName == null) { System.out.println("Error "); } DirContext dirContext = null; try { // Create a directory context with username or dnName and password dirContext = ImplementDirectoryContextCreationLogic(); /************************************************/ /*** Map internal groups to apigee-edge roles ***/ /************************************************/ return apigeeEdgeRoleMapper(dirContext, dnName, expectedNamespace); } catch (Exception ex) { ex.printStackTrace(); System.out.println("Error in authenticating User: {}" + new Object[] { username }); } finally { // Customer implementation to close // ActiveDirectory/LDAP context. } return null; } /** * * This method would be implemented by the customer and would be invoked * while using security token or access token as authentication credentials. * */ @Override public Collection<NameSpacedRole> getUserRoles(String username, NameSpace expectedNamespace) throws ExternalRoleMappingException { /*************************************************************/ /****************** Authenticate Given User ******************/ /*************************************************************/ // Customer Specific Implementation will override the // ImplementDnameLookupLogic implementation. // Obtain dnName for given username or email address. String dnName = ImplementDnNameLookupLogic(username); if (dnName == null) { System.out.println("Error "); } DirContext dirContext = null; try { // Create a directory context with username or dnName and password dirContext = ImplementDirectoryContextCreationLogic(); /************************************************/ /*** Map internal groups to apigee-edge roles ***/ /************************************************/ return apigeeEdgeRoleMapper(dirContext, dnName, expectedNamespace); } catch (Exception ex) { ex.printStackTrace(); System.out.println("Error in authenticating User: {}" + new Object[] { username }); } finally { // Customer implementation to close // ActiveDirectory/LDAP context. } return null; } /** * This method should be replaced with Customer Specific Implementations * * Provided as a sample Implementation of mapping user groups to apigee-edge roles */ private Collection<NameSpacedRole> apigeeEdgeRoleMapper(DirContext dirContext, String dnName, NameSpace expectedNamespace) throws Exception { Collection<NameSpacedRole> results = new HashSet<NameSpacedRole>(); /****************************************************/ /************ Fetch internal groups *****************/ /****************************************************/ String groupDN = "OU=Groups,DC=corp,DC=wacapps,DC=net"; String userFilter = "(user=userDnName)"; SearchControls controls = new SearchControls(); controls.setSearchScope(SearchControls.ONELEVEL_SCOPE); // Looking for all groups the user belongs to in customer's LDAP NamingEnumeration<SearchResult> groups = dirContext.search(groupDN,userFilter.replace("userDnName", dnName), 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 internal groups to apigee-edge roles ***/ /************************************************/ if (groupName.equals("BusDev")) { results.add(new NameSpacedRole("businessAdmin",SystemNamespace.get())); } else if (groupName.equals("Engineering")) { if (expectedNamespace instanceof OrganizationNamespace) { String orgName = ((OrganizationNamespace) expectedNamespace).getOrganization(); results.add(new NameSpacedRole("orgadmin", new OrganizationNamespace(orgName))); } } 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 !!!!!"); } return results; } /** * The customer need to replace with own implementations for getting dnName for given user */ private String ImplementDnNameLookupLogic(String username) { // Connect to the customer's own LDAP to fetch user dnName return customerLDAP.getDnName(username); } /** * The customer need to replace with own implementations for creating DirContext */ private DirContext ImplementDirectoryContextCreationLogic() { // Connect to the customer's own LDAP to create DirContext for given user return customerLDAP.createLdapContextUsingCredentials(); } }