OLD | NEW |
(Empty) | |
| 1 /* |
| 2 Copyright 2013 Google Inc |
| 3 |
| 4 Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 you may not use this file except in compliance with the License. |
| 6 You may obtain a copy of the License at |
| 7 |
| 8 http://www.apache.org/licenses/LICENSE-2.0 |
| 9 |
| 10 Unless required by applicable law or agreed to in writing, software |
| 11 distributed under the License is distributed on an "AS IS" BASIS, |
| 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 See the License for the specific language governing permissions and |
| 14 limitations under the License. |
| 15 */ |
| 16 |
| 17 using System.Collections.Specialized; |
| 18 using System.Diagnostics; |
| 19 using System.IO; |
| 20 using System.Linq; |
| 21 using System.Net; |
| 22 using System.Net.Sockets; |
| 23 using System.Threading; |
| 24 using System.Threading.Tasks; |
| 25 |
| 26 using Google.Apis.Auth.OAuth2.Requests; |
| 27 using Google.Apis.Auth.OAuth2.Responses; |
| 28 using Google.Apis.Logging; |
| 29 |
| 30 namespace Google.Apis.Auth.OAuth2 |
| 31 { |
| 32 /// <summary> |
| 33 /// OAuth 2.0 verification code receiver that runs a local server on a free
port and waits for a call with the· |
| 34 /// authorization verification code. |
| 35 /// </summary> |
| 36 public class LocalServerCodeReceiver : ICodeReceiver |
| 37 { |
| 38 private static readonly ILogger Logger = ApplicationContext.Logger.ForTy
pe<LocalServerCodeReceiver>(); |
| 39 |
| 40 /// <summary>The call back format. Expects one port parameter.</summary> |
| 41 private const string LoopbackCallback = "http://localhost:{0}/authorize/
"; |
| 42 |
| 43 /// <summary>Close HTML tag to return the browser so it will close itsel
f.</summary> |
| 44 private const string ClosePageResponse = |
| 45 @"<html> |
| 46 <head><title>OAuth 2.0 Authentication Token Received</title></head> |
| 47 <body> |
| 48 Received verification code. Closing... |
| 49 <script type='text/javascript'> |
| 50 window.setTimeout(function() { |
| 51 window.open('', '_self', '');· |
| 52 window.close();· |
| 53 }, 1000); |
| 54 if (window.opener) { window.opener.checkToken(); } |
| 55 </script> |
| 56 </body> |
| 57 </html>"; |
| 58 |
| 59 private string redirectUri; |
| 60 public string RedirectUri |
| 61 { |
| 62 get |
| 63 { |
| 64 if (!string.IsNullOrEmpty(redirectUri)) |
| 65 { |
| 66 return redirectUri; |
| 67 } |
| 68 |
| 69 return redirectUri = string.Format(LoopbackCallback, GetRandomUn
usedPort()); |
| 70 } |
| 71 } |
| 72 |
| 73 public async Task<AuthorizationCodeResponseUrl> ReceiveCodeAsync(Authori
zationCodeRequestUrl url, |
| 74 CancellationToken taskCancellationToken) |
| 75 { |
| 76 var authorizationUrl = url.Build().ToString(); |
| 77 using (var listener = new HttpListener()) |
| 78 { |
| 79 listener.Prefixes.Add(RedirectUri); |
| 80 try |
| 81 { |
| 82 listener.Start(); |
| 83 |
| 84 Logger.Debug("Open a browser with \"{0}\" URL", authorizatio
nUrl); |
| 85 Process.Start(authorizationUrl); |
| 86 |
| 87 // Wait to get the authorization code response. |
| 88 var context = await listener.GetContextAsync().ConfigureAwai
t(false); |
| 89 NameValueCollection coll = context.Request.QueryString; |
| 90 |
| 91 // Write a "close" response. |
| 92 using (var writer = new StreamWriter(context.Response.Output
Stream)) |
| 93 { |
| 94 writer.WriteLine(ClosePageResponse); |
| 95 writer.Flush(); |
| 96 } |
| 97 context.Response.OutputStream.Close(); |
| 98 |
| 99 // Create a new response URL with a dictionary that contains
all the response query parameters. |
| 100 return new AuthorizationCodeResponseUrl(coll.AllKeys.ToDicti
onary(k => k, k => coll[k])); |
| 101 } |
| 102 finally |
| 103 { |
| 104 listener.Close(); |
| 105 } |
| 106 } |
| 107 } |
| 108 |
| 109 |
| 110 /// <summary>Returns a random, unused port.</summary> |
| 111 private static int GetRandomUnusedPort() |
| 112 { |
| 113 var listener = new TcpListener(IPAddress.Loopback, 0); |
| 114 try |
| 115 { |
| 116 listener.Start(); |
| 117 return ((IPEndPoint)listener.LocalEndpoint).Port; |
| 118 } |
| 119 finally |
| 120 { |
| 121 listener.Stop(); |
| 122 } |
| 123 } |
| 124 } |
| 125 } |
OLD | NEW |