# Need help with server to server OAuth authentication using C#

**URL:** <https://devforum.zoom.us/t/need-help-with-server-to-server-oauth-authentication-using-c/88187>\
**Category:** API and Webhooks\
**Created:** [May 10, 2023, 8:05pm UTC](https://devforum.zoom.us/t/need-help-with-server-to-server-oauth-authentication-using-c/88187 "2023-05-10T20:05:05Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![rramnarayan](https://avatars.discourse-cdn.com/v4/letter/r/838e76/32.png) [@rramnarayan](https://devforum.zoom.us/u/rramnarayan)\
**Post date:** [May 10, 2023, 8:05pm UTC](https://devforum.zoom.us/t/need-help-with-server-to-server-oauth-authentication-using-c/88187/1 "2023-05-10T20:05:05Z")

</div>

Looking for sample C# code to do server to server OAuth authentication for a C# console application. I currently have C# code that does JWT authentication. Looking to change this since JWT authentication will be discontinued. If anybody can provide some samples, that will be really helpful.

This is my code -

–  
Console.WriteLine(“Starting..”);

var accountId = “xxxxxxxxxxxxxxx”;  
var clientID = “xxxxxxxxxxxx”;  
var clientSecret = “xxxxxxxxxxxxxxx”;

string restcli = “[https://zoom.us/oauth/token?grant\_type=account\_credentials&accountId=](https://zoom.us/oauth/token?grant_type=account_credentials&accountId=)” + accountId;

var client = new RestClient(restcli);  
[//client.Timeout](https://client.Timeout) = -1;

var request = new RestRequest(restcli);  
request.AddHeader(“Authorization”, “Basic \<base64encoded\_”+ clientID + “\_”+clientSecret+ “\>”);

RestResponse response = client.Execute(request);

## Console.WriteLine(response.Content);

And I am getting a “Request failed with status code MethodNotAllowed” in the response.

---

<div class="post-metadata">

**Author:** ![rramnarayan](https://avatars.discourse-cdn.com/v4/letter/r/838e76/32.png) [@rramnarayan](https://devforum.zoom.us/u/rramnarayan)\
**Post date:** [May 11, 2023, 3:44pm UTC](https://devforum.zoom.us/t/need-help-with-server-to-server-oauth-authentication-using-c/88187/2 "2023-05-11T15:44:44Z")

</div>

After additional research, I modified my code to this -

–  
Console.WriteLine(“Starting..”);

var accountId = “xxxxxxxxxxxxxxxx”;  
var clientID = “xxxxxxxxxxxxxxxxxxxxxx”;  
var clientSecret = “xxxxxxxxxxxxxxxxxxxxxxxxxxxxx”;

string restcli = “[https://zoom.us/oauth/token?grant\_type=account\_credentials&accountId=](https://zoom.us/oauth/token?grant_type=account_credentials&accountId=)” + accountId;

RestClient client = new RestClient(restcli);

var request = new RestRequest(restcli);  
request.Timeout = -1;

string clientID\_clientSecret = clientID + “:” + clientSecret;

var plaintextbytes = System.Text.Encoding.UTF8.GetBytes(clientID\_clientSecret);  
string base64Value = System.Convert.ToBase64String(plaintextbytes);

request.AddHeader(“Authorization”, "Basic "+base64Value);

RestResponse response = client.Execute(request);

## Console.WriteLine(response.Content);

And I am still getting a “Request failed with status code MethodNotAllowed” - Some sample codes of C# Server-to-Server OAuth authentication would really be helpful.

---

<div class="post-metadata">

**Author:** ![MultiplayerSession](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/multiplayersession/32/66446_2.png) [@MultiplayerSession](https://devforum.zoom.us/u/MultiplayerSession)\
**Post date:** [May 11, 2023, 4:22pm UTC](https://devforum.zoom.us/t/need-help-with-server-to-server-oauth-authentication-using-c/88187/3 "2023-05-11T16:22:37Z")

</div>

Looking at our implementation (which uses a different technology stack):

- The contents of your query string should be included in the request body instead (still formatted as a query string).
- The parameter name should be spelled `account_id` instead of using camel case.
- Declare your content type in a header such as: `Content-Type: application/x-www-form-urlencoded; charset=utf-8`
- Use the `POST` method (not `GET`).

I’m not sure what framework you’re using to send these requests (I’m most familiar with `HttpWebRequest` in the .NET Framework world), so I can’t recommend which properties and methods you should use.

---

<div class="post-metadata">

**Author:** ![rramnarayan](https://avatars.discourse-cdn.com/v4/letter/r/838e76/32.png) [@rramnarayan](https://devforum.zoom.us/u/rramnarayan)\
**Post date:** [May 11, 2023, 4:44pm UTC](https://devforum.zoom.us/t/need-help-with-server-to-server-oauth-authentication-using-c/88187/4 "2023-05-11T16:44:05Z")

</div>

Hi Christopher, thanks for responding. As mentioned, I am using C# developing on Visual Studio 2022. Do you by any chance have a sample HttpWebRequest code in C# that I can try for the authentication? Any help would be much appreciated.

Thanks,  
Ravi.

---

<div class="post-metadata">

**Author:** ![MultiplayerSession](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/multiplayersession/32/66446_2.png) [@MultiplayerSession](https://devforum.zoom.us/u/MultiplayerSession)\
**Post date:** [May 11, 2023, 5:32pm UTC](https://devforum.zoom.us/t/need-help-with-server-to-server-oauth-authentication-using-c/88187/5 "2023-05-11T17:32:59Z")

</div>

This sample is for a different organization’s API (not for Zoom), but uses a pretty similar workflow that you can use as a starting point.

```auto
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Script.Serialization;

		static internal async Task<string> ReadResponseTextForResponseAsync(WebResponse authorizationResponse)
		{
			string authorizationResponseText;
			using (Stream authorizationResponseStream = authorizationResponse.GetResponseStream())
			{
				UTF8Encoding textEncoderWithoutBOM = new UTF8Encoding(false);
				long responseLengthLong = authorizationResponse.ContentLength;
				if (0 <= responseLengthLong)
				{
					int responseRemainder = (int)responseLengthLong;
					byte[] responseBytes = new byte[responseRemainder];
					int responseIndex = 0;
					int responseBytesRead;
					do
					{
						responseBytesRead = await authorizationResponseStream.ReadAsync(responseBytes, responseIndex, responseRemainder).ConfigureAwait(false);
						responseIndex += responseBytesRead;
						responseRemainder -= responseBytesRead;
					} while (responseBytesRead != 0);
					/* UNDONE: observe response charset. */
					authorizationResponseText = textEncoderWithoutBOM.GetString(responseBytes);
				}
				else
				{
					int responseRemainder = 4096;
					byte[] responseBytes = new byte[responseRemainder];
					int responseIndex = 0;
					int responseBytesRead;
					do
					{
						responseBytesRead = await authorizationResponseStream.ReadAsync(responseBytes, responseIndex, responseRemainder).ConfigureAwait(false);
						responseIndex += responseBytesRead;
						responseRemainder -= responseBytesRead;
						if(responseIndex == responseBytes.Length)
						{
							Array.Resize<byte>(ref responseBytes, responseIndex + 4096);
							responseRemainder += 4096;
						}
						if(responseRemainder < 1)
						{
							break;
						}
					} while (responseBytesRead != 0);
					Array.Resize<byte>(ref responseBytes, responseIndex);
					/* UNDONE: observe response charset. */
					authorizationResponseText = textEncoderWithoutBOM.GetString(responseBytes);
				}
			}
			return authorizationResponseText;
		}

		static internal async Task<string> GetAccessTokenResponseTextAsync()
		{
			string authorizationResponseText;
			HttpWebRequest authorizationRequest = (HttpWebRequest)WebRequest.Create(ContosoHandler.FabrikamAuthURL);
			authorizationRequest.Accept = "application/json";
			authorizationRequest.ContentType = "application/x-www-form-urlencoded; charset=utf-8";
			authorizationRequest.Method = "POST";
			string authorizationRequestBody = "client_id=" + HttpUtility.UrlEncode(ContosoHandler.FabrikamClientID) + "&client_secret=" + HttpUtility.UrlEncode(ContosoHandler.FabrikamSecretKey) + "&grant_type=client_credentials&scope=openid";
			UTF8Encoding textEncoderWithoutBOM = new UTF8Encoding(false);
			byte[] authorizationRequestBodyBytes = textEncoderWithoutBOM.GetBytes(authorizationRequestBody);
			authorizationRequest.ContentLength = authorizationRequestBodyBytes.Length;
			using (Stream authorizationRequestStream = await authorizationRequest.GetRequestStreamAsync().ConfigureAwait(false))
			{
				await authorizationRequestStream.WriteAsync(authorizationRequestBodyBytes, 0, authorizationRequestBodyBytes.Length).ConfigureAwait(false);
				authorizationRequestStream.Close();
				WebResponse authorizationResponse;
				try
				{
					authorizationResponse = await authorizationRequest.GetResponseAsync().ConfigureAwait(false);
				}
				catch (WebException problem)
				{
					authorizationResponse = problem.Response;
					throw;
				}

				using (authorizationResponse)
				{
					authorizationResponseText = await ContosoHandler.ReadResponseTextForResponseAsync(authorizationResponse).ConfigureAwait(false);
					authorizationResponse.Close();
				}
			}

			return authorizationResponseText;
		}

		static internal string GetAccessTokenFromAuthorizationResponse(string authorizationResponseText, out int accessTokenLifetimeSeconds)
		{
			JavaScriptSerializer serializer = new JavaScriptSerializer();
			Dictionary<string, object> authorizationResponseObject = serializer.Deserialize<Dictionary<string, object>>(authorizationResponseText);
			string accessToken = (string)authorizationResponseObject["access_token"];
			accessTokenLifetimeSeconds = (int)authorizationResponseObject["expires_in"];
			return accessToken;
		}

```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/6/1/614bdd549b610bbaa46ff934617683a02bdaa03c.png) [@system](https://devforum.zoom.us/u/system)\
**Post date:** [August 22, 2023, 6:32pm UTC](https://devforum.zoom.us/t/need-help-with-server-to-server-oauth-authentication-using-c/88187/6 "2023-08-22T18:32:20Z")

</div>

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.
