| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/api/identity/web_auth_flow.h" | 5 #include "chrome/browser/extensions/api/identity/web_auth_flow.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 #include "content/public/browser/notification_types.h" | 29 #include "content/public/browser/notification_types.h" |
| 30 #include "content/public/browser/render_frame_host.h" | 30 #include "content/public/browser/render_frame_host.h" |
| 31 #include "content/public/browser/resource_request_details.h" | 31 #include "content/public/browser/resource_request_details.h" |
| 32 #include "content/public/browser/web_contents.h" | 32 #include "content/public/browser/web_contents.h" |
| 33 #include "crypto/random.h" | 33 #include "crypto/random.h" |
| 34 #include "extensions/browser/app_window/app_window.h" | 34 #include "extensions/browser/app_window/app_window.h" |
| 35 #include "extensions/browser/event_router.h" | 35 #include "extensions/browser/event_router.h" |
| 36 #include "extensions/browser/extension_system.h" | 36 #include "extensions/browser/extension_system.h" |
| 37 #include "net/http/http_response_headers.h" | 37 #include "net/http/http_response_headers.h" |
| 38 #include "url/gurl.h" | 38 #include "url/gurl.h" |
| 39 #include "url/url_constants.h" |
| 39 | 40 |
| 40 using content::RenderViewHost; | 41 using content::RenderViewHost; |
| 41 using content::ResourceRedirectDetails; | 42 using content::ResourceRedirectDetails; |
| 42 using content::WebContents; | 43 using content::WebContents; |
| 43 using content::WebContentsObserver; | 44 using content::WebContentsObserver; |
| 44 using guest_view::GuestViewBase; | 45 using guest_view::GuestViewBase; |
| 45 | 46 |
| 46 namespace extensions { | 47 namespace extensions { |
| 47 | 48 |
| 48 namespace identity_private = api::identity_private; | 49 namespace identity_private = api::identity_private; |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 content::NavigationHandle* navigation_handle) { | 201 content::NavigationHandle* navigation_handle) { |
| 201 if (navigation_handle->IsInMainFrame()) | 202 if (navigation_handle->IsInMainFrame()) |
| 202 BeforeUrlLoaded(navigation_handle->GetURL()); | 203 BeforeUrlLoaded(navigation_handle->GetURL()); |
| 203 } | 204 } |
| 204 | 205 |
| 205 void WebAuthFlow::DidFinishNavigation( | 206 void WebAuthFlow::DidFinishNavigation( |
| 206 content::NavigationHandle* navigation_handle) { | 207 content::NavigationHandle* navigation_handle) { |
| 207 bool failed = false; | 208 bool failed = false; |
| 208 | 209 |
| 209 if (navigation_handle->GetNetErrorCode() != net::OK) { | 210 if (navigation_handle->GetNetErrorCode() != net::OK) { |
| 210 failed = true; | 211 if (navigation_handle->GetURL().spec() == url::kAboutBlankURL) { |
| 211 TRACE_EVENT_ASYNC_STEP_PAST1("identity", "WebAuthFlow", this, | 212 // As part of the OAUth 2.0 protocol with GAIA, at the end of the web |
| 212 "DidFinishNavigationFailure", "error_code", | 213 // authorization flow, GAIA redirects to a custom scheme URL of type |
| 213 navigation_handle->GetNetErrorCode()); | 214 // |com.googleusercontent.apps.123:/<extension_id>|, where |
| 215 // |com.googleusercontent.apps.123| is the reverse DNS notation of the |
| 216 // client ID of the extension that started the web sign-in flow. (The |
| 217 // intent of this weird URL scheme was to make sure it couldn't be loaded |
| 218 // anywhere at all as this makes it much harder to pull off a cross-site |
| 219 // attack that could leak the returned oauth token to a malicious script |
| 220 // or site.) |
| 221 // |
| 222 // This URL is not an accessible URL from within a Guest WebView, so |
| 223 // during its load of this URL, Chrome changes it to |about:blank| and |
| 224 // then the Identity Scope Approval Dialog extension fails to load it. |
| 225 // Failing to load |about:blank| must not be treated as a failure of |
| 226 // the web auth flow. |
| 227 DCHECK_EQ(net::ERR_UNKNOWN_URL_SCHEME, |
| 228 navigation_handle->GetNetErrorCode()); |
| 229 } else { |
| 230 failed = true; |
| 231 TRACE_EVENT_ASYNC_STEP_PAST1("identity", "WebAuthFlow", this, |
| 232 "DidFinishNavigationFailure", "error_code", |
| 233 navigation_handle->GetNetErrorCode()); |
| 234 } |
| 214 } else if (navigation_handle->IsInMainFrame() && | 235 } else if (navigation_handle->IsInMainFrame() && |
| 215 navigation_handle->GetResponseHeaders() && | 236 navigation_handle->GetResponseHeaders() && |
| 216 navigation_handle->GetResponseHeaders()->response_code() >= 400) { | 237 navigation_handle->GetResponseHeaders()->response_code() >= 400) { |
| 217 failed = true; | 238 failed = true; |
| 218 TRACE_EVENT_ASYNC_STEP_PAST1( | 239 TRACE_EVENT_ASYNC_STEP_PAST1( |
| 219 "identity", "WebAuthFlow", this, "DidFinishNavigationFailure", | 240 "identity", "WebAuthFlow", this, "DidFinishNavigationFailure", |
| 220 "response_code", | 241 "response_code", |
| 221 navigation_handle->GetResponseHeaders()->response_code()); | 242 navigation_handle->GetResponseHeaders()->response_code()); |
| 222 } | 243 } |
| 223 | 244 |
| 224 if (failed && delegate_) | 245 if (failed && delegate_) |
| 225 delegate_->OnAuthFlowFailure(LOAD_FAILED); | 246 delegate_->OnAuthFlowFailure(LOAD_FAILED); |
| 226 } | 247 } |
| 227 | 248 |
| 228 } // namespace extensions | 249 } // namespace extensions |
| OLD | NEW |