c调用java的grpc_拦截服务器和客户端中的gRPC C调用

本文介绍了如何在gRPC C调用Java服务中实现认证拦截器。通过子类化AuthMetadataProcessor,重写Process方法,检查请求的元数据,验证令牌的可用性和有效性。示例代码展示了如何处理不同方法的拦截,并在安全服务中设置AuthMetadataProcessor。
摘要由CSDN通过智能技术生成

是.您需要子类化AuthMetadataProcessor,重写其Process方法并使用您的服务注册派生类型的实例.完成后,Process将拦截所有方法调用,并为其提供随请求一起发送的客户端元数据.

您对Process的实现必须决定是否需要对截获的方法进行身份验证(即,您的Authenticate方法不需要进行身份验证,但后续调用的方法将需要进行身份验证).这可以通过检查:路径元数据键来完成,如问题#9211中所述,这是一个指定截获方法的可信值.

您的Process实现必须决定令牌是否在请求中提供并且是否有效.这是一个实现细节,但通常Process指的是Authenticate生成的有效令牌存储.这可能就是你已经在Java中设置的方式了.

遗憾的是,无法在不安全的凭据之上注册AuthMetadataProcessor,这意味着您必须使用SSL,否则尝试以不同方式拦截方法.

该框架还提供了便利功能,允许您使用对等标识属性.进程可以在身份验证上下文中调用AddProperty,提供令牌隐含的标识,然后是SetPeerIdentityPropertyName.然后,调用的方法可以使用GetPeerIdentity访问信息,并避免将标记重新映射到标识.

AuthMetadataProcessor实现示例

struct Const

{

static const std::string& TokenKeyName() { static std::string _("token"); return _; }

static const std::string& PeerIdentityPropertyName() { static std::string _("username"); return _; }

};

class MyServiceAuthProcessor : public grpc::AuthMetadataProcessor

{

public:

grpc::Status Process(const InputMetadata& auth_metadata, grpc::AuthContext* context, OutputMetadata* consumed_auth_metadata, OutputMetadata* response_metadata) override

{

// determine intercepted method

std::string dispatch_keyname = ":path";

auto dispatch_kv = auth_metadata.find(dispatch_keyname);

if (dispatch_kv == auth_metadata.end())

return grpc::Status(grpc::StatusCode::INTERNAL, "Internal Error");

// if token metadata not necessary, return early, avoid token checking

auto dispatch_value = std::string(dispatch_kv->second.data());

if (dispatch_value == "/MyPackage.MyService/Authenticate")

return grpc::Status::OK;

// determine availability of token metadata

auto token_kv = auth_metadata.find(Const::TokenKeyName());

if (token_kv == auth_metadata.end())

return grpc::Status(grpc::StatusCode::UNAUTHENTICATED, "Missing Token");

// determine validity of token metadata

auto token_value = std::string(token_kv->second.data());

if (tokens.count(token_value) == 0)

return grpc::Status(grpc::StatusCode::UNAUTHENTICATED, "Invalid Token");

// once verified, mark as consumed and store user for later retrieval

consumed_auth_metadata->insert(std::make_pair(Const::TokenKeyName(), token_value)); // required

context->AddProperty(Const::PeerIdentityPropertyName(), tokens[token_value]); // optional

context->SetPeerIdentityPropertyName(Const::PeerIdentityPropertyName()); // optional

return grpc::Status::OK;

}

std::map<:string std::string> tokens;

};

安全服务中的AuthMetadataProcessor设置

class MyServiceImplSecure : public MyPackage::MyService::Service

{

public:

MyServiceImplSecure(std::string _server_priv, std::string _server_cert, std::string _ca_cert) :

server_priv(_server_priv), server_cert(_server_cert), ca_cert(_ca_cert) {}

std::shared_ptr<:servercredentials> GetServerCredentials()

{

grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp;

pkcp.private_key = server_priv;

pkcp.cert_chain = server_cert;

grpc::SslServerCredentialsOptions ssl_opts;

ssl_opts.pem_key_cert_pairs.push_back(pkcp);

ssl_opts.pem_root_certs = ca_cert;

std::shared_ptr<:servercredentials> creds = grpc::SslServerCredentials(ssl_opts);

creds->SetAuthMetadataProcessor(auth_processor);

return creds;

}

void GetContextUserMapping(::grpc::ServerContext* context, std::string& username)

{

username = context->auth_context()->GetPeerIdentity()[0].data();

}

private:

std::string server_priv;

std::string server_cert;

std::string ca_cert;

std::shared_ptr auth_processor =

std::shared_ptr(new MyServiceAuthProcessor());

};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值