curl访问Kerberos认证WebHDFS报401 Authentication required错误
WebHDFS Kerberos认证401故障排查
问题现象
已完成Hadoop集群Kerberos认证服务部署配置,使用curl调用WebHDFS接口访问HDFS存储文件时认证失败。本地Kerberos票据缓存中存在有效合法票据,票据对应账号对目标路径/user/hadoop/file1拥有读写权限,执行访问命令后返回HTTP/1.1 401 Authentication required错误。
执行命令与响应如下:
hadoop@hadoop-name:~$ curl -i --negotiate -u:anyUser -L "http://hadoop-name:9870/webhdfs/v1/user/hadoop/file1?op=OPEN" HTTP/1.1 401 Authentication required Pragma: no-cache X-Content-Type-Options: nosniff X-FRAME-OPTIONS: SAMEORIGIN X-XSS-Protection: 1; mode=block WWW-Authenticate: Negotiate Set-Cookie: hadoop.auth=; Path=/; Domain=HADOOP.LOCAL; HttpOnly Cache-Control: must-revalidate,no-cache,no-store Content-Type: text/html;charset=iso-8859-1 Content-Length: 482 <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> <title>Error 401 Authentication required</title> </head> <body><h2>HTTP ERROR 401 Authentication required</h2> <table> <tr><th>URI:</th><td>/webhdfs/v1/user/hadoop/file1</td></tr> <tr><th>STATUS:</th><td>401</td></tr> <tr><th>MESSAGE:</th><td>Authentication required</td></tr> <tr><th>SERVLET:</th><td>com.sun.jersey.spi.container.servlet.ServletContainer-4c6daf0</td></tr> </table> </body> </html>
常见故障原因
- 安装的curl版本未编译GSS-API/SPNEGO模块,
--negotiate参数未实际生效,无法发起Kerberos协商请求 - 请求使用的主机名与Kerberos中注册的HTTP服务SPN不匹配,curl无法获取对应服务的认证令牌
- curl命令缺少凭证委托参数,跟随WebHDFS 307重定向到DataNode时未携带认证信息
- Hadoop集群侧HTTP Kerberos配置错误,keytab文件无效或加载失败
- 本地Kerberos票据缓存权限不足,curl进程无法读取有效票据
排查解决步骤
- 验证curl的Kerberos支持能力
执行curl --version,检查输出的特性列表中是否包含GSS-API、SPNEGO标识。如果没有相关标识,说明当前curl未启用Kerberos协商能力,需要重新编译安装带GSSAPI支持的curl版本,否则--negotiate参数不会生效。 - 校验SPN与请求主机名匹配性
首先执行klist确认本地缓存的客户端票据有效,再执行kvno HTTP/<请求使用的主机名>@HADOOP.LOCAL测试能否获取对应HTTP服务的票据。如果获取失败,说明请求主机名和KDC中注册的SPN不匹配:需要将curl请求中的主机名替换为SPN对应的完整域名(通常是带域名后缀的FQDN),保证请求地址的主机名部分和SPN中HTTP/后面的主机名完全一致,同时确认DNS或/etc/hosts中该主机名映射正确。 - 修正curl命令参数
原命令存在两个问题:一是未开启Kerberos凭证委托,跟随重定向时不会携带认证信息;二是-u:anyUser的写法可能导致用户信息解析异常。调整后的测试命令如下,增加-v参数输出完整协商日志方便定位:
正常Kerberos协商流程中,第一次请求会收到401响应,curl会自动在第二次请求中添加curl -v --negotiate -u : --delegation always "http://<替换为正确的FQDN主机名>:9870/webhdfs/v1/user/hadoop/file1?op=OPEN"Authorization: Negotiate <加密令牌>请求头。如果开启verbose日志后看不到该请求头,说明curl侧Kerberos协商未触发,回头检查curl支持能力、票据可读性、SPN匹配性。 - 校验Hadoop集群侧配置
登录NameNode节点检查core-site.xml中以下配置项:hadoop.http.authentication.type需设置为kerberoshadoop.http.authentication.kerberos.principal需设置为HTTP/_HOST@HADOOP.LOCAL,_HOST会自动替换为当前节点的主机名hadoop.http.authentication.kerberos.keytab指向的keytab文件存在,且NameNode启动用户对其有读权限,可执行kinit -kt <keytab路径> HTTP/<当前节点FQDN>@HADOOP.LOCAL验证keytab有效性
同时检查NameNode启动日志,排查是否存在keytab加载失败、Kerberos主体无效类的报错。
- 检查票据缓存权限
执行echo $KRB5CCNAME查看当前票据缓存路径,确认执行curl的用户对该缓存文件有读权限,避免因权限不足导致curl无法读取票据发起认证。
内容的提问来源于stack exchange,提问作者JG97
相关产品推荐
相关产品推荐

