การแมปบทบาทภายนอก

การแมปบทบาทภายนอกช่วยให้คุณแมปกลุ่มหรือบทบาทของคุณเองกับการควบคุมการเข้าถึงตามบทบาทได้ (RBAC) บทบาทและกลุ่มที่สร้างใน Apigee Edge ฟีเจอร์นี้ใช้ได้กับ Edge เท่านั้นสำหรับ Private Cloud

ข้อกำหนดเบื้องต้น

  • คุณต้องเป็นผู้ดูแลระบบ Apigee Private Cloud ที่มีผู้ดูแลระบบส่วนกลาง ข้อมูลเข้าสู่ระบบในการกำหนดค่านี้
  • คุณจำเป็นต้องทราบไดเรกทอรีรูทของการติดตั้ง Apigee Edge Private Cloud ไดเรกทอรีรากเริ่มต้นคือ /opt

ตัวอย่างการตั้งค่าแบบทีละขั้นตอน

โปรดดู บทความนี้ในฟอรัมชุมชน Apigee สำหรับตัวอย่างทีละขั้นตอนในการตั้งค่า การแมปบทบาท

การกำหนดค่าเริ่มต้น

การแมปบทบาทภายนอกจะปิดใช้อยู่โดยค่าเริ่มต้น

เปิดใช้การแมปบทบาทภายนอก

วิธีเปิดใช้การแมปบทบาทภายนอก

  1. ก่อนที่คุณจะสามารถกำหนดค่าต่อไปนี้ให้เสร็จสมบูรณ์ คุณต้องสร้างคลาส Java ที่ ใช้งานอินเทอร์เฟซ ExternalRoleMapperServiceV2 และรวมการติดตั้งใช้งานของคุณใน classpath ของเซิร์ฟเวอร์การจัดการ:
    /opt/apigee/edge-management-server/lib/thirdparty/

    สำหรับรายละเอียดเกี่ยวกับการติดตั้งนี้ โปรดดูที่ส่วนเกี่ยวกับ ExternalRoleMapperImpl ตัวอย่างการติดตั้งใช้งานภายหลังในเอกสารนี้

  2. เข้าสู่ระบบเซิร์ฟเวอร์การจัดการ Apigee Edge แล้วหยุดกระบวนการของเซิร์ฟเวอร์การจัดการโดยทำดังนี้
    /opt/apigee/apigee-service/bin/apigee-service edge-management-server stop
  3. เปิด /opt/apigee/customer/application/management-server.properties ในเครื่องมือแก้ไขข้อความ หากไม่มี ให้สร้างไฟล์นี้
  4. แก้ไขไฟล์คุณสมบัติเพื่อตั้งค่าต่อไปนี้
    # The user store to be used for authentication.
    # Use "externalized.authentication" for LDAP user store.
    # Note that for authorization, we continue to use LDAP.
    # See Enabling external authentication more on enabling external auth.
    conf_security_authentication
    .user.store=externalized.authentication

    #Enable the external authorizations role mapper.
    conf_security_externalized
    .authentication.role.mapper.enabled=true
    conf_security_externalized
    .authentication.role.mapper.implementation.class=com.customer.authorization.impl.ExternalRoleMapperImpl
  5. บันทึกไฟล์ management-server.properties
  6. ตรวจสอบว่าผู้ใช้ Apigee เป็นเจ้าของ management-server.properties ดังนี้ วันที่
    chown apigee:apigee /opt/apigee/customer/application/management-server.properties
  7. เริ่มต้นเซิร์ฟเวอร์การจัดการด้วยคำสั่งต่อไปนี้
    /opt/apigee/apigee-service/bin/apigee-service edge-management-server start

ปิดใช้การให้สิทธิ์ภายนอก

ในการปิดใช้งานการให้สิทธิ์ภายนอก:

  1. เปิด /opt/apigee/customer/application/management-server.properties ในเครื่องมือแก้ไขข้อความ หากไม่มีไฟล์ ให้สร้างขึ้นมา
  2. เปลี่ยนที่เก็บผู้ใช้การตรวจสอบสิทธิ์เป็น "LDAP":
    conf_security_authentication.user.store=ldap
  3. ตั้งค่าพร็อพเพอร์ตี้นี้เป็น "เท็จ"
    conf_security_externalized.authentication.role.mapper.enabled=false
  4. รีสตาร์ทเซิร์ฟเวอร์การจัดการ
    /opt/apigee/apigee-service/bin/apigee-service edge-management-server start

เกี่ยวกับ ExternalRoleMapperImpl ตัวอย่างการใช้งาน

ในไฟล์การกำหนดค่า Security.properties ซึ่งอธิบายไว้ก่อนหน้านี้ในการเปิดใช้การแมปบทบาทภายนอก โปรดระบุบรรทัดต่อไปนี้

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

คลาสนี้ใช้อินเทอร์เฟซ ExternalRoleMapperServiceV2 และจำเป็นต้องใช้ สิ่งที่คุณต้องทำ สร้างการใช้งานคลาสนี้ของคุณเอง ซึ่งสะท้อนให้เห็นถึงกลุ่มของคุณ เมื่อเสร็จแล้ว วางคลาสที่คอมไพล์ใน JAR และใส่ JAR นั้นในคลาสพาธของเซิร์ฟเวอร์การจัดการใน

/opt/apigee/edge-management-server/lib/thirdparty/

คุณสามารถตั้งชื่อคลาสและแพ็กเกจได้ตามต้องการ ExternalRoleMapperServiceV2 สามารถเข้าถึงได้ใน classpath ของคุณ และมีการอ้างอิงอย่างถูกต้องใน 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)));
                       
// In OPDK 4.50 and later, do
                       
// results.add(new NameSpacedRole("orgadmin", OrganizationNamespace.of(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();
   
}

}