Ranger Plugin对应的服务进程在启动时会启动PolicyRefresher线程,在后台动态刷新策略,刷新策略就是下载最新策略的过程,这个过程涉及到Restful api请求Ranger服务端,请求过程代码如下所示:
RangerAdminRESTClient.getServicePoliciesIfUpdated // 根据service_name获取最新的policies
如果policy.rest.client.cookie.enabled参数(默认值为true),且policyDownloadSessionId不为空,且isValidPolicyDownloadSessionCookie为true
RangerAdminRESTClient.getServicePoliciesIfUpdatedWithCookie
RangerAdminRESTClient.getRangerAdminPolicyDownloadResponse
做一些cookie和session的检查和重置工作,以及设置policyDownloadSessionId和isValidPolicyDownloadSessionCookie
如若不满足条件
RangerAdminRESTClient.getServicePoliciesIfUpdatedWithCred
user = MiscUtil.getUGILoginUser(); // 获取ugi
isSecureMode // 根据ugi判断是否安全模式
RangerAdminRESTClient.getRangerAdminPolicyDownloadResponse //下载策略
组装queryParams对象,表示查询条件
如果isSecureMode为true // 安全模式,例如kerberos认证
通过user.doAs发起restful api请求
relativeURL为/service/plugins/secure/policies/download/{serviceName}
如果isSecureMode为false // 非安全模式,例如simple认证
直接发起restful api请求
relativeURL为/service/plugins/policies/download/{serviceName}
如果请求结果不为空,且响应码不是NOT_MODIFIED、NO_CONTENT、OK、NOT_FOUND
LOG.warn("Error getting policies. secureMode=" + isSecureMode + ", user=" + user + ", response=" + resp + ", serviceName=" + serviceName);
发送restful api请求后,请求就到了Ranger Admin服务端,接口定义在ServiceREST类中,服务端处理逻辑如下所示:
ServiceREST.getSecureServicePoliciesIfUpdated // 处理/secure/policies/download/{serviceName}请求
isValid = ServiceUtil.isValidService //判断请求是否有效
如果serviceName为空
LOG.error("ServiceName not provided");
抛异常Unauthorized access
如果请求中带有downloadPolicy属性,且值为secure
service = ServiceDBStore.getServiceByNameForDP(serviceName);//查询service
daoMgr.getXXService().findByName //直接数据库查询返回
如若不然
service = ServiceDBStore.getServiceByName(serviceName);//查询service
xService = daoMgr.getXXService().findByName //数据库查询
如果ContextUtil.getCurrentUserSession()不为空
如果bizUtil.hasAccess(xService, null)为false
抛异常Logged in user is not allowed to read service
return xService
如果isValid为true,表示有效
rangerService = svcStore.getServiceByName
判断请求用户是否在policy.download.auth.users和policy.grantrevoke.auth.users列表中,记为isAllowed
如果isAllowed为true
svcStore.getServicePoliciesIfUpdated //查询数据库,获取策略列表
如果isAllowed为false
服务端打印日志failed as User doesn't have permission to download Policy
SC_UNAUTHORIZED响应返回
如果isValid为false,表示无效,则抛异常WebApplicationException
ServiceREST.getServicePoliciesIfUpdated // 处理/policies/download/{serviceName}请求
在secure请求处理过程中,多了对policy.download.auth.users和policy.grantrevoke.auth.users两个参数值的判断,容易引发401错误。
还有一种易于引发401错误的场景。
RangerAuthenticationEntryPoint作为http请求的filter,当请求报文的header中包含X-Requested-With,且值不为XMLHttpRequest时,就会返回401响应,源码如下所示:
VXResponse vXResponse = new VXResponse();
vXResponse.setStatusCode(HttpServletResponse.SC_UNAUTHORIZED);
vXResponse.setMsgDesc("Authentication Failed");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write(jsonUtil.writeObjectAsString(vXResponse));
例如下图所示:
kerberos环境下,请求secure接口,就出现了上述场景。