Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 /* | 1 /* |
2 Copyright 2013 Google Inc | 2 Copyright 2013 Google Inc |
3 | 3 |
4 Licensed under the Apache License, Version 2.0 (the "License"); | 4 Licensed under the Apache License, Version 2.0 (the "License"); |
5 you may not use this file except in compliance with 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 | 6 You may obtain a copy of the License at |
7 | 7 |
8 http://www.apache.org/licenses/LICENSE-2.0 | 8 http://www.apache.org/licenses/LICENSE-2.0 |
9 | 9 |
10 Unless required by applicable law or agreed to in writing, software | 10 Unless required by applicable law or agreed to in writing, software |
11 distributed under the License is distributed on an "AS IS" BASIS, | 11 distributed under the License is distributed on an "AS IS" BASIS, |
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 See the License for the specific language governing permissions and | 13 See the License for the specific language governing permissions and |
14 limitations under the License. | 14 limitations under the License. |
15 */ | 15 */ |
16 | 16 |
17 using System; | 17 using System; |
18 using System.Collections.Generic; | 18 using System.Collections.Generic; |
19 using System.IO; | 19 using System.IO; |
20 using System.Net.Http; | 20 using System.Net.Http; |
21 using System.Threading; | 21 using System.Threading; |
22 using System.Threading.Tasks; | 22 using System.Threading.Tasks; |
23 | 23 |
24 using Google.Apis.Auth.OAuth2.Requests; | 24 using Google.Apis.Auth.OAuth2.Requests; |
25 using Google.Apis.Auth.OAuth2.Responses; | 25 using Google.Apis.Auth.OAuth2.Responses; |
26 using Google.Apis.Http; | 26 using Google.Apis.Http; |
27 using Google.Apis.Json; | |
28 using Google.Apis.Logging; | 27 using Google.Apis.Logging; |
29 using Google.Apis.Requests.Parameters; | |
30 using Google.Apis.Util; | 28 using Google.Apis.Util; |
31 using Google.Apis.Util.Store; | 29 using Google.Apis.Util.Store; |
32 using Google.Apis.Testing; | 30 using Google.Apis.Testing; |
33 | 31 |
34 namespace Google.Apis.Auth.OAuth2 | 32 namespace Google.Apis.Auth.OAuth2 |
35 { | 33 { |
36 /// <summary> | 34 /// <summary> |
37 /// Thread-safe OAuth 2.0 authorization code flow that manages and persists end-user credentials. | 35 /// Thread-safe OAuth 2.0 authorization code flow that manages and persists end-user credentials. |
38 /// <para> | 36 /// <para> |
39 /// This is designed to simplify the flow in which an end-user authorizes th e application to access their protected | 37 /// This is designed to simplify the flow in which an end-user authorizes th e application to access their protected |
40 /// data, and then the application has access to their data based on an acce ss token and a refresh token to refresh· | 38 /// data, and then the application has access to their data based on an acce ss token and a refresh token to refresh· |
41 /// that access token when it expires. | 39 /// that access token when it expires. |
42 /// </para> | 40 /// </para> |
43 /// </summary> | 41 /// </summary> |
44 public class AuthorizationCodeFlow : IAuthorizationCodeFlow | 42 public class AuthorizationCodeFlow : IAuthorizationCodeFlow |
45 { | 43 { |
46 private static readonly ILogger Logger = ApplicationContext.Logger.ForTy pe<AuthorizationCodeFlow>(); | 44 private static readonly ILogger Logger = ApplicationContext.Logger.ForTy pe<AuthorizationCodeFlow>(); |
47 | 45 |
48 #region Initializer | 46 #region Initializer |
49 | 47 |
50 /// <summary>An initializer class for the authorization code flow. </sum mary> | 48 /// <summary>An initializer class for the authorization code flow. </sum mary> |
51 public class Initializer | 49 public class Initializer |
52 { | 50 { |
53 /// <summary> | 51 /// <summary> |
54 /// Gets or sets the method for presenting the access token to the r esource server. | 52 /// Gets or sets the method for presenting the access token to the r esource server. |
55 /// The default value is <seealso cref="BearerToken.AuthorizationHea derAccessMethod"/>. | 53 /// The default value is <seealso cref="BearerToken.AuthorizationHea derAccessMethod"/>. |
56 /// </summary> | 54 /// </summary> |
57 public IAccessMethod AccessMethod { get; set; } | 55 public IAccessMethod AccessMethod { get; set; } |
58 | 56 |
59 /// <summary>Gets or sets the token server URL.</summary> | 57 /// <summary>Gets the token server URL.</summary> |
60 public string TokenServerUrl { get; private set; } | 58 public string TokenServerUrl { get; private set; } |
61 | 59 |
62 /// <summary>Gets or sets the authorization server URL.</summary> | 60 /// <summary>Gets or sets the authorization server URL.</summary> |
63 public string AuthorizationServerUrl { get; private set; } | 61 public string AuthorizationServerUrl { get; private set; } |
64 | 62 |
65 /// <summary>Gets or sets the client secrets which includes the clie nt identifier and its secret.</summary> | 63 /// <summary>Gets or sets the client secrets which includes the clie nt identifier and its secret.</summary> |
66 public ClientSecrets ClientSecrets { get; set; } | 64 public ClientSecrets ClientSecrets { get; set; } |
67 | 65 |
68 /// <summary> | 66 /// <summary> |
69 /// Gets or sets the client secrets stream which contains the client identifier and its secret. | 67 /// Gets or sets the client secrets stream which contains the client identifier and its secret. |
70 /// </summary> | 68 /// </summary> |
71 /// <remarks>The AuthorizationCodeFlow constructor is responsible fo r disposing the stream.</remarks> | 69 /// <remarks>The AuthorizationCodeFlow constructor is responsible fo r disposing the stream.</remarks> |
72 public Stream ClientSecretsStream { get; set; } | 70 public Stream ClientSecretsStream { get; set; } |
73 | 71 |
74 /// <summary>Gets or sets the data store used to store the token res ponse.</summary> | 72 /// <summary>Gets or sets the data store used to store the token res ponse.</summary> |
75 public IDataStore DataStore { get; set; } | 73 public IDataStore DataStore { get; set; } |
76 | 74 |
77 /// <summary>Gets or sets the scopes.</summary> | 75 /// <summary> |
76 /// Gets or sets the scopes which indicate the API access your appli cation is requesting. | |
77 /// </summary> | |
78 public IEnumerable<string> Scopes { get; set; } | 78 public IEnumerable<string> Scopes { get; set; } |
79 | 79 |
80 /// <summary>· | 80 /// <summary>· |
81 /// Gets or sets the factory for creating <see cref="System.Net.Http .HttpClient"/> instance. | 81 /// Gets or sets the factory for creating <see cref="System.Net.Http .HttpClient"/> instance. |
82 /// </summary> | 82 /// </summary> |
83 public IHttpClientFactory HttpClientFactory { get; set; } | 83 public IHttpClientFactory HttpClientFactory { get; set; } |
84 | 84 |
85 /// <summary> | 85 /// <summary> |
86 /// Get or sets the exponential back-off policy. Default value is < c>UnsuccessfulResponse503</c>, which· | 86 /// Get or sets the exponential back-off policy. Default value is < c>UnsuccessfulResponse503</c>, which· |
87 /// means that exponential back-off is used on 503 abnormal HTTP res ponses. | 87 /// means that exponential back-off is used on 503 abnormal HTTP res ponses. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 private readonly string authorizationServerUrl; | 122 private readonly string authorizationServerUrl; |
123 private readonly ClientSecrets clientSecrets; | 123 private readonly ClientSecrets clientSecrets; |
124 private readonly IDataStore dataStore; | 124 private readonly IDataStore dataStore; |
125 private readonly IEnumerable<string> scopes; | 125 private readonly IEnumerable<string> scopes; |
126 private readonly ConfigurableHttpClient httpClient; | 126 private readonly ConfigurableHttpClient httpClient; |
127 private readonly IClock clock; | 127 private readonly IClock clock; |
128 | 128 |
129 #endregion | 129 #endregion |
130 | 130 |
131 /// <summary>Gets the token server URL.</summary> | 131 /// <summary>Gets the token server URL.</summary> |
132 public string TokenServerEncodedUrl { get { return tokenServerUrl; } } | 132 public string TokenServerUrl { get { return tokenServerUrl; } } |
133 | 133 |
134 /// <summary>Gets the authorization code server URL.</summary> | 134 /// <summary>Gets the authorization code server URL.</summary> |
135 public string AuthorizationServerUrl { get { return authorizationServerU rl; } } | 135 public string AuthorizationServerUrl { get { return authorizationServerU rl; } } |
136 | 136 |
137 /// <summary>Gets the client secrets which includes the client identifie r and its secret.</summary> | 137 /// <summary>Gets the client secrets which includes the client identifie r and its secret.</summary> |
138 public ClientSecrets ClientSecrets { get { return clientSecrets; } } | 138 public ClientSecrets ClientSecrets { get { return clientSecrets; } } |
139 | 139 |
140 /// <summary>Gets the data store used to store the credentials.</summary > | 140 /// <summary>Gets the data store used to store the credentials.</summary > |
141 public IDataStore DataStore { get { return dataStore; } } | 141 public IDataStore DataStore { get { return dataStore; } } |
142 | 142 |
143 /// <summary>Gets the scopes.</summary> | 143 /// <summary>Gets the scopes which indicate the API access your applicat ion is requesting.</summary> |
144 public IEnumerable<string> Scopes { get { return scopes; } } | 144 public IEnumerable<string> Scopes { get { return scopes; } } |
145 | 145 |
146 /// <summary>Gets the HTTP client used to make authentication requests t o the server.</summary> | 146 /// <summary>Gets the HTTP client used to make authentication requests t o the server.</summary> |
147 public ConfigurableHttpClient HttpClient { get { return httpClient; } } | 147 public ConfigurableHttpClient HttpClient { get { return httpClient; } } |
148 | 148 |
149 /// <summary>Constructs a new flow using the initializer's properties.</ summary> | 149 /// <summary>Constructs a new flow using the initializer's properties.</ summary> |
150 public AuthorizationCodeFlow(Initializer initializer) | 150 public AuthorizationCodeFlow(Initializer initializer) |
151 { | 151 { |
152 clientSecrets = initializer.ClientSecrets; | 152 clientSecrets = initializer.ClientSecrets; |
153 if (clientSecrets == null) | 153 if (clientSecrets == null) |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
217 public virtual AuthorizationCodeRequestUrl CreateAuthorizationCodeReques t(string redirectUri) | 217 public virtual AuthorizationCodeRequestUrl CreateAuthorizationCodeReques t(string redirectUri) |
218 { | 218 { |
219 return new AuthorizationCodeRequestUrl(new Uri(AuthorizationServerUr l)) | 219 return new AuthorizationCodeRequestUrl(new Uri(AuthorizationServerUr l)) |
220 { | 220 { |
221 ClientId = ClientSecrets.ClientId, | 221 ClientId = ClientSecrets.ClientId, |
222 Scope = string.Join(" ", Scopes), | 222 Scope = string.Join(" ", Scopes), |
223 RedirectUri = redirectUri | 223 RedirectUri = redirectUri |
224 }; | 224 }; |
225 } | 225 } |
226 | 226 |
227 public async Task<TokenResponse> ExchangeCodeForTokenAsync(string userId , string code, string redirectUri, | 227 public async Task<TokenResponse> ExchangeCodeForTokenAsync(string userId , string code, string redirectUri, |
class
2013/10/02 17:37:18
Missing <summary>
peleyal
2013/10/02 18:24:45
on the interface :) On 2013/10/02 17:37:18, class
| |
228 CancellationToken taskCancellationToken) | 228 CancellationToken taskCancellationToken) |
229 { | 229 { |
230 var authorizationCodeTokenReq = new AuthorizationCodeTokenRequest | 230 var authorizationCodeTokenReq = new AuthorizationCodeTokenRequest |
231 { | 231 { |
232 Scope = string.Join(" ", Scopes), | 232 Scope = string.Join(" ", Scopes), |
233 RedirectUri = redirectUri, | 233 RedirectUri = redirectUri, |
234 Code = code, | 234 Code = code, |
235 }; | 235 }; |
236 | 236 |
237 var token = await FetchTokenAsync(userId, authorizationCodeTokenReq, taskCancellationToken) | 237 var token = await FetchTokenAsync(userId, authorizationCodeTokenReq, taskCancellationToken) |
238 .ConfigureAwait(false); | 238 .ConfigureAwait(false); |
239 await StoreTokenAsync(userId, token, taskCancellationToken).Configur eAwait(false); | 239 await StoreTokenAsync(userId, token, taskCancellationToken).Configur eAwait(false); |
240 return token; | 240 return token; |
241 } | 241 } |
242 | 242 |
243 public async Task<TokenResponse> RefreshTokenAsync(string userId, string refreshToken, | 243 public async Task<TokenResponse> RefreshTokenAsync(string userId, string refreshToken, |
class
2013/10/02 17:37:18
Missing <summary>
peleyal
2013/10/02 18:24:45
on the interface :)
On 2013/10/02 17:37:18, class
| |
244 CancellationToken taskCancellationToken) | 244 CancellationToken taskCancellationToken) |
245 { | 245 { |
246 var refershTokenReq = new RefreshTokenRequest | 246 var refershTokenReq = new RefreshTokenRequest |
247 { | 247 { |
248 RefreshToken = refreshToken, | 248 RefreshToken = refreshToken, |
249 }; | 249 }; |
250 var token = await FetchTokenAsync(userId, refershTokenReq, taskCance llationToken).ConfigureAwait(false); | 250 var token = await FetchTokenAsync(userId, refershTokenReq, taskCance llationToken).ConfigureAwait(false); |
251 | 251 |
252 // The new token may not contain a refresh token, so set it with the given refresh token. | 252 // The new token may not contain a refresh token, so set it with the given refresh token. |
253 if (token.RefreshToken == null) | 253 if (token.RefreshToken == null) |
(...skipping 26 matching lines...) Expand all Loading... | |
280 /// <param name="taskCancellationToken">Cancellation token to cancel ope ration</param> | 280 /// <param name="taskCancellationToken">Cancellation token to cancel ope ration</param> |
281 /// <returns>Token response with the new access token</returns> | 281 /// <returns>Token response with the new access token</returns> |
282 [VisibleForTestOnly] | 282 [VisibleForTestOnly] |
283 internal async Task<TokenResponse> FetchTokenAsync(string userId, TokenR equest request, | 283 internal async Task<TokenResponse> FetchTokenAsync(string userId, TokenR equest request, |
284 CancellationToken taskCancellationToken) | 284 CancellationToken taskCancellationToken) |
285 { | 285 { |
286 // Add client id and client secret to requests. | 286 // Add client id and client secret to requests. |
287 request.ClientId = ClientSecrets.ClientId; | 287 request.ClientId = ClientSecrets.ClientId; |
288 request.ClientSecret = ClientSecrets.ClientSecret; | 288 request.ClientSecret = ClientSecrets.ClientSecret; |
289 | 289 |
290 var httpRequest = new HttpRequestMessage(HttpMethod.Post, TokenServe rEncodedUrl); | 290 TokenResponseException tokenException = null; |
291 httpRequest.Content = ParameterUtils.CreateFormUrlEncodedContent(req uest); | 291 try |
292 | 292 { |
293 var response = await HttpClient.SendAsync(httpRequest, taskCancellat ionToken).ConfigureAwait(false); | 293 var tokenResponse = await request.Execute(httpClient, TokenServe rUrl, taskCancellationToken, Clock); |
294 | 294 return tokenResponse; |
295 var content = await response.Content.ReadAsStringAsync().ConfigureAw ait(false); | 295 } |
296 if (!response.IsSuccessStatusCode) | 296 catch (TokenResponseException ex) |
297 { | 297 { |
298 var error = NewtonsoftJsonSerializer.Instance.Deserialize<TokenE rrorResponse>(content); | 298 // In case there is an exception during getting the token, we de lete any user's token information from· |
299 await DeleteTokenAsync(userId, taskCancellationToken); | 299 // the data store. |
300 throw new TokenResponseException(error); | 300 tokenException = ex; |
301 } | 301 } |
302 | 302 await DeleteTokenAsync(userId, taskCancellationToken); |
303 // Get the token and sets its issued time. | 303 throw tokenException; |
304 var token = NewtonsoftJsonSerializer.Instance.Deserialize<TokenRespo nse>(content); | |
305 token.Issued = clock.Now; | |
306 | |
307 return token; | |
308 } | 304 } |
309 | 305 |
310 public void Dispose() | 306 public void Dispose() |
311 { | 307 { |
312 if (HttpClient != null) | 308 if (HttpClient != null) |
313 { | 309 { |
314 HttpClient.Dispose(); | 310 HttpClient.Dispose(); |
315 } | 311 } |
316 } | 312 } |
317 } | 313 } |
318 } | 314 } |
LEFT | RIGHT |