跳到主要内容

ranger grant 授权

看impala的ranger插件代码, 才知道原来ranger还能这么玩. 支持create role, grant privilege权限,看起来跟mysql的grant语法一样, 背后其实自动转换调用ranger api创建policy.

不过还没实际去测试过.

jira Enhance ranger hive plugin to support sql role commands

在 2019 年这个jira issue里, 为ranger增加了role based authorization.

这是一个比较庞大的变更, 支持其他服务的角色授权直接通过ranger api转化为背后的授权.

Enhancements to support roles in Ranger policies

https://issues.apache.org/jira/browse/RANGER-2414

https://github.com/apache/ranger/commit/c2fdfbc09c29f41d3c02b27faef3c5f7e57ffbb2

Current Ranger policy model supports authorization/column-masking/row-filtering for users/user-groups based on various criteria like accessed-resource, resource-classifications, IP-address and custom conditions. Given the wide-spread use of role-based authorization in traditional enterprise applications (like RDBMS, J2EE), it will be very useful for Ranger policy model to support 'roles' i.e. to be able to specify authorization/column-masking/row-filtering for roles as well - in addition to existing support for users and user-groups.

https://issues.apache.org/jira/browse/RANGER-2425

As an extension to https://issues.apache.org/jira/browse/RANGER-2414, enhance ranger hive plugin to support sql role commands:

ranger grant 授权

 package org.apache.ranger.admin.client;

public class RangerAdminRESTClient extends AbstractRangerAdminClient {
private static final Logger LOG = LoggerFactory.getLogger(RangerAdminRESTClient.class);

@Override
public void grantAccess(final GrantRevokeRequest request) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerAdminRESTClient.grantAccess(" + request + ")");
}

ClientResponse response = null;
UserGroupInformation user = MiscUtil.getUGILoginUser();
boolean isSecureMode = isKerberosEnabled(user);

Map<String, String> queryParams = new HashMap<String, String>();
queryParams.put(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);

if (isSecureMode) {
PrivilegedAction<ClientResponse> action = new PrivilegedAction<ClientResponse>() {
public ClientResponse run() {
String relativeURL = RangerRESTUtils.REST_URL_SECURE_SERVICE_GRANT_ACCESS + serviceNameUrlParam;
ClientResponse clientResp = null;
try {
clientResp = restClient.post(relativeURL, queryParams, request);
} catch (Exception e) {
LOG.error("Failed to get response, Error is : "+e.getMessage());
}
return clientResp;
}
};
if (LOG.isDebugEnabled()) {
LOG.debug("grantAccess as user " + user);
}
response = user.doAs(action);
} else {
String relativeURL = RangerRESTUtils.REST_URL_SERVICE_GRANT_ACCESS + serviceNameUrlParam;
response = restClient.post(relativeURL, queryParams, request);
}
if(response != null && response.getStatus() != HttpServletResponse.SC_OK) {
RESTResponse resp = RESTResponse.fromClientResponse(response);
LOG.error("grantAccess() failed: HTTP status=" + response.getStatus() + ", message=" + resp.getMessage() + ", isSecure=" + isSecureMode + (isSecureMode ? (", user=" + user) : ""));

if(response.getStatus()==HttpServletResponse.SC_UNAUTHORIZED) {
throw new AccessControlException();
}

throw new Exception("HTTP " + response.getStatus() + " Error: " + resp.getMessage());
} else if(response == null) {
throw new Exception("unknown error during grantAccess. serviceName=" + serviceName);
}

if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerAdminRESTClient.grantAccess(" + request + ")");
}
}
}

ranger的grant request api参数


@JsonAutoDetect(getterVisibility=Visibility.NONE, setterVisibility=Visibility.NONE, fieldVisibility=Visibility.ANY)
@JsonSerialize(include=JsonSerialize.Inclusion.NON_EMPTY )
@JsonIgnoreProperties(ignoreUnknown=true)
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class GrantRevokeRequest implements Serializable {
private static final long serialVersionUID = 1L;

private String grantor;
private Set<String> grantorGroups;
private Map<String, String> resource;
private Set<String> users;
private Set<String> groups;
private Set<String> roles;
private Set<String> accessTypes;
private List<String> forwardedAddresses;
private String remoteIPAddress;
private Boolean delegateAdmin = Boolean.FALSE;
private Boolean enableAudit = Boolean.TRUE;
private Boolean replaceExistingPermissions = Boolean.FALSE;
private Boolean isRecursive = Boolean.FALSE;
private String clientIPAddress;
private String clientType;
private String requestData;
private String sessionId;
private String clusterName;
private String zoneName;
private String ownerUser;

ranger 创建角色

ranger role是后面才有的概念, 创建角色就跟创建用户/用户组一样, 可以调用api完成.

 package org.apache.ranger.admin.client;

public class RangerAdminRESTClient extends AbstractRangerAdminClient {


@Override
public RangerRole createRole(final RangerRole request) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerAdminRESTClient.createRole(" + request + ")");
}

RangerRole ret = null;

ClientResponse response = null;
UserGroupInformation user = MiscUtil.getUGILoginUser();
boolean isSecureMode = isKerberosEnabled(user);
String relativeURL = RangerRESTUtils.REST_URL_SERVICE_CREATE_ROLE;

Map <String, String> queryParams = new HashMap<String, String> ();
queryParams.put(RangerRESTUtils.SERVICE_NAME_PARAM, serviceNameUrlParam);

if (isSecureMode) {
PrivilegedAction<ClientResponse> action = new PrivilegedAction<ClientResponse>() {
public ClientResponse run() {
ClientResponse clientRes = null;
try {
clientRes = restClient.post(relativeURL, queryParams, request);
} catch (Exception e) {
LOG.error("Failed to get response, Error is : "+e.getMessage());
}
return clientRes;
}
};
if (LOG.isDebugEnabled()) {
LOG.debug("create role as user " + user);
}
response = user.doAs(action);
} else {
response = restClient.post(relativeURL, queryParams, request);
}

if(response != null && response.getStatus() != HttpServletResponse.SC_OK) {
RESTResponse resp = RESTResponse.fromClientResponse(response);
LOG.error("createRole() failed: HTTP status=" + response.getStatus() + ", message=" + resp.getMessage() + ", isSecure=" + isSecureMode + (isSecureMode ? (", user=" + user) : ""));

if(response.getStatus()==HttpServletResponse.SC_UNAUTHORIZED) {
throw new AccessControlException();
}

throw new Exception("HTTP " + response.getStatus() + " Error: " + resp.getMessage());
} else if(response == null) {
throw new Exception("unknown error during createRole. roleName=" + request.getName());
} else {
ret = response.getEntity(RangerRole.class);
}

if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerAdminRESTClient.createRole(" + request + ")");
}
return ret;
}

}

ranger 授权角色权限

ranger 授权角色权限, 其实就是ranger plugin调用ranger admin的 api 创建 policy, 给 role 赋予权限.


package org.apache.ranger.admin.client;

public class RangerAdminRESTClient extends AbstractRangerAdminClient {

@Override
public void grantRole(final GrantRevokeRoleRequest request) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerAdminRESTClient.grantRole(" + request + ")");
}

ClientResponse response = null;
UserGroupInformation user = MiscUtil.getUGILoginUser();
boolean isSecureMode = isKerberosEnabled(user);
String relativeURL = RangerRESTUtils.REST_URL_SERVICE_GRANT_ROLE + serviceNameUrlParam;

if (isSecureMode) {
PrivilegedAction<ClientResponse> action = new PrivilegedAction<ClientResponse>() {
public ClientResponse run() {
ClientResponse clientResp = null;
try {
clientResp = restClient.put(relativeURL, null, request);
} catch (Exception e) {
LOG.error("Failed to get response, Error is : "+e.getMessage());
}
return clientResp;
}
};
if (LOG.isDebugEnabled()) {
LOG.debug("grant role as user " + user);
}
response = user.doAs(action);
} else {
response = restClient.put(relativeURL, null, request);
}
if(response != null && response.getStatus() != HttpServletResponse.SC_OK) {
RESTResponse resp = RESTResponse.fromClientResponse(response);
LOG.error("grantRole() failed: HTTP status=" + response.getStatus() + ", message=" + resp.getMessage() + ", isSecure=" + isSecureMode + (isSecureMode ? (", user=" + user) : ""));

if(response.getStatus()==HttpServletResponse.SC_UNAUTHORIZED) {
throw new AccessControlException();
}

throw new Exception("HTTP " + response.getStatus() + " Error: " + resp.getMessage());
} else if(response == null) {
throw new Exception("unknown error during grantRole. serviceName=" + serviceName);
}

if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerAdminRESTClient.grantRole(" + request + ")");
}
}
}