protected void Page_Load(object sender, EventArgs e) { GoogleAuthorizationCodeFlow flow; var assembly = Assembly.GetExecutingAssembly(); using (var stream = assembly.GetManifestResourceStream("Tasks.ASP.NET.SimpleOAuth2.client_secrets.json")) { flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer { DataStore = new FileDataStore("Tasks.ASP.NET.Sample.Store"), ClientSecretsStream = stream, Scopes = new[] { TasksService.Scope.TasksReadonly } }); } var uri = Request.Url.ToString(); var code = Request["code"]; if (code != null) { var token = flow.ExchangeCodeForTokenAsync(UserId, code, uri.Substring(0, uri.IndexOf("?")), CancellationToken.None).Result; // Extract the right state. var oauthState = AuthWebUtility.ExtracRedirectFromState( flow.DataStore, UserId, Request["state"]).Result; Response.Redirect(oauthState); } else { var result = new AuthorizationCodeWebApp(flow, uri, uri).AuthorizeAsync(UserId, CancellationToken.None).Result; if (result.RedirectUri != null) { // Redirect the user to the authorization server. Response.Redirect(result.RedirectUri); } else { // The data store contains the user credential, so the user has been already authenticated. service = new TasksService(new BaseClientService.Initializer { ApplicationName = "Tasks API Sample", HttpClientInitializer = result.Credential }); } } }
/// <summary> /// Processes the request based on the path. /// </summary> /// <param name="context">Contains the request and response.</param> public void ProcessRequest(HttpContext context) { // Redirect base path to signin. if (context.Request.Path.EndsWith("/")) { context.Response.RedirectPermanent("signin.ashx"); } // This is reached when the root document is passed. Return HTML // using index.html as a template. if (context.Request.Path.EndsWith("/signin.ashx")) { String state = (String)context.Session["state"]; // Store a random string in the session for verifying // the responses in our OAuth2 flow. if (state == null) { Random random = new Random((int)DateTime.Now.Ticks); StringBuilder builder = new StringBuilder(); for (int i = 0; i < 13; i++) { builder.Append(Convert.ToChar( Convert.ToInt32(Math.Floor( 26 * random.NextDouble() + 65)))); } state = builder.ToString(); context.Session["state"] = state; } // Render the templated HTML. String templatedHTML = File.ReadAllText( context.Server.MapPath("index.html")); templatedHTML = Regex.Replace(templatedHTML, "[{]{2}\\s*APPLICATION_NAME\\s*[}]{2}", APP_NAME); templatedHTML = Regex.Replace(templatedHTML, "[{]{2}\\s*CLIENT_ID\\s*[}]{2}", secrets.ClientId); templatedHTML = Regex.Replace(templatedHTML, "[{]{2}\\s*STATE\\s*[}]{2}", state); context.Response.ContentType = "text/html"; context.Response.Write(templatedHTML); return; } if (context.Session["authState"] == null) { // The connect action exchanges a code from the sign-in button, // verifies it, and creates OAuth2 credentials. if (context.Request.Path.Contains("/connect")) { // Get the code from the request POST body. StreamReader sr = new StreamReader( context.Request.InputStream); string code = sr.ReadToEnd(); string state = context.Request["state"]; // Test that the request state matches the session state. if (!state.Equals(context.Session["state"])) { context.Response.StatusCode = 401; return; } // Use the code exchange flow to get an access and refresh token. IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer { ClientSecrets = secrets, Scopes = SCOPES }); token = flow.ExchangeCodeForTokenAsync("", code, "postmessage", CancellationToken.None).Result; // Create an authorization state from the returned token. context.Session["authState"] = token; // Get tokeninfo for the access token if you want to verify. Oauth2Service service = new Oauth2Service( new Google.Apis.Services.BaseClientService.Initializer()); Oauth2Service.TokeninfoRequest request = service.Tokeninfo(); request.AccessToken = token.AccessToken; Tokeninfo info = request.Execute(); string gplus_id = info.UserId; } else { // No cached state and we are not connecting. context.Response.StatusCode = 400; return; } } else if (context.Request.Path.Contains("/connect")) { // The user is already connected and credentials are cached. context.Response.ContentType = "application/json"; context.Response.StatusCode = 200; context.Response.Write(JsonConvert.SerializeObject("Current user is already connected.")); return; } else { // Register the authenticator and construct the Plus service // for performing API calls on behalf of the user. token = (TokenResponse)context.Session["authState"]; IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer { ClientSecrets = secrets, Scopes = SCOPES }); UserCredential credential = new UserCredential(flow, "me", token); bool success = credential.RefreshTokenAsync(CancellationToken.None).Result; token = credential.Token; ps = new PlusService( new Google.Apis.Services.BaseClientService.Initializer() { ApplicationName = ".NET Quickstart", HttpClientInitializer = credential }); } // Perform an authenticated API request to retrieve the list of // people that the user has made visible to the app. if (context.Request.Path.Contains("/people")) { // Get the PeopleFeed for the currently authenticated user. PeopleFeed pf = ps.People.List("me", PeopleResource.ListRequest.CollectionEnum.Visible).Execute(); // This JSON, representing the people feed, will later be // parsed by the JavaScript client. string jsonContent = Newtonsoft.Json.JsonConvert.SerializeObject(pf); context.Response.ContentType = "application/json"; context.Response.Write(jsonContent); return; } // Disconnect the user from the application by revoking the tokens // and removing all locally stored data associated with the user. if (context.Request.Path.Contains("/disconnect")) { // Perform a get request to the token endpoint to revoke the // refresh token. token = (TokenResponse)context.Session["authState"]; string tokenToRevoke = (token.RefreshToken != null) ? token.RefreshToken : token.AccessToken; WebRequest request = WebRequest.Create( "https://accounts.google.com/o/oauth2/revoke?token=" + tokenToRevoke); WebResponse response = request.GetResponse(); // Remove the cached credentials. context.Session["authState"] = null; // You could reset the state in the session but you must also // reset the state on the client. // context.Session["state"] = null; context.Response.Write( response.GetResponseStream().ToString().ToCharArray()); return; } }