简体   繁体   中英

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

The following code is throwing returning response from google with the required parameter is missing: response_type. Either the error is misleading with something else or the value might be wrong. Here is the documentation: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);

Yes it is possible to code your own version of Google Oauth2 flow.

First call

The first call is a HTTP GET and is the link to the consent screen displayed to the user.

If this is an installed application like a desktop app or console app. Then redirect uri should be urn:ietf:wg:oauth:2.0:oob.

Scopes should be separated by space if you want more than one, add offline if you want to get a refresh token back.

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

second call

The response to the first call is an Authentication Code this code needs to be exchanged with google. This is a 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

The post data for this call is one long string do not try to parse it. Just post it in the body of your call. You are correct that the content type is "application/x-www-form-urlencoded";

The response to this call will contain an access token and a refresh token

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

The access token will expire after one hour so you will need to refresh it thats what the refresh token is for.

refresh access token

The following call is also a HTTP POST

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

working example

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; }
    }

Try This.

   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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM