Edge for Private Cloud phiên bản 4.18.01
Chế độ ánh xạ vai trò bên ngoài cho phép bạn liên kết các nhóm hoặc vai trò của mình với chế độ kiểm soát quyền truy cập dựa trên vai trò Các vai trò và nhóm (RBAC) được tạo trên Apigee Edge. Tính năng này chỉ hoạt động với Edge Private Đám mây.
Tính năng mới
Dịch vụ Ánh xạ vai trò bên ngoài dành cho Edge dành cho các bản phát hành Đám mây riêng tư trước phiên bản 4.18.01 đã không được dùng nữa. Bản phát hành 4.18.01 của Ánh xạ vai trò bên ngoài là phiên bản cập nhật đã khắc phục lỗi và những tính năng mới đã được thêm:
- Khắc phục vấn đề bạn nhận được phản hồi 403 bị cấm khi xác thực khi xác thực với người dùng có quyền truy cập.
- X-Apigee-Current-User tiêu đề hiện đã được hỗ trợ trong mục ánh xạ vai trò bên ngoài. Người dùng có quyền truy cập thích hợp (quản trị viên hệ thống) hiện có thể xem các vai trò được chỉ định cho người dùng khác.
Điều kiện tiên quyết
- Bạn phải là quản trị viên hệ thống đám mây riêng tư của Apigee và có quản trị viên hệ thống chung thông tin xác thực để thực hiện cấu hình này.
-
Bạn cần biết thư mục gốc của quá trình cài đặt dịch vụ đám mây riêng tư Apigee Edge. Chiến lược phát hành đĩa đơn thư mục gốc mặc định là /opt.
Ví dụ về cách thiết lập từng bước
Xem bài viết này trên Diễn đàn cộng đồng Apigee để tham khảo ví dụ từng bước về cách thiết lập ánh xạ vai trò.
Cấu hình mặc định
Tính năng ánh xạ vai trò bên ngoài bị tắt theo mặc định.
Bật tính năng ánh xạ vai trò bên ngoài
- Trước khi có thể hoàn tất cấu hình sau, bạn phải tạo một lớp Java
triển khai giao diện ExternalRoleMapperServiceV2 và đưa phương thức triển khai của bạn vào
Đường dẫn lớp máy chủ quản lý:
/opt/apigee/edge-management-server/lib/thirdparty/
Để biết chi tiết về quá trình triển khai này, hãy xem phần Giới thiệu về ExternalRoleMapperImpl triển khai mẫu ở phần sau của tài liệu này. - Đăng nhập vào máy chủ quản lý Apigee Edge rồi dừng máy chủ quản lý
quy trình:
> /opt/apigee/apigee-service/bin/apigee-service ngừng máy chủ quản lý cạnh - Mở /opt/apigee/customer/application/management-server.properties trong trình chỉnh sửa văn bản. Nếu tệp này không tồn tại, hãy tạo tệp.
- Hãy chỉnh sửa tệp thuộc tính để thực hiện các chế độ cài đặt sau:
# Cửa hàng người dùng được sử dụng cho xác thực.
# Sử dụng lệnh "externalized.authentication" cho cửa hàng người dùng LDAP.
# Xin lưu ý rằng để uỷ quyền, chúng tôi tiếp tục sử dụng LDAP.
# Xem thêm về Bật tính năng xác thực bên ngoài về cách bật xác thực bên ngoài.
conf_security_authentication.user.store=externalized.authentication
#Bật trình liên kết vai trò uỷ quyền bên ngoài.
conf_security_externalized.authentication.role.mapper.enabled=true conf_security_externalized.authentication.role.mapper.implementation.class=com.customer.authorization.impl.ExternalRoleMapperImpl
Lưu ý quan trọng: lớp triển khai và tên gói được tham chiếu trong cấu hình ở trên (ExternalRoleMapperImpl) chỉ là một ví dụ -- đây là một lớp bạn phải triển khai và bạn có thể đặt tên cho lớp và gói bất kỳ thứ gì mình muốn. Để biết chi tiết về cách triển khai lớp học, hãy xem phần Giới thiệu về Lớp triển khai mẫu ExternalVaiMapperImpl bên dưới. Đây là một lớp học mà bạn phải triển khai để phản ánh các nhóm của chính mình. - Lưu tệp management-server.properties.
- Đảm bảo rằng management-server.properties thuộc sở hữu của
người dùng apigee:?
> chown apigee:apigee /opt/apigee/customer/application/management-server.properties - Khởi động máy chủ quản lý:
> /opt/apigee/apigee-service/bin/apigee-service bắt đầu máy chủ quản lý cạnh
Tắt tính năng uỷ quyền bên ngoài
Để tắt cho phép bên ngoài, hãy làm như sau:
- Mở /opt/apigee/customer/application/management-server.properties trong trình chỉnh sửa văn bản. Nếu tệp không tồn tại, hãy tạo tệp đó.
- Thay đổi kho lưu trữ xác thực của người dùng thành ldap:
conf_security_authentication.user.store=ldap - Đặt thuộc tính này thành false:
conf_security_externalized.authentication.role.mapper.enabled=false - Khởi động lại máy chủ quản lý:
> /opt/apigee/apigee-service/bin/apigee-service bắt đầu máy chủ quản lý cạnh
Giới thiệu về ExternalRoleMapperImpl triển khai mẫu
Trong tệp cấu hình security.properties như được mô tả trước đó trong phần Bật tính năng liên kết vai trò bên ngoài, hãy lưu ý dòng sau:
externalized.authentication.role.mapper.implementation.class=com.customer.authorization.impl.ExternalRoleMapperImpl
Lớp này triển khai giao diện ExternalRoleMapperServiceV2 và bắt buộc. Bạn cần tạo cách triển khai lớp này để phản ánh các nhóm tương ứng của bạn. Khi hoàn tất, đặt lớp được biên dịch trong tệp JAR và đặt JAR đó trong đường dẫn lớp của Máy chủ quản lý:
/opt/apigee/edge-management-server/lib/thirdparty/
Bạn có thể đặt tên bất kỳ cho lớp và gói, miễn là lớp này triển khai ExternalRoleMapperServiceV2, có thể truy cập được trong classpath của bạn và được tham chiếu chính xác trong tệp cấu hình Management-server.properties.
Dưới đây, chúng tôi cung cấp một phương thức triển khai mẫu được nhận xét kỹ lưỡng về lớp 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(); } }