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 设置您自己的名称。