@anmolsdna,
Thank you for the query. Please take a look at the code example below showing how to use OAuth 2.0 for a Google account:
public class TokenResponse
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "access_token", Required = Newtonsoft.Json.Required.Default)]
public string AccessToken { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "token_type", Required = Newtonsoft.Json.Required.Default)]
public string TokenType { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "expires_in", Required = Newtonsoft.Json.Required.Default)]
public int ExpiresIn { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "refresh_token", Required = Newtonsoft.Json.Required.Default)]
public string RefreshToken { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "scope", Required = Newtonsoft.Json.Required.Default)]
public string Scope { get; set; }
}
/// <summary>
/// Developers console
/// https://console.cloud.google.com/projectselector2
/// Documentation
/// https://developers.google.com/identity/protocols/oauth2/native-app
/// </summary>
internal class GoogleOAuthHelper
{
public const string AUTHORIZATION_URL = "https://accounts.google.com/o/oauth2/v2/auth";
//public const string TOKEN_REQUEST_URL = "https://www.googleapis.com/oauth2/v4/token";
public const string TOKEN_REQUEST_URL = "https://oauth2.googleapis.com/token";
public const string LOGOUT_URL = "https://accounts.google.com/Logout";
public const string LOGIN_URL = "https://accounts.google.com/ServiceLogin";
public static string codeVerifier;
public static string codeChallenge;
public static CodeChallengeMethod codeChallengeMethod = CodeChallengeMethod.S256;
public const string SCOPE =
"https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar" + // Calendar
"+" +
"https%3A%2F%2Fwww.google.com%2Fm8%2Ffeeds%2F" + // Contacts
"+" +
"https%3A%2F%2Fmail.google.com%2F"; // IMAP & SMTP
public const string REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
public const string REDIRECT_TYPE = "code";
static GoogleOAuthHelper()
{
CreateCodeVerifier();
CreateCodeChalange();
}
internal static string CreateCodeVerifier()
{
string allowedChars = "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz-._~";
char[] chars = allowedChars.ToCharArray();
int minLength = 43;
int maxLength = 128;
Random rnd = new Random();
int length = minLength + rnd.Next(maxLength - minLength);
List<char> codeVerifierChars = new List<char>();
for (int i = 0; i < length; i++)
{
int index = rnd.Next(allowedChars.Length);
codeVerifierChars.Add(allowedChars[index]);
}
return codeVerifier = string.Join("", codeVerifierChars.ToArray());
}
internal static string CreateCodeChalange()
{
if (codeChallengeMethod == CodeChallengeMethod.plain)
return codeChallenge = codeVerifier;
byte[] hashValue = null;
using (SHA256 sha256 = SHA256.Create())
hashValue = sha256.ComputeHash(Encoding.ASCII.GetBytes(codeVerifier));
string b64 = Convert.ToBase64String(hashValue);
b64 = b64.Split('=')[0];
b64 = b64.Replace('+', '-');
b64 = b64.Replace('/', '_');
return codeChallenge = b64;
}
internal static string GetAuthorizationCodeUrl(TestUser acc)
{
return GetAuthorizationCodeUrl((OAuthTestUser)acc, SCOPE, REDIRECT_URI, REDIRECT_TYPE);
}
internal static string GetAuthorizationCodeUrlUrl(OAuthTestUser acc)
{
return GetAuthorizationCodeUrl(acc, SCOPE, REDIRECT_URI, REDIRECT_TYPE);
}
internal static string GetAuthorizationCodeUrlUrl(
TestUser acc,
string scope,
string redirectUri,
string responseType)
{
return GetAuthorizationCodeUrl(
(OAuthTestUser)acc,
scope,
redirectUri,
responseType);
}
internal static string GetAuthorizationCodeUrl(
OAuthTestUser acc,
string scope,
string redirectUri,
string responseType)
{
Debug.WriteLine("");
Debug.WriteLine("---------------------------------------------------------");
Debug.WriteLine("-----------OAuth 2.0 authorization information-----------");
Debug.WriteLine("---------------------------------------------------------");
Debug.WriteLine(string.Format("Login: '{0}'", acc.EMail));
string state = System.Web.HttpUtility.UrlEncode(Guid.NewGuid().ToString());
string authorizationCode = null;
string error = null;
string approveUrl = AUTHORIZATION_URL +
$"?client_id={acc.ClientId}&redirect_uri={redirectUri}&response_type={responseType}&scope={scope}&" +
$"code_challenge={codeChallenge}&code_challenge_method={codeChallengeMethod.ToString()}&" +
$"state={state}"
;
return approveUrl;
}
internal static TokenResponse GetAccessTokenByRefreshToken(TestUser user)
{
return GetAccessTokenByRefreshToken((OAuthTestUser)user);
}
internal static TokenResponse GetAccessTokenByRefreshToken(OAuthTestUser user)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(TOKEN_REQUEST_URL);
request.CookieContainer = new CookieContainer();
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
var clientId = System.Web.HttpUtility.UrlEncode(user.ClientId);
var clientSecret = System.Web.HttpUtility.UrlEncode(user.ClientSecret);
var refreshToken = System.Web.HttpUtility.UrlEncode(user.RefreshToken);
var grantType = System.Web.HttpUtility.UrlEncode(GrantTypes.refresh_token.ToString());
string encodedParameters = $"client_id={clientId}&client_secret={clientSecret}&refresh_token={refreshToken}&grant_type={grantType}";
byte[] requestData = Encoding.UTF8.GetBytes(encodedParameters);
request.ContentLength = requestData.Length;
if (requestData.Length > 0)
using (Stream stream = request.GetRequestStream())
stream.Write(requestData, 0, requestData.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string responseText = null;
using (TextReader reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII))
responseText = reader.ReadToEnd();
TokenResponse tokensResponse = JsonConvert.DeserializeObject<TokenResponse>(responseText);
Debug.WriteLine("");
Debug.WriteLine("---------------------------------------------------------");
Debug.WriteLine("-----------OAuth 2.0 authorization information-----------");
Debug.WriteLine("---------------------------------------------------------");
Debug.WriteLine(string.Format("Login: '{0}'", user.EMail));
Debug.WriteLine(string.Format("Access token: '{0}'", tokensResponse.AccessToken));
Debug.WriteLine(string.Format("Token type: '{0}'", tokensResponse.TokenType));
Debug.WriteLine(string.Format("Expires in: '{0}'", tokensResponse.ExpiresIn));
Debug.WriteLine("---------------------------------------------------------");
Debug.WriteLine("");
return tokensResponse;
}
internal static TokenResponse GetAccessTokenByAuthCode(string authorizationCode, TestUser user)
{
return GetAccessTokenByAuthCode(authorizationCode, (OAuthTestUser)user);
}
internal static TokenResponse GetAccessTokenByAuthCode(string authorizationCode, OAuthTestUser user)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(TOKEN_REQUEST_URL);
request.CookieContainer = new CookieContainer();
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string clientId = System.Web.HttpUtility.UrlEncode(user.ClientId);
string clientSecret = System.Web.HttpUtility.UrlEncode(user.ClientSecret);
string authCode = System.Web.HttpUtility.UrlEncode(authorizationCode);
string redirectUri = System.Web.HttpUtility.UrlEncode(REDIRECT_URI);
string grantType = System.Web.HttpUtility.UrlEncode(GrantTypes.authorization_code.ToString());
string encodedParameters = $"client_id={clientId}&client_secret={clientSecret}&code={authCode}&code_verifier={codeVerifier}&redirect_uri={redirectUri}&grant_type={grantType}";
byte[] requestData = Encoding.UTF8.GetBytes(encodedParameters);
request.ContentLength = requestData.Length;
if (requestData.Length > 0)
using (Stream stream = request.GetRequestStream())
stream.Write(requestData, 0, requestData.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string responseText = null;
using (TextReader reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII))
responseText = reader.ReadToEnd();
TokenResponse tokensResponse = JsonConvert.DeserializeObject<TokenResponse>(responseText);
Debug.WriteLine(string.Format("Authorization code: '{0}'", authorizationCode));
Debug.WriteLine(string.Format("Access token: '{0}'", tokensResponse.AccessToken));
Debug.WriteLine(string.Format("Refresh token: '{0}'", tokensResponse.RefreshToken));
Debug.WriteLine(string.Format("Token type: '{0}'", tokensResponse.TokenType));
Debug.WriteLine(string.Format("Expires in: '{0}'", tokensResponse.ExpiresIn));
Debug.WriteLine("---------------------------------------------------------");
Debug.WriteLine("");
return tokensResponse;
}
}
GoogleOAuthHelper
has to be used in the next way:
// The first user has to generate an authorization code URL.
string authUrl = GoogleOAuthHelper.GetAuthorizationCodeUrl(user);
// Then he has to open this url in browser and complete all operations.
// As result he will get authorization code.
// User has to use this authorization code to retrieve refresh token (TokenResponse.RefreshToken)
string authorizationCode = "put your authorization code here";
TokenResponse tokenInfo = GoogleOAuthHelper.GetAccessTokenByAuthCode(authorizationCode, user);
// When refresh token exists, user may use it to retrieve access token
tokenInfo = GoogleOAuthHelper.GetAccessTokenByRefreshToken(user);
SMTP connection:
// The first way
string accessToken = GoogleOAuthHelper.GetAccessTokenByRefreshToken(user).AccessToken;
SmtpClient client = new SmtpClient(
server.ImapUrl,
server.ImapPort,
user.EMail,
accessToken,
true,
SecurityOptions.SSLImplicit);
// The second way
ITokenProvider tokenProvider = TokenProvider.Google.GetInstance(
user.ClientId,
user.ClientSecret,
user.RefreshToken);
SmtpClient client = new SmtpClient(
server.ImapUrl,
server.ImapPort,
user.EMail,
tokenProvider,
server.ImapSecurityOptions);
More details: Gmail Utility Features
You can do it for Office 365 account in a similar way.