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.Threading; | 18 using System.Threading; |
18 using System.Threading.Tasks; | 19 using System.Threading.Tasks; |
19 | 20 |
20 using Google.Apis.Auth.OAuth2.Requests; | 21 using Google.Apis.Auth.OAuth2.Requests; |
21 | 22 |
22 namespace Google.Apis.Auth.OAuth2 | 23 namespace Google.Apis.Auth.OAuth2 |
23 { | 24 { |
24 /// <summary> | 25 /// <summary> |
25 /// Thread safe OAuth 2.0 authorization code flow for a web application that persists end-user credentials. | 26 /// Thread safe OAuth 2.0 authorization code flow for a web application that persists end-user credentials. |
26 /// </summary> | 27 /// </summary> |
27 public class AuthorizationCodeWebApp | 28 public class AuthorizationCodeWebApp |
28 { | 29 { |
29 /// <summary> | 30 /// <summary> |
31 /// The state key. As part of making the request for authorization code we save the original request to verify· | |
32 /// that this server create the original request. | |
33 /// </summary> | |
34 public const string StateKey = "oauth_"; | |
35 | |
36 /// <summary>The length of the random number which will be added to the end of the state parameter.</summary> | |
37 public const int StateRandomLength = 8; | |
38 | |
39 /// <summary> | |
30 /// AuthResult which contains the user's credentials if it was loaded su ccessfully from the store. Otherwise | 40 /// AuthResult which contains the user's credentials if it was loaded su ccessfully from the store. Otherwise |
31 /// it contains the redirect URI for the authorization server. | 41 /// it contains the redirect URI for the authorization server. |
32 /// </summary> | 42 /// </summary> |
33 public class AuthResult | 43 public class AuthResult |
34 { | 44 { |
35 /// <summary> | 45 /// <summary> |
36 /// Gets or sets the user's credentials or <c>null</c> in case the e nd user need to authorize. | 46 /// Gets or sets the user's credentials or <c>null</c> in case the e nd user needs to authorize. |
class
2013/10/02 17:37:18
"in case the user need to authorize" should be "in
peleyal
2013/10/02 18:24:45
Done.
| |
37 /// </summary> | 47 /// </summary> |
38 public Credential Credential { get; set; } | 48 public UserCredential Credential { get; set; } |
39 | 49 |
40 /// <summary> | 50 /// <summary> |
41 /// Gets or sets the redirect URI to for the user to authorize again st the authorization server or· | 51 /// Gets or sets the redirect URI to for the user to authorize again st the authorization server or· |
42 /// <c>null</c> in case the <see cref="Google.Apis.Auth.OAuth2.Crede ntial"/> was loaded from the data· | 52 /// <c>null</c> in case the <see cref="Google.Apis.Auth.OAuth2.UserC redential"/> was loaded from the data· |
43 /// store. | 53 /// store. |
44 /// </summary> | 54 /// </summary> |
45 public string RedirectUri { get; set; } | 55 public string RedirectUri { get; set; } |
46 } | 56 } |
47 | 57 |
48 private readonly IAuthorizationCodeFlow flow; | 58 private readonly IAuthorizationCodeFlow flow; |
49 private readonly string redirectUri; | 59 private readonly string redirectUri; |
50 private readonly string state; | 60 private readonly string state; |
51 | 61 |
52 /// <summary>Gets the authorization code flow.</summary> | 62 /// <summary>Gets the authorization code flow.</summary> |
(...skipping 12 matching lines...) Expand all Loading... | |
65 public string State | 75 public string State |
66 { | 76 { |
67 get { return state; } | 77 get { return state; } |
68 } | 78 } |
69 | 79 |
70 /// <summary> | 80 /// <summary> |
71 /// Constructs a new authorization code installed application with the g iven flow and code receiver. | 81 /// Constructs a new authorization code installed application with the g iven flow and code receiver. |
72 /// </summary> | 82 /// </summary> |
73 public AuthorizationCodeWebApp(IAuthorizationCodeFlow flow, string redir ectUri, string state) | 83 public AuthorizationCodeWebApp(IAuthorizationCodeFlow flow, string redir ectUri, string state) |
74 { | 84 { |
85 // TODO(peleyal): should we provide a way to disable to random numbe r in the end of the state parameter? | |
75 this.flow = flow; | 86 this.flow = flow; |
76 this.redirectUri = redirectUri; | 87 this.redirectUri = redirectUri; |
77 this.state = state; | 88 this.state = state; |
78 } | 89 } |
79 | 90 |
80 /// <summary>Authorizes the web application to access user's protected d ata.</summary> | 91 /// <summary>Authorizes the web application to access user's protected d ata.</summary> |
81 /// <param name="userId">User identifier</param> | 92 /// <param name="userId">User identifier</param> |
82 /// <param name="taskCancellationToken">Cancellation token to cancel an operation</param> | 93 /// <param name="taskCancellationToken">Cancellation token to cancel an operation</param> |
83 /// <returns> | 94 /// <returns> |
84 /// Auth result object which contains the user's credential or redirect URI for the authorization server | 95 /// Auth result object which contains the user's credential or redirect URI for the authorization server |
85 /// </returns> | 96 /// </returns> |
86 public async Task<AuthResult> Authorize(string userId, CancellationToken taskCancellationToken) | 97 public async Task<AuthResult> Authorize(string userId, CancellationToken taskCancellationToken) |
87 { | 98 { |
88 // Try to load a token from the data store. | 99 // Try to load a token from the data store. |
89 var token = await Flow.LoadTokenAsync(userId, taskCancellationToken) .ConfigureAwait(false); | 100 var token = await Flow.LoadTokenAsync(userId, taskCancellationToken) .ConfigureAwait(false); |
90 | 101 |
91 // If the stored token is null or it doesn't have a refresh token an d the access token is expired, we need· | 102 // If the stored token is null or it doesn't have a refresh token an d the access token is expired, we need· |
92 // to retrieve a new access token. | 103 // to retrieve a new access token. |
93 if (token == null || (token.RefreshToken == null && token.IsExpired( flow.Clock))) | 104 if (token == null || (token.RefreshToken == null && token.IsExpired( flow.Clock))) |
94 { | 105 { |
95 // Create a authorization code request. | 106 // Create a authorization code request. |
96 AuthorizationCodeRequestUrl codeRequest = Flow.CreateAuthorizati onCodeRequest(redirectUri); | 107 AuthorizationCodeRequestUrl codeRequest = Flow.CreateAuthorizati onCodeRequest(redirectUri); |
97 | 108 |
98 // TODO(peleyal): Change the state to contain some random number . | 109 // Add a random number to the end of the state so we can indicat e the original request was made by this |
class
2013/10/02 17:37:18
Don't forget to verify the state again later as we
peleyal
2013/10/02 18:24:45
Done.
| |
99 codeRequest.State = state; | 110 // call. |
111 var oauthState = state; | |
112 if (Flow.DataStore != null) | |
113 { | |
114 var rndString = new string('9', StateRandomLength); | |
115 var random = new Random().Next(int.Parse(rndString)).ToStrin g("D" + StateRandomLength); | |
116 oauthState += random; | |
117 await Flow.DataStore.StoreAsync(StateKey + userId, oauthStat e); | |
118 } | |
119 codeRequest.State = oauthState; | |
100 | 120 |
101 return new AuthResult { RedirectUri = codeRequest.Build().ToStri ng() }; | 121 return new AuthResult { RedirectUri = codeRequest.Build().ToStri ng() }; |
102 } | 122 } |
103 | 123 |
104 return new AuthResult { Credential = new Credential(flow, userId, to ken) }; | 124 return new AuthResult { Credential = new UserCredential(flow, userId , token) }; |
105 } | 125 } |
106 } | 126 } |
107 } | 127 } |
LEFT | RIGHT |