如何在 C# 中为 Google AutoML 获取 OAuth 2.0 身份验证承载令牌?

How to get an OAuth 2.0 authentication bearer token in C# for Google AutoML?

以下代码从 google 抛出返回响应,缺少必需的参数:response_type。该错误可能会误导其他内容,或者该值可能是错误的。这是文档:https://cloud.google.com/docs/authentication/#oauth-2.0-clients

var client = new RestClient("https://accounts.google.com/o/oauth2/auth");
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddParameter("application/x-www-form-urlencoded", "grant_type=client_credentials&client_id=501819637859-6ng1c949htt0admmpa19vm6tfle04jdc.apps.googleusercontent.com&client_secret=nrrIjxFqugLKd24E8xVesA6f", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

是的,可以编写您自己版本的 Google Oauth2 流程。

第一次通话

第一个调用是 HTTP GET,是 link 显示给用户的同意屏幕。

如果这是已安装的应用程序,例如桌面应用程序或控制台应用程序。那么重定向 uri 应该是 urn:ietf:wg:oauth:2.0:oob.

范围应该用space分开,如果你想要一个以上,如果你想取回刷新令牌,请添加离线。

GET https://accounts.google.com/o/oauth2/v2/auth?client_id={clientid}&redirect_uri={RedirectURI}&scope={scopes}&response_type=code

第二次通话

第一次调用的响应是验证码,此代码需要与 google 交换。这是一个 HTTP POST

POST https://oauth2.googleapis.com/token
code=4/X9lG6uWd8-MMJPElWggHZRzyFKtp.QubAT_P-GEwePvB8fYmgkJzntDnaiAI&client_id= 

{ClientId}&client_secret={ClientSecret}&redirect_uri={RedirectURI}&grant_type=authorization_code

此调用的 post 数据是一个长字符串,请勿尝试解析它。只需 post 它在您的通话正文中。您是正确的,内容类型是“application/x-www-form-urlencoded”;

对此调用的响应将包含一个访问令牌和一个刷新令牌

{
"access_token" : "ya29.1.AADtN_VSBMC2Ga2lhxsTKjVQ_ROco8VbD6h01aj4PcKHLm6qvHbNtn-_BIzXMw",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/J-3zPA8XR1o_cXebV9sDKn_f5MTqaFhKFxH-3PUPiJ4"
}

访问令牌将在一小时后过期,因此您需要刷新它,这就是刷新令牌的用途。

刷新访问令牌

下面的调用也是HTTP POST

https://oauth2.googleapis.com/token
client_id={ClientId}&client_secret={ClientSecret}&refresh_token={Refresh token from previous call}&grant_type=refresh_token

工作示例

class Program
    {
        private const string Clientid = "Add yours";
        private const string Secret = "Add yours.";
        
        static async Task  Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            
            Console.WriteLine($"open the following link in your browser window: {Helper.BuildConsentURL(Clientid, new []{ "profile" })}");
            
            Console.WriteLine("Please paste the Authorization code here:");
            var authorizationCode = Console.ReadLine();

            var tokenResponse = await Helper.ExchangeAuthorizationCode(authorizationCode, Clientid, Secret);

            var refreshTokenResponse = await Helper.ExchangeRefreshToken(tokenResponse.refresh_token, Clientid, Secret);

        }
    }

Helper.cs

 public class Helper
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="clientId"></param>
        /// <param name="scope">string array of scopes</param>
        /// <param name="redirectUri">leave empty for installed application</param>
        /// <returns></returns>
        public static string BuildConsentURL(string clientId, string[] scope, string redirectUri = null)
        {
            if (string.IsNullOrEmpty(redirectUri))
            {
                redirectUri = "urn:ietf:wg:oauth:2.0:oob"; // for installed application
            }

            return
                $"https://accounts.google.com/o/oauth2/auth?client_id={clientId}&redirect_uri={redirectUri}&scope={string.Join(" ", scope)}&response_type=code";
        }

        private static string BuildAuthorizationCodeRequest(string code, string clientId, string secret,
            string redirectUri)
        {
            return
                $"code={code}&client_id={clientId}&client_secret={secret}&redirect_uri={redirectUri}&grant_type=authorization_code";
        }
        
        private static string BuildRefreshAccessTokenRequest(string refreshToken, string clientId, string secret)
        {
            return
                $"client_id={clientId}&client_secret={secret}&refresh_token={refreshToken}&grant_type=refresh_token";
        }


        private static async Task<AuthResponse> PostMessage(string postData)
        {
            AuthResponse result;

            var client = new HttpClient();
            client.BaseAddress = new Uri("https://accounts.google.com/");
            var request = new HttpRequestMessage(HttpMethod.Post, "o/oauth2/token");
            request.Content = new StringContent(postData, Encoding.UTF8, "application/x-www-form-urlencoded");
            var response = await client.SendAsync(request);
            using (var content = response.Content)
            {
                var json = content.ReadAsStringAsync().Result;
                result = JsonSerializer.Deserialize<AuthResponse>(json);
            }
            return result;
        }


        public static async Task<AuthResponse> ExchangeAuthorizationCode(string code, string clientId, string secret,
            string redirectUri = null)
        {
            var result = new AuthResponse();

            if (string.IsNullOrEmpty(redirectUri))
            {
                redirectUri = "urn:ietf:wg:oauth:2.0:oob"; // for installed application
            }

            var postData = BuildAuthorizationCodeRequest(code, clientId, secret, redirectUri);

            return await PostMessage(postData);
        }
        
        public static async Task<AuthResponse> ExchangeRefreshToken(string refreshToken, string clientId, string secret)
        {
            var postData = BuildRefreshAccessTokenRequest(refreshToken, clientId, secret);

            return await PostMessage(postData);
        }
        
    }

authresonse.cs

  public class AuthResponse
    {
        public string access_token { get; set; }
        public string token_type { get; set; }
        public int expires_in { get; set; }
        public string refresh_token { get; set; }
    }

试试这个。

   String client_id = "<OAUTH_client_id >";
            String client_secret = "<OAUTH_client_secret>";

            var BaseAddress = "https://gateway-stage-core.optum.com";
            var httpClient = new HttpClient() { BaseAddress = new Uri(BaseAddress) };


            var creds = $"client_id={client_id}&client_secret={client_secret}&grant_type=client_credentials";
            httpClient.DefaultRequestHeaders.Accept.Clear();
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
            var content = new StringContent(creds, Encoding.UTF8, "application/x-www-form-urlencoded");
            var response = httpClient.PostAsync("/auth/oauth2/cached/token", content).Result;
            var jsonContent = response.Content.ReadAsStringAsync().Result;

            var tokenObj = JsonConvert.DeserializeObject<BearerViewModel>(jsonContent);
            var token = tokenObj.access_token;