認證

本文預覽一下gRPC認證,包含內置已支持的認證機制,如何添加自己的認證系統(tǒng)和如何在支持的語言里使用gRPC認證的例子。

簡介

gRPC設計可以和很多認證機制工作狞尔,可以很簡單安全的使用gRPC與其他系統(tǒng)溝通」簦可以使用我們已支持的機制 - SSL/TLS使用或者不適用Google基于token認證 - 或者可以添加你自己的認證系統(tǒng)通過擴展我們提供的代碼偏序。

gRPC同樣提供了簡單的認證API,讓你提供所有需要的認證信息作為憑證(Credentials)在創(chuàng)建channel或者請求時胖替。

已支持的認證機制

下面的認證機制是gRPC內置的:

  • SSL/TLS: gRPC繼承了SSL/TLS研儒,并且提升了SSL/TLS認證服務器的使用豫缨,加密所有客戶端和服務端的數據交換。為客戶端提供相互認證的證書機制是可選的端朵。

  • 基于Google的Token認證:gRPC提供了通用的機制(下面介紹)對請求和響應附加metadata好芭。另外支持使用tokens(一般是OAuth2 tokens)在通過gRPC使用Google API提供確認的認證流程:可以在下面代碼例子里查看如何使用舍败。一般這種機制必須是SSL/TLS的 - 沒有SSL/TLS Google不允許連接,并且大多數gRPC語言實現不會讓你在未加密的渠道上發(fā)送認證敬拓。

警告:谷歌認證只允許用于谷歌服務。如果發(fā)送一個谷歌的OAuth2 token到非谷歌服務會導致這個token被竊取然后濫用谷歌的服務乘凸。

認證API

gRPC提供了簡單的認證API,基于統(tǒng)一認證對象的概念营勤,可以用在創(chuàng)建整個gRPC管道或單個調用的時候。

憑證類型

兩種憑證類型:

  • Channel憑證冀偶,當訪問到Channel時,比如SSL憑證渔嚷。
  • Call憑證进鸠,當觸發(fā)一個調用時(或者C++里的ClientContext)。

也可以在CompositeChannelCredentials組合使用形病,允許你指定客年,比如SSL 憑證給channel,然后這個channel上的每個請求用call憑證漠吻。CompositeChannelCredentials結合ChannelCredentialsCallCredentials來創(chuàng)建一個新的ChannelCredentials量瓜。結果發(fā)送認證數據與channel上的每個請求CallCredentialswith組合。

比如途乃,你可以創(chuàng)建SslCredentials的ChannelCredentialsAccessTokenCredentials绍傲。結果就是在Channel上使用時將會為Channel上的每個請求發(fā)送合適的認證token。

單個CallCredentials同樣可以與CompositeCallCredentials組合耍共。這會當CallCredentials使用在請求上是將會觸發(fā)發(fā)送認證數據和兩個CallCredentials烫饼。

使用客戶端SSL/TLS

現在我們看一下Credentials如何與我們支持的認證機制合作。這是最簡單的認證場景:客戶端指向認證服務器并加密所有的數據试读。例子是用C++杠纵,但是API對所有的語言都相同:你可以在我們下面的例子里看到很多語言里如何啟用SSL/TLS:

// Create a default SSL ChannelCredentials object.
auto channel_creds = grpc::SslCredentials(grpc::SslCredentialsOptions());
// Create a channel using the credentials created in the previous step.
auto channel = grpc::CreateChannel(server_name, channel_creds);
// Create a stub on the channel.
std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
// Make actual RPC calls on the stub.
grpc::Status s = stub->sayHello(&context, *request, response);

對于更高級的案例,比如修改根CA或者使用客戶端證書钩骇,相應的選項可以在SslCredentialsOptions參數里設置傳遞給工廠方法比藻。

基于谷歌token認證

gRPC應用可以使用簡單的API創(chuàng)建認證铝量,用于和Google各種開發(fā)場景認證。同樣银亲,我們的例子是C++慢叨,但是你可以找到其他語言的例子:

auto creds = grpc::GoogleDefaultCredentials();
// Create a channel, stub and make RPC calls (same as in the previous example)
auto channel = grpc::CreateChannel(server_name, creds);
std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
grpc::Status s = stub->sayHello(&context, *request, response);

這個channel認證對象用于使用Service Accounts的應用,以及運行在Google Compute Engine (GCE)的應用.
在前一種情況下群凶,服務賬戶的私鑰會被環(huán)境變量里的GOOGLE_APPLICATION_CREDENTIALS文件加載插爹。密鑰用于生成無記名令牌附加到每個發(fā)送的RPC在相應的channel。

對于運行在GCE里的應用程序请梢,默認的服務賬戶和相應的OAuth2域可以在VM設置期間配置赠尾。在運行時,這個憑證處理和認證系統(tǒng)通信獲取OAuth2訪問tokens毅弧,然后加在相應的channel里的發(fā)送的RPC气嫁。

擴展gRPC支持其他認證機制

認證插件API允許開發(fā)者加入自己的認證類型。這包括:

  • MetadataCredentialsPlugin抽象類够坐,包含純凈的虛擬GetMetadata方法寸宵,需要被開發(fā)者創(chuàng)建的子類實現。
  • MetadataCredentialsFromPlugin方法,在MetadataCredentialsPlugin插件里創(chuàng)建一個CallCredentials元咙。

下面是一個簡單認證插件例子梯影,在自定義header里設置憑證ticket:

class MyCustomAuthenticator : public grpc::MetadataCredentialsPlugin {
 public:
  MyCustomAuthenticator(const grpc::string& ticket) : ticket_(ticket) {}

  grpc::Status GetMetadata(
      grpc::string_ref service_url, grpc::string_ref method_name,
      const grpc::AuthContext& channel_auth_context,
      std::multimap<grpc::string, grpc::string>* metadata) override {
    metadata->insert(std::make_pair("x-custom-auth-ticket", ticket_));
    return grpc::Status::OK;
  }

 private:
  grpc::string ticket_;
};

auto call_creds = grpc::MetadataCredentialsFromPlugin(
    std::unique_ptr<grpc::MetadataCredentialsPlugin>(
        new MyCustomAuthenticator("super-secret-ticket")));

更深層次的插件集成實現gRPC憑證實現是在源代碼等級。gRPC內部同樣可以與其他加密實現交換SSL/TLS庶香。

示例

這些認證機制可以在gRPC支持的所有語言里可用甲棍。下面會演示如何認證和在每個語言里上面講述的認證特性:更多語言準備中赶掖。

Java

基礎案例 - 無需加密或認證

ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
    .usePlaintext(true)
    .build();
GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel);

使用服務端認證SSL/TLS
如果gRPC是TLS的奢赂,我們建議在Java里使用OpenSSL≡凼浚可以在Security文檔里查看如何安裝和使用OpenSSL和其他必須的庫轧钓。

在服務端啟用TLS,證書鏈和密鑰需要制定為PEM格式脂矫。標準的TLS端口是443庭再,但是下面我們使用8443,以免需要系統(tǒng)的額外權限拄轻。

Server server = ServerBuilder.forPort(8443)
    // Enable TLS
    .useTransportSecurity(certChainFile, privateKeyFile)
    .addService(TestServiceGrpc.bindService(serviceImplementation))
    .build();
server.start();

如果客戶端不知道發(fā)行證書機構恨搓,那么正確的配置SslContext或者SSLSocketFactory應該提供給NettyChannelBuilder或者OkHttpChannelBuilder

在客戶端常拓,服務端的SSL/TLS認證看起來像:

// With server authentication SSL/TLS
ManagedChannel channel = ManagedChannelBuilder.forAddress("myservice.example.com", 443)
    .build();
GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel);

// With server authentication SSL/TLS; custom CA root certificates; not on Android
ManagedChannel channel = NettyChannelBuilder.forAddress("myservice.example.com", 443)
    .sslContext(GrpcSslContexts.forClient().trustManager(new File("roots.pem")).build())
    .build();
GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel);
谷歌認證

下面的代碼片段演示如何使用服務賬戶和gRPC調用Google Cloud PubSub API弄抬。證書從已知的位置加載或者通過程序運行環(huán)境提供的自動發(fā)現宪郊,比如,Google Compute Engine懊亡。這個例子是指定谷歌和他的服務的乎串,其他服務提供者可以使用相同的模式。

GoogleCredentials creds = GoogleCredentials.getApplicationDefault();
ManagedChannel channel = ManagedChannelBuilder.forTarget("greeter.googleapis.com")
    .build();
GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel)
    .withCallCredentials(MoreCallCredentials.from(creds));
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末坏瞄,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子鸠匀,更是在濱河造成了極大的恐慌,老刑警劉巖宅此,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件父腕,死亡現場離奇詭異青瀑,居然都是意外死亡萧诫,警方通過查閱死者的電腦和手機帘饶,發(fā)現死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門及刻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缴饭,“玉大人馁菜,你說我怎么就攤上這事∏突穑” “怎么了龙助?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵寇壳,是天一觀的道長锣咒。 經常有香客問我试和,道長衅枫,這世上最難降的妖魔是什么弦撩? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任益楼,我火速辦了婚禮点晴,結果婚禮上,老公的妹妹穿的比我還像新娘陪竿。我一直安慰自己屠橄,他們只是感情好捐康,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布解总。 她就那樣靜靜地躺著花枫,像睡著了一般掏膏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上佳簸,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天生均,我揣著相機與錄音腥刹,去河邊找鬼。 笑死佩脊,一個胖子當著我的面吹牛,可吹牛的內容都是我干的威彰。 我是一名探鬼主播穴肘,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼梢褐,長吁一口氣:“原來是場噩夢啊……” “哼赵讯!你這毒婦竟也來了?” 一聲冷哼從身側響起边翼,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤组底,失蹤者是張志新(化名)和其女友劉穎筐骇,沒想到半個月后江滨,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡告唆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年擒悬,在試婚紗的時候發(fā)現自己被綠了稻艰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡僧凤,死狀恐怖拼弃,靈堂內的尸體忽然破棺而出摇展,到底是詐尸還是另有隱情,我是刑警寧澤咏连,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布祟滴,位于F島的核電站,受9級特大地震影響骑晶,放射性物質發(fā)生泄漏草慧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一仔雷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧电抚,春花似錦竖共、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至狰挡,卻和暖如春释涛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背唇撬。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工窖认, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人烧给。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓喝噪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親榴鼎。 傳聞我的和親對象是個殘疾皇子晚唇,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內容