CKAN - 使用 API 与 curl 和 Apache 基本身份验证
CKAN - use API with curl and Apache basic authentication
我使用 curl 在 Ckan 中创建资源,一切正常:
curl -H'Authorization: zzzzzz-zzzzz-zzzzz-zzzzz-zzzzzz' 'https://ckan.site.com/api/action/resource_create' --form upload=@/home/file.csv --form package_id=test-upload-file --form url='' --form name='test 12' --form format='csv'
但是,如果 Ckan 在具有 basic-auth 的 Apache Web 服务器上(因此,当我尝试登录到 Web 界面时,会出现一个询问用户名和密码的弹出窗口)curl 停止工作。我向 curl 命令添加 -u 选项以将用户名和密码传递给 Web 服务器,但我总是从 Apache 收到 "Unauthorized" 答复;我还尝试使用 http://username:password@ckan.site.com 或 -n 和 .netrc 文件传递用户名和密码,但我没有成功。
我怀疑 Apache 搞乱了 "Authorization" header:一个是通过 curl 和 -H 选项传递的,另一个是因为 Apache 中配置了基本身份验证(documentation here ) ...也许他们混淆了?
如果我尝试简单 curl -n https://ckan.site.com/
我可以下载 Ckan 主页。
这是 Apache 基本身份验证配置:
<Location />
AuthType Basic
AuthName "ckan login"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Location>
这是我在 Apache 日志中看到的 auth_basic 错误:
client used wrong authentication scheme: /api/action/resource_create
HTTP Basic Auth 与许多其他 HTTP 身份验证方案一样,使用 Authorization
header 将凭据从客户端传递到服务器。这与 CKAN 使用 Authorization
header 传递 API 键的要求相冲突。
当您在 curl 中手动设置 Authorization
header 时,您会覆盖将为基本身份验证设置的值。您可以自己测试,例如使用 netcat
。这是 curl 为基本身份验证生成的 GET
请求:
curl 'http://user:pass@localhost:8080'
来自 netcat -l 8080
的输出:
GET / HTTP/1.1
Host: localhost:8080
Authorization: Basic dXNlcjpwYXNz
User-Agent: curl/7.58.0
Accept: */*
如您所见,curl 已使用用户 user
和密码 pass
.
的编码凭据填充 Authorization
header
现在让我们尝试相同的操作,并手动为 Authorization
指定一个值:
curl -H'Authorization: Foo' 'http://user:pass@localhost:8080'
来自 netcat
的输出:
GET / HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.58.0
Accept: */*
Authorization: Foo
我们的自定义值已覆盖基本身份验证的值。 Apache 现在会将 Foo
(或者,在您的情况下,您的 API 密钥)解释为 HTTP 身份验证方案的名称(如之前的 Basic
)——因为它不适合您用于保护 URL Apache 的方案引发了您看到的错误 (client used wrong authentication scheme
)。
为避免此问题,CKAN 还接受 X-CKAN-API-Key
header 中的 API 键。您甚至可以使用 CKAN 的 api_key_header_name
配置选项为 header 设置您自己的名称。
我使用 curl 在 Ckan 中创建资源,一切正常:
curl -H'Authorization: zzzzzz-zzzzz-zzzzz-zzzzz-zzzzzz' 'https://ckan.site.com/api/action/resource_create' --form upload=@/home/file.csv --form package_id=test-upload-file --form url='' --form name='test 12' --form format='csv'
但是,如果 Ckan 在具有 basic-auth 的 Apache Web 服务器上(因此,当我尝试登录到 Web 界面时,会出现一个询问用户名和密码的弹出窗口)curl 停止工作。我向 curl 命令添加 -u 选项以将用户名和密码传递给 Web 服务器,但我总是从 Apache 收到 "Unauthorized" 答复;我还尝试使用 http://username:password@ckan.site.com 或 -n 和 .netrc 文件传递用户名和密码,但我没有成功。
我怀疑 Apache 搞乱了 "Authorization" header:一个是通过 curl 和 -H 选项传递的,另一个是因为 Apache 中配置了基本身份验证(documentation here ) ...也许他们混淆了?
如果我尝试简单 curl -n https://ckan.site.com/
我可以下载 Ckan 主页。
这是 Apache 基本身份验证配置:
<Location />
AuthType Basic
AuthName "ckan login"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Location>
这是我在 Apache 日志中看到的 auth_basic 错误:
client used wrong authentication scheme: /api/action/resource_create
HTTP Basic Auth 与许多其他 HTTP 身份验证方案一样,使用 Authorization
header 将凭据从客户端传递到服务器。这与 CKAN 使用 Authorization
header 传递 API 键的要求相冲突。
当您在 curl 中手动设置 Authorization
header 时,您会覆盖将为基本身份验证设置的值。您可以自己测试,例如使用 netcat
。这是 curl 为基本身份验证生成的 GET
请求:
curl 'http://user:pass@localhost:8080'
来自 netcat -l 8080
的输出:
GET / HTTP/1.1
Host: localhost:8080
Authorization: Basic dXNlcjpwYXNz
User-Agent: curl/7.58.0
Accept: */*
如您所见,curl 已使用用户 user
和密码 pass
.
Authorization
header
现在让我们尝试相同的操作,并手动为 Authorization
指定一个值:
curl -H'Authorization: Foo' 'http://user:pass@localhost:8080'
来自 netcat
的输出:
GET / HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.58.0
Accept: */*
Authorization: Foo
我们的自定义值已覆盖基本身份验证的值。 Apache 现在会将 Foo
(或者,在您的情况下,您的 API 密钥)解释为 HTTP 身份验证方案的名称(如之前的 Basic
)——因为它不适合您用于保护 URL Apache 的方案引发了您看到的错误 (client used wrong authentication scheme
)。
为避免此问题,CKAN 还接受 X-CKAN-API-Key
header 中的 API 键。您甚至可以使用 CKAN 的 api_key_header_name
配置选项为 header 设置您自己的名称。