如何使用werkzeug / bottle实现私有/公共apikey?

时间:2012-12-06 12:14:47

标签: python rest public-key-encryption bottle werkzeug

我正在开发一个带有Bottle的RESTful Web服务,可能很快就会迁移到Werkzeug。我想实现一个基于私钥/公钥对的auth方案,其中服务器只需要存储公共部分,而用户保留私有部分。在访问时,服务器将要求访问者使用服务器可以验证并与公钥部分相关的私钥来执行动作。一旦成功,例如生成可以使用一段时间的令牌。为Werkzeug或Bottle实现类似的东西的路径是什么?我可以使用的任何项目/示例吗?

1 个答案:

答案 0 :(得分:3)

我相信,这里最好的选择是将责任转移到加密技术上。 Web服务器和CA(证书颁发机构)都很好。

基本上,他们可以

  1. 确保连接安全
  2. 确保客户端使用由有效(例如,您的)CA
  3. 签名的证书
  4. 确保证书未被撤销
  5. 向您的应用程序提供您需要的唯一信息:远程方的标识符
  6. 我们使用这种机制来验证第三方支付服务(对不起,私有代码),并且还有一个plugin to Redmine提供相同的客户端授权机制,我们也使用它(当然,它是Ruby ,但它也是一个有效的证据,证明这些服务可以在野外找到。)

    为了让事情顺利进行,您只需要

    1. 配置您的CA。
    2. 配置您的网络服务器,以确保它接受您当局的证书,并且只接受这些证书,并将客户端ID进一步传递给您的应用。
    3. 确保您的应用程序可以从请求中提取客户端标识符。
    4. 以下是easyrsa,nginx,uWsgi和werkzeug的一个小例子

      配置CA

      easyrsa工具包是OpenVPN安装的一部分。可以使用OpenSSL“raw”命令或PyOpenSSL,但easyrsa至少在概念阶段是方便和合适的。

      cp -a /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/nginx/easyrsa
      cd /etc/nginx/easyrsa && source vars && ./clean-all
      

      创建CA

      ./build-ca
      

      创建服务器证书

      ./build-key --server server
      

      创建客户证书。

      ./build-key-pkcs12  client1
      

      在上面的示例中,您将同时创建客户端密钥及其对应的公共部分(证书),但良好实践假定您已签署客户端证书请求,并且无权访问秘密部分。

      有些服务会为您生成一对密钥+证书,然后在下载页面上写一条消息,例如“这是您下载密钥的唯一机会。我们不存储它,所以无法下载后“。

      此外,此命令还会创建一个带有加密密钥和证书的PKCS12文件,这对于导入浏览器非常方便。

      配置nginx

      首先,我们应该创建一对“服务器证书+ ca证书”,作为我们的CA自签名:

      cat keys/server.crt keys/ca.crt > keys/server_and_ca.crt
      

      然后可以应用以下配置:

      server {
          listen 443;
      
          location / {
              # Here we define the name and the contents of the WSGI variable to pass to service
              uwsgi_param SSL_CLIENT_ID $ssl_client_s_dn;
              include uwsgi_params;
              uwsgi_pass 127.0.0.1:5000;
          }
      
      
          # SSL support
          ssl                 on;
          ssl_protocols       SSLv3 TLSv1;
          ssl_certificate     easyrsa/keys/ca_and_server.crt;
          ssl_certificate_key easyrsa/keys/server.key;
      
          # We don't accept anyone without correct client certificate
          ssl_verify_client on;
          # The CA we use to verify client certificates
          ssl_client_certificate easyrsa/keys/ca.crt;
      }
      

      有关配置选项的更多信息,请herehere

      确保您对/ etc / nginx / easyrsa目录具有正确的权限,并且只有root和nginx才能访问密钥。

      撰写Werkzeug申请

      python部分很简单。只需从WSGI环境中读取变量SSL_CLIENT_ID。

      文件sample.py

      中示例应用程序的内容
      from werkzeug.wrappers import Response
      
      def application(environ, start_response):
          text = 'Hello, your certificate id is %s\n' % environ.get('SSL_CLIENT_ID', '(unknown)')
          response = Response(text, mimetype='text/plain')
          return response(environ, start_response)
      

      使用uwsgi服务器启动服务:uwsgi -w sample:application --socket 127.0.0.1:5000

      测试您的安装

      使用curl进行测试很容易

      $ curl --cert keys/client1.crt --key keys/client1.key --cacert keys/ca.crt https://localhost/
      Hello, your certificate id is /C=US/ST=CA/L=SanFrancisco/O=Fort-Funston/OU=changeme/CN=client1/name=changeme/emailAddress=mail@host.domain