在grpc服务器端调用SSL证书

时间:2017-03-10 12:56:23

标签: c++ ssl grpc

我有一个gRPC客户端/服务器组合,它使用SSLCredentials方法加密通信。 我试图在服务器上检索客户端的SSL证书' side(用C ++编写)所以我可以区分调用服务器的不同客户端。

到目前为止,我只能找到似乎大致相同的an example for Go,但在C ++方面,我只能找到仅提供以下信息的AuthMetadataProcessor overloading ,这不是我需要的。

:authority  =  localhost:50051
:path  =  /API.GameDatabase/saveData
grpc-accept-encoding  =  identity,deflate,gzip
grpc-encoding  =  identity
user-agent  =  grpc-csharp/1.0.1 grpc-c/1.0.1 (linux; chttp2)
Dispatch value:  "/API.GameDatabase/saveData"

这是可能的还是我必须自己发送这种元数据?

2 个答案:

答案 0 :(得分:0)

如果您决定使用此类拦截器从服务器的业务逻辑中分解出身份验证/授权逻辑,则可以使用AuthContext从ServerContext或AuthMetadataProcessor中的响应处理程序中检索客户端的SSL证书。 。 http://www.grpc.io/grpc/cpp/classgrpc_1_1_auth_context.html

如果存在,则将X509的对等标识属性设置为SAN,否则设置为CN。但是,您可以使用以下权限访问完整证书 http://www.grpc.io/grpc/core/grpc__security__constants_8h.html#ad46c3fd565d6a24eeb25d1fdc342cb28 在AuthContext中填充的属性。

答案 1 :(得分:0)

在朱利安答案的帮助下,我能够让它发挥作用,我接受了他的答案,但在下面给出了一个代码示例:

grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp =
{"<key>", "<cert>"};

// The client must be force to present a cert every time a call is made,
// else it will only happen once when the first connection is made.
// The other options can be found here:
// http://www.grpc.io/grpc/core/grpc__security__constants_8h.html#a29ffe63a8bb3b4945ecab42d82758f09
grpc::SslServerCredentialsOptions 
ssl_opts(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);

ssl_opts.pem_root_certs = "<CA cert>";
ssl_opts.pem_key_cert_pairs.push_back(pkcp);

std::shared_ptr<grpc::ServerCredentials> sslCredentials = 
grpc::SslServerCredentials(ssl_opts);

builder.AddListeningPort("<server address>", sslCredentials);

有两种方法可以检索ssl证书:

  1. Subclass AuthMetaDataProcessor(refer to this post for more info),这样您每次拨打电话时都可以在中心位置获取ssl证书:

    std::shared_ptr<AuthMetaDataProcessor> auth_processor = 
    std::make_shared<AuthMetaDataProcessor>();
    
    // Add the meta data processor to the ssl credentials before building the server
    sslCredentials->SetAuthMetadataProcessor(auth_processor);
    

    然后在重写过程函数中:

    grpc::Status Process(const InputMetadata& auth_metadata,
        grpc::AuthContext* context,
        OutputMetadata* consumed_auth_metadata,
        OutputMetadata* response_metadata) override 
    {
        std::string cert = context->FindPropertyValues("x509_pem_cert").front().data();
    
        return grpc::Status::OK;
    }
    
  2. 从每次调用提供的ServerContext中获取它

    std::string cert = context->auth_context()->FindPropertyValues("x509_pem_cert").front().data();
    
  3. 我希望这会有所帮助。