diff options
author | dgn <dgn@chromium.org> | 2015-11-26 05:27:05 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-26 13:27:52 +0000 |
commit | 4779a19456ede067cb623eb117570e9bf5780239 (patch) | |
tree | 6ac2618729f10225515c4dcec86aba0350c4b5f9 /android_webview | |
parent | 82a853121ef353f905d2e019b455242b415d722a (diff) | |
download | chromium_src-4779a19456ede067cb623eb117570e9bf5780239.zip chromium_src-4779a19456ede067cb623eb117570e9bf5780239.tar.gz chromium_src-4779a19456ede067cb623eb117570e9bf5780239.tar.bz2 |
Add Kerberos support to webview
Add negotiate handler to WebView's http auth handlers and
adds support for the policies (AuthAndroidNegotiateAccountType and
AuthServerWhitelist) required to configure Kerberos in WebView
BUG=533513
Review URL: https://codereview.chromium.org/1431473004
Cr-Commit-Position: refs/heads/master@{#361878}
Diffstat (limited to 'android_webview')
8 files changed, 129 insertions, 24 deletions
diff --git a/android_webview/browser/aw_browser_context.cc b/android_webview/browser/aw_browser_context.cc index 1591078..4f3fdb1 100644 --- a/android_webview/browser/aw_browser_context.cc +++ b/android_webview/browser/aw_browser_context.cc @@ -47,6 +47,18 @@ using content::BrowserThread; namespace android_webview { +namespace prefs { + +// String that specifies the Android account type to use for Negotiate +// authentication. +const char kAuthAndroidNegotiateAccountType[] = + "auth.android_negotiate_account_type"; + +// Whitelist containing servers for which Integrated Authentication is enabled. +const char kAuthServerWhitelist[] = "auth.server_whitelist"; + +} // namespace prefs + namespace { // Shows notifications which correspond to PersistentPrefStore's reading errors. @@ -181,8 +193,14 @@ void AwBrowserContext::PreMainMessageLoopRun() { LOG(WARNING) << "Failed to get cache directory for Android WebView. " << "Using app data directory as a fallback."; } + + browser_policy_connector_.reset(new AwBrowserPolicyConnector()); + + InitUserPrefService(); + url_request_context_getter_ = new AwURLRequestContextGetter( - cache_path, cookie_store_.get(), CreateProxyConfigService()); + cache_path, cookie_store_.get(), CreateProxyConfigService(), + user_pref_service_.get()); data_reduction_proxy_io_data_.reset( new data_reduction_proxy::DataReductionProxyIOData( @@ -220,10 +238,6 @@ void AwBrowserContext::PreMainMessageLoopRun() { form_database_service_.reset( new AwFormDatabaseService(context_storage_path_)); - browser_policy_connector_.reset(new AwBrowserPolicyConnector()); - - InitUserPrefService(); - // Ensure the storage partition is initialized in time for DataReductionProxy. EnsureResourceContextInitialized(this); @@ -298,7 +312,7 @@ AwMessagePortService* AwBrowserContext::GetMessagePortService() { return message_port_service_.get(); } -// Create user pref service for autofill functionality. +// Create user pref service void AwBrowserContext::InitUserPrefService() { user_prefs::PrefRegistrySyncable* pref_registry = new user_prefs::PrefRegistrySyncable(); @@ -314,6 +328,10 @@ void AwBrowserContext::InitUserPrefService() { data_reduction_proxy::RegisterSimpleProfilePrefs(pref_registry); policy::URLBlacklistManager::RegisterProfilePrefs(pref_registry); + pref_registry->RegisterStringPref(prefs::kAuthServerWhitelist, std::string()); + pref_registry->RegisterStringPref(prefs::kAuthAndroidNegotiateAccountType, + std::string()); + base::PrefServiceFactory pref_service_factory; pref_service_factory.set_user_prefs(make_scoped_refptr(new AwPrefStore())); pref_service_factory.set_managed_prefs( diff --git a/android_webview/browser/aw_browser_context.h b/android_webview/browser/aw_browser_context.h index 9028da0..4141c3f 100644 --- a/android_webview/browser/aw_browser_context.h +++ b/android_webview/browser/aw_browser_context.h @@ -57,6 +57,14 @@ class AwQuotaManagerBridge; class AwURLRequestContextGetter; class JniDependencyFactory; +namespace prefs { + +// Used for Kerberos authentication. +extern const char kAuthAndroidNegotiateAccountType[]; +extern const char kAuthServerWhitelist[]; + +} // namespace prefs + class AwBrowserContext : public content::BrowserContext, public visitedlink::VisitedLinkDelegate { public: diff --git a/android_webview/browser/aw_browser_policy_connector.cc b/android_webview/browser/aw_browser_policy_connector.cc index f0e03ea..d05a8d2 100644 --- a/android_webview/browser/aw_browser_policy_connector.cc +++ b/android_webview/browser/aw_browser_policy_connector.cc @@ -4,6 +4,7 @@ #include "android_webview/browser/aw_browser_policy_connector.h" +#include "android_webview/browser/aw_browser_context.h" #include "base/bind.h" #include "components/policy/core/browser/android/android_combined_policy_provider.h" #include "components/policy/core/browser/configuration_policy_handler_list.h" @@ -34,12 +35,21 @@ scoped_ptr<policy::ConfigurationPolicyHandlerList> BuildHandlerList( base::Bind(&PopulatePolicyHandlerParameters), base::Bind(&GetChromePolicyDetails))); + // URL Filtering handlers->AddHandler(make_scoped_ptr(new policy::SimplePolicyHandler( policy::key::kURLWhitelist, policy::policy_prefs::kUrlWhitelist, base::Value::TYPE_LIST))); - handlers->AddHandler( make_scoped_ptr(new policy::URLBlacklistPolicyHandler())); + + // HTTP Negotiate authentication + handlers->AddHandler(make_scoped_ptr(new policy::SimplePolicyHandler( + policy::key::kAuthServerWhitelist, prefs::kAuthServerWhitelist, + base::Value::TYPE_STRING))); + handlers->AddHandler(make_scoped_ptr(new policy::SimplePolicyHandler( + policy::key::kAuthAndroidNegotiateAccountType, + prefs::kAuthAndroidNegotiateAccountType, base::Value::TYPE_STRING))); + return handlers.Pass(); } @@ -47,9 +57,9 @@ scoped_ptr<policy::ConfigurationPolicyHandlerList> BuildHandlerList( AwBrowserPolicyConnector::AwBrowserPolicyConnector() : BrowserPolicyConnectorBase(base::Bind(&BuildHandlerList)) { - SetPlatformPolicyProvider(make_scoped_ptr( - new policy::android::AndroidCombinedPolicyProvider(GetSchemaRegistry()))); - InitPolicyProviders(); + SetPlatformPolicyProvider(make_scoped_ptr( + new policy::android::AndroidCombinedPolicyProvider(GetSchemaRegistry()))); + InitPolicyProviders(); } AwBrowserPolicyConnector::~AwBrowserPolicyConnector() {} diff --git a/android_webview/browser/net/aw_url_request_context_getter.cc b/android_webview/browser/net/aw_url_request_context_getter.cc index 529bce4..8941452 100644 --- a/android_webview/browser/net/aw_url_request_context_getter.cc +++ b/android_webview/browser/net/aw_url_request_context_getter.cc @@ -16,6 +16,7 @@ #include "android_webview/common/aw_content_client.h" #include "base/bind.h" #include "base/command_line.h" +#include "base/prefs/pref_service.h" #include "base/strings/string_number_conversions.h" #include "base/threading/sequenced_worker_pool.h" #include "base/threading/worker_pool.h" @@ -31,8 +32,11 @@ #include "net/base/cache_type.h" #include "net/cookies/cookie_store.h" #include "net/dns/mapped_host_resolver.h" +#include "net/http/http_auth_filter.h" +#include "net/http/http_auth_handler_factory.h" #include "net/http/http_cache.h" #include "net/http/http_stream_factory.h" +#include "net/http/url_security_manager.h" #include "net/log/net_log.h" #include "net/proxy/proxy_service.h" #include "net/socket/next_proto.h" @@ -51,20 +55,16 @@ namespace android_webview { namespace { -void ApplyCmdlineOverridesToURLRequestContextBuilder( - net::URLRequestContextBuilder* builder) { +void ApplyCmdlineOverridesToHostResolver( + net::MappedHostResolver* host_resolver) { const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); if (command_line.HasSwitch(switches::kHostResolverRules)) { // If hostname remappings were specified on the command-line, layer these // rules on top of the real host resolver. This allows forwarding all // requests through a designated test server. - scoped_ptr<net::MappedHostResolver> host_resolver( - new net::MappedHostResolver( - net::HostResolver::CreateDefaultResolver(NULL))); host_resolver->SetRulesFromString( command_line.GetSwitchValueASCII(switches::kHostResolverRules)); - builder->set_host_resolver(host_resolver.Pass()); } } @@ -159,13 +159,19 @@ scoped_ptr<net::URLRequestJobFactory> CreateJobFactory( } // namespace AwURLRequestContextGetter::AwURLRequestContextGetter( - const base::FilePath& cache_path, net::CookieStore* cookie_store, - scoped_ptr<net::ProxyConfigService> config_service) + const base::FilePath& cache_path, + net::CookieStore* cookie_store, + scoped_ptr<net::ProxyConfigService> config_service, + PrefService* user_pref_service) : cache_path_(cache_path), net_log_(new net::NetLog()), proxy_config_service_(config_service.Pass()), cookie_store_(cookie_store), - http_user_agent_settings_(new AwHttpUserAgentSettings()) { + http_user_agent_settings_(new AwHttpUserAgentSettings()), + auth_android_negotiate_account_type_(user_pref_service->GetString( + prefs::kAuthAndroidNegotiateAccountType)), + auth_server_whitelist_( + user_pref_service->GetString(prefs::kAuthServerWhitelist)) { // CreateSystemProxyConfigService for Android must be called on main thread. DCHECK_CURRENTLY_ON(BrowserThread::UI); } @@ -215,7 +221,15 @@ void AwURLRequestContextGetter::InitializeURLRequestContext() { ApplyCmdlineOverridesToNetworkSessionParams(&network_session_params); builder.set_http_network_session_params(network_session_params); builder.SetSpdyAndQuicEnabled(true, true); - ApplyCmdlineOverridesToURLRequestContextBuilder(&builder); + + scoped_ptr<net::MappedHostResolver> host_resolver(new net::MappedHostResolver( + net::HostResolver::CreateDefaultResolver(nullptr))); + ApplyCmdlineOverridesToHostResolver(host_resolver.get()); + builder.add_http_auth_handler_factory( + "negotiate", + CreateNegotiateAuthHandlerFactory(host_resolver.get()).release()); + builder.set_host_resolver(host_resolver.Pass()); + url_request_context_ = builder.Build().Pass(); job_factory_ = CreateJobFactory(&protocol_handlers_, @@ -258,4 +272,32 @@ void AwURLRequestContextGetter::SetKeyOnIO(const std::string& key) { request_options()->SetKeyOnIO(key); } +scoped_ptr<net::HttpAuthHandlerFactory> +AwURLRequestContextGetter::CreateNegotiateAuthHandlerFactory( + net::HostResolver* resolver) { + DCHECK(resolver); + + net::HttpAuthFilterWhitelist* auth_filter_default_credentials = nullptr; + if (!auth_server_whitelist_.empty()) { + auth_filter_default_credentials = + new net::HttpAuthFilterWhitelist(auth_server_whitelist_); + } + + url_security_manager_.reset(net::URLSecurityManager::Create( + auth_filter_default_credentials, nullptr /*auth_filter_delegate*/)); + + std::vector<std::string> supported_schemes = {"negotiate"}; + scoped_ptr<net::HttpAuthHandlerFactory> negotiate_factory( + net::HttpAuthHandlerRegistryFactory::Create( + supported_schemes, + url_security_manager_.get(), + resolver, + std::string() /* gssapi_library_name - not used on android */, + auth_android_negotiate_account_type_ , + false /* negotiate_disable_cname_lookup - unsupported policy */, + false /* negotiate_enable_port - unsupported policy */)); + + return negotiate_factory; +} + } // namespace android_webview diff --git a/android_webview/browser/net/aw_url_request_context_getter.h b/android_webview/browser/net/aw_url_request_context_getter.h index b7411de..06ddad5 100644 --- a/android_webview/browser/net/aw_url_request_context_getter.h +++ b/android_webview/browser/net/aw_url_request_context_getter.h @@ -13,13 +13,18 @@ #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_job_factory.h" +class PrefService; + namespace net { class CookieStore; +class HostResolver; +class HttpAuthHandlerFactory; class HttpUserAgentSettings; class NetLog; class ProxyConfigService; class URLRequestContext; class URLRequestJobFactory; +class URLSecurityManager; } namespace android_webview { @@ -31,7 +36,8 @@ class AwURLRequestContextGetter : public net::URLRequestContextGetter { AwURLRequestContextGetter( const base::FilePath& cache_path, net::CookieStore* cookie_store, - scoped_ptr<net::ProxyConfigService> config_service); + scoped_ptr<net::ProxyConfigService> config_service, + PrefService* pref_service); // net::URLRequestContextGetter implementation. net::URLRequestContext* GetURLRequestContext() override; @@ -62,6 +68,11 @@ class AwURLRequestContextGetter : public net::URLRequestContextGetter { void InitializeURLRequestContext(); + // This is called to create a HttpAuthHandlerFactory that will handle + // negotiate challenges for the new URLRequestContext + scoped_ptr<net::HttpAuthHandlerFactory> + CreateNegotiateAuthHandlerFactory(net::HostResolver* resolver); + const base::FilePath cache_path_; scoped_ptr<net::NetLog> net_log_; @@ -71,6 +82,14 @@ class AwURLRequestContextGetter : public net::URLRequestContextGetter { scoped_ptr<net::HttpUserAgentSettings> http_user_agent_settings_; scoped_ptr<net::URLRequestContext> url_request_context_; + // URLSecurityManager associated with the negotiate auth handler. It is + // configured to follow the auth_server_whitelist_ + scoped_ptr<net::URLSecurityManager> url_security_manager_; + + // Store HTTP Auth-related policies in this thread. + std::string auth_android_negotiate_account_type_; + std::string auth_server_whitelist_; + // ProtocolHandlers and interceptors are stored here between // SetHandlersAndInterceptors() and the first GetURLRequestContext() call. content::ProtocolHandlerMap protocol_handlers_; diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java index 5c38f14..9925882 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java +++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java @@ -7,10 +7,8 @@ package org.chromium.android_webview; import android.content.Context; import android.content.SharedPreferences; -import org.chromium.android_webview.policy.AwPolicyProvider; import org.chromium.content.browser.ContentViewStatics; import org.chromium.net.DefaultAndroidKeyStore; -import org.chromium.policy.CombinedPolicyProvider; /** * Java side of the Browser Context: contains all the java side objects needed to host one @@ -32,7 +30,6 @@ public class AwBrowserContext { public AwBrowserContext(SharedPreferences sharedPreferences, Context applicationContext) { mSharedPreferences = sharedPreferences; - CombinedPolicyProvider.get().registerProvider(new AwPolicyProvider(applicationContext)); } public AwGeolocationPermissions getGeolocationPermissions() { diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java index 0989339..a936cd3 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java +++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java @@ -6,6 +6,7 @@ package org.chromium.android_webview; import android.content.Context; +import org.chromium.android_webview.policy.AwPolicyProvider; import org.chromium.base.CommandLine; import org.chromium.base.PathUtils; import org.chromium.base.ThreadUtils; @@ -13,6 +14,7 @@ import org.chromium.base.library_loader.LibraryLoader; import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.ProcessInitException; import org.chromium.content.browser.BrowserStartupController; +import org.chromium.policy.CombinedPolicyProvider; /** * Wrapper for the steps needed to initialize the java and native sides of webview chromium. @@ -54,6 +56,11 @@ public abstract class AwBrowserProcess { ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { + // The policies are used by browser startup, so we need to register the policy + // providers before starting the browser process. This only registers java objects + // and doesn't need the native library. + CombinedPolicyProvider.get().registerProvider(new AwPolicyProvider(context)); + try { BrowserStartupController.get(context, LibraryProcessType.PROCESS_WEBVIEW) .startBrowserProcessesSync(!CommandLine.getInstance().hasSwitch( diff --git a/android_webview/test/shell/AndroidManifest.xml b/android_webview/test/shell/AndroidManifest.xml index dbfa31a..57babe1 100644 --- a/android_webview/test/shell/AndroidManifest.xml +++ b/android_webview/test/shell/AndroidManifest.xml @@ -17,6 +17,10 @@ <uses-permission android:name="android.permission.RECORD_VIDEO" /> <uses-permission android:name="android.permission.CAMERA" /> + <!-- Kerberos authentication --> + <uses-permission android:name="android.permission.GET_ACCOUNTS" /> + <uses-permission android:name="android.permission.USE_CREDENTIALS" /> + <application android:name="org.chromium.android_webview.shell.AwShellApplication" android:label="AwShellApplication" android:hardwareAccelerated="true"> |