1 /* 2 * 3 * Copyright 2016 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_OAUTH2_OAUTH2_CREDENTIALS_H 20 #define GRPC_CORE_LIB_SECURITY_CREDENTIALS_OAUTH2_OAUTH2_CREDENTIALS_H 21 22 #include <grpc/support/port_platform.h> 23 24 #include <string> 25 26 #include <grpc/grpc_security.h> 27 #include "src/core/lib/json/json.h" 28 #include "src/core/lib/security/credentials/credentials.h" 29 #include "src/core/lib/uri/uri_parser.h" 30 31 // Constants. 32 #define GRPC_STS_POST_MINIMAL_BODY_FORMAT_STRING \ 33 "grant_type=urn:ietf:params:oauth:grant-type:token-exchange&subject_token=%" \ 34 "s&subject_token_type=%s" 35 36 // auth_refresh_token parsing. 37 struct grpc_auth_refresh_token { 38 const char* type; 39 char* client_id; 40 char* client_secret; 41 char* refresh_token; 42 }; 43 /// Returns 1 if the object is valid, 0 otherwise. 44 int grpc_auth_refresh_token_is_valid( 45 const grpc_auth_refresh_token* refresh_token); 46 47 /// Creates a refresh token object from string. Returns an invalid object if a 48 /// parsing error has been encountered. 49 grpc_auth_refresh_token grpc_auth_refresh_token_create_from_string( 50 const char* json_string); 51 52 /// Creates a refresh token object from parsed json. Returns an invalid object 53 /// if a parsing error has been encountered. 54 grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json( 55 const grpc_core::Json& json); 56 57 /// Destructs the object. 58 void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token* refresh_token); 59 60 // -- Oauth2 Token Fetcher credentials -- 61 // 62 // This object is a base for credentials that need to acquire an oauth2 token 63 // from an http service. 64 65 struct grpc_oauth2_pending_get_request_metadata { 66 grpc_credentials_mdelem_array* md_array; 67 grpc_closure* on_request_metadata; 68 grpc_polling_entity* pollent; 69 struct grpc_oauth2_pending_get_request_metadata* next; 70 }; 71 72 class grpc_oauth2_token_fetcher_credentials : public grpc_call_credentials { 73 public: 74 grpc_oauth2_token_fetcher_credentials(); 75 ~grpc_oauth2_token_fetcher_credentials() override; 76 77 bool get_request_metadata(grpc_polling_entity* pollent, 78 grpc_auth_metadata_context context, 79 grpc_credentials_mdelem_array* md_array, 80 grpc_closure* on_request_metadata, 81 grpc_error** error) override; 82 83 void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, 84 grpc_error* error) override; 85 86 void on_http_response(grpc_credentials_metadata_request* r, 87 grpc_error* error); 88 std::string debug_string() override; 89 90 protected: 91 virtual void fetch_oauth2(grpc_credentials_metadata_request* req, 92 grpc_httpcli_context* httpcli_context, 93 grpc_polling_entity* pollent, grpc_iomgr_cb_func cb, 94 grpc_millis deadline) = 0; 95 96 private: 97 gpr_mu mu_; 98 grpc_mdelem access_token_md_ = GRPC_MDNULL; 99 gpr_timespec token_expiration_; 100 bool token_fetch_pending_ = false; 101 grpc_oauth2_pending_get_request_metadata* pending_requests_ = nullptr; 102 grpc_httpcli_context httpcli_context_; 103 grpc_polling_entity pollent_; 104 }; 105 106 // Google refresh token credentials. 107 class grpc_google_refresh_token_credentials final 108 : public grpc_oauth2_token_fetcher_credentials { 109 public: 110 grpc_google_refresh_token_credentials(grpc_auth_refresh_token refresh_token); 111 ~grpc_google_refresh_token_credentials() override; 112 refresh_token()113 const grpc_auth_refresh_token& refresh_token() const { 114 return refresh_token_; 115 } 116 117 std::string debug_string() override; 118 119 protected: 120 void fetch_oauth2(grpc_credentials_metadata_request* req, 121 grpc_httpcli_context* httpcli_context, 122 grpc_polling_entity* pollent, grpc_iomgr_cb_func cb, 123 grpc_millis deadline) override; 124 125 private: 126 grpc_auth_refresh_token refresh_token_; 127 grpc_closure http_post_cb_closure_; 128 }; 129 130 // Access token credentials. 131 class grpc_access_token_credentials final : public grpc_call_credentials { 132 public: 133 grpc_access_token_credentials(const char* access_token); 134 ~grpc_access_token_credentials() override; 135 136 bool get_request_metadata(grpc_polling_entity* pollent, 137 grpc_auth_metadata_context context, 138 grpc_credentials_mdelem_array* md_array, 139 grpc_closure* on_request_metadata, 140 grpc_error** error) override; 141 142 void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, 143 grpc_error* error) override; 144 145 std::string debug_string() override; 146 147 private: 148 grpc_mdelem access_token_md_; 149 }; 150 151 // Private constructor for refresh token credentials from an already parsed 152 // refresh token. Takes ownership of the refresh token. 153 grpc_core::RefCountedPtr<grpc_call_credentials> 154 grpc_refresh_token_credentials_create_from_auth_refresh_token( 155 grpc_auth_refresh_token token); 156 157 // Exposed for testing only. 158 grpc_credentials_status 159 grpc_oauth2_token_fetcher_credentials_parse_server_response( 160 const struct grpc_http_response* response, grpc_mdelem* token_md, 161 grpc_millis* token_lifetime); 162 163 namespace grpc_core { 164 // Exposed for testing only. This function validates the options, ensuring that 165 // the required fields are set, and outputs the parsed URL of the STS token 166 // exchanged service. 167 grpc_error* ValidateStsCredentialsOptions( 168 const grpc_sts_credentials_options* options, grpc_uri** sts_url); 169 } // namespace grpc_core 170 171 #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_OAUTH2_OAUTH2_CREDENTIALS_H */ 172