Ranger Client策略下载过程


发布于 2024-03-28 / 87 阅读 / 0 评论 /
Ranger对策略下载请求发送和处理过程源码解析

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接口,就出现了上述场景。