Need help with server to server OAuth authentication using C#

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.

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