OAuth2 client credentials implementations

thanks! you are a champ!

Thank you! Lovin how active this community is

Hi,
I’m trying to get a client running in java 11, with the java HttpClient class (not the apache one), but I’m getting stuck on getting the authentication token.
I tried extending the Authenticator class and passing that to the HttpClient builder. I also tried to add the client id and secret in the POST body, and any other variation I could think of or adapt from examples I’ve seen in other languages.

I keep getting 401, with this error:

{"error":"unauthorized","error_description":"An Authentication object was not found in the SecurityContext"}

Can anyone help? Maybe you already have an implementation with the Java Httpclient?

Thanks!

Sorry, I can’t help with this one, I hate Java.

I would advise you to create a separate topic asking for help with this specific situation to give it more visibility on the forum. If possible provide a sample code and someone will reply eventually.

OK, I’ll try that. Thanks.

Btw, I was able to get over the authentication problem. Now I’m getting this response:

{
  "error":"invalid_request",
  "error_description":"Missing grant type"
}

You probably forgot to include the grant type in your authorization request
'grant_type' should have 'client_credentials' as value.

I did add the grant type.
I just managed to get it to work. When I used Content-Type of application/x-www-form-urlencoded it started working. I’ve been using multipart before, because that’s what they say in the guide.
I don’t know why.

That is definitely an error in the documentation, the RFC clearly states all requests are application/x-www-form-urlencoded.

I guess I just assumed that in all of my code, until now I didn’t even notice that part of the guide, or perhaps the old documentation was different.

1 Like

Hello there!

Has someone made oauth authentication with react? I’m learning new stuff with react and spent couple of hours debugging because access token expired (need to handle errors better in future…). Was planning to make it possible to get access token directly but have no idea how to continue

Unless you are talking about the experimental server-side rendering you can’t use react to handle API requests and token generation.

It is a severe security risk to expose you credentials or even the generated token to the client. You must use a back-end server to handle all API requests.

I created this proxy to help people who doesn’t want to deal with the back-end part.

C# (using Newtonsoft.Json)

using Newtonsoft.Json;
    public class BlizzardAccessToken
    {
        [JsonProperty("access_token")]
        public string access_token { get; private set; }
        [JsonProperty("token_type")]
        public string token_type { get; private set; }
        [JsonProperty("expires_in")]
        public int expires_in { get; private set; } // Seconds
        [JsonProperty("scope")]
        public string scope { get; private set; }
    }
        private async Task RequestToken()
        {
            try
            {
                using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://{region}.battle.net/oauth/token"))
                {
                    var base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{this.Config.client_id}:{this.Config.client_secret}")); // Point to client_id and client_secret variables
                    request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}");
                    request.Content = new StringContent("grant_type=client_credentials");
                    request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");

                    var response = await Program.httpClient.SendAsync(request); // Replace Program.httpClient with your instance of HttpClient
                    using (HttpContent content = response.Content)
                    {
                        var json = content.ReadAsStringAsync().Result;
                        if (!json.Contains("access_token")) throw new Exception($"Error obtaining token:\n{json}\n{response}");
                        else // Load token information
                        {
                            using (var sr = new StringReader(json))
                            {
                                var serializer = new JsonSerializer();
                                this.Config.Token = (BlizzardAccessToken)serializer.Deserialize(sr, typeof(BlizzardAccessToken)); // Point to where you want your Token stored
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Program.Log(ex.ToString()); // Your logging method
            }
}