问题描述:如下图所示,Access Type显示出现异常
原因分析:
PrestoDB的日志输出调用逻辑
1 RangerBasedAccessControl.class
enum HiveAccessType { NONE, CREATE, ALTER, DROP, INDEX, LOCK, SELECT, UPDATE, USE, ALL, ADMIN } private boolean checkAccess(ConnectorIdentity identity, SchemaTableName tableName, String column, HiveAccessType accessType) { return rangerAuthorizer.authorizeHiveResource(tableName.getSchemaName(), tableName.getTableName(), column, accessType.toString(), identity.getUser(), getGroupsForUser(identity.getUser()), getRolesForUser(identity.getUser())); }
2 RangerAuthorizer.class
plugin.setResultProcessor(new RangerDefaultAuditHandler()); public boolean authorizeHiveResource(String database, String table, String column, String accessType, String user, Set<String> userGroups, Set<String> userRoles) { updateRangerPolicies(); RangerAccessResourceImpl resource = new RangerAccessResourceImpl(); if (!isNullOrEmpty(database)) { resource.setValue(KEY_DATABASE, database); } if (!isNullOrEmpty(table)) { resource.setValue(KEY_TABLE, table); } if (!isNullOrEmpty(column)) { resource.setValue(KEY_COLUMN, column); } RangerAccessRequest request = new RangerAccessRequestImpl(resource, accessType.toLowerCase(ENGLISH), user, userGroups, userRoles); RangerAccessResult result = plugin.isAccessAllowed(request); return result != null && result.getIsAllowed(); }
3 RangerBasePlugin.class
public RangerAccessResult isAccessAllowed(RangerAccessRequest request) { return isAccessAllowed(request, resultProcessor); }
上面是PrestoDB的ranger审计日志的输出逻辑,问题就出在RangerDefaultAuditHandler处,两个变量赋值错误。
ret.setAction(request.getAccessType());
ret.setAccessType(request.getAction());
ret.setRepositoryName(result.getServiceName()); ret.setRepositoryType(result.getServiceType()); ret.setResourceType(resourceType); ret.setResourcePath(resourcePath); ret.setRequestData(request.getRequestData()); ret.setEventTime(request.getAccessTime() != null ? request.getAccessTime() : new Date()); ret.setUser(request.getUser()); ret.setAction(request.getAccessType()); ret.setAccessResult((short) (result.getIsAllowed() ? 1 : 0)); ret.setPolicyId(result.getPolicyId()); ret.setAccessType(request.getAction()); ret.setClientIP(request.getClientIPAddress()); ret.setClientType(request.getClientType()); ret.setSessionId(request.getSessionId()); ret.setAclEnforcer(moduleName);
但在创建request的时候,RangerDefaultAuditHandler只set了access type
RangerDefaultAuditHandler.class
RangerAccessRequest request = new RangerAccessRequestImpl(resource, accessType.toLowerCase(ENGLISH), user, userGroups, userRoles);
RangerAccessRequestImpl.class
public RangerAccessRequestImpl(RangerAccessResource resource, String accessType, String user, Set<String> userGroups, Set<String> userRoles) { setResource(resource); setAccessType(accessType); setUser(user); setUserGroups(userGroups); setUserRoles(userRoles); setForwardedAddresses(null); // set remaining fields to default value setAccessTime(null); setRemoteIPAddress(null); setClientType(null); setAction(null); setRequestData(null); setSessionId(null); setContext(null); setClusterName(null); }
对比Hive(正常)
Hive对上述两个异常的值重新设置
RangerHiveAuditHandler.class
AuthzAuditEvent auditEvent = super.getAuthzEvents(result); auditEvent.setAccessType(accessType); auditEvent.setResourcePath(resourcePath); auditEvent.setResourceType("@" + resourceType); // to be consistent with earlier release String action = request.getAction(); if (hiveResource.getObjectType() == HiveObjectType.GLOBAL && isRoleOperation(action)) { auditEvent.setAccessType(action); }