Commit 82fb972e authored by Yi Su's avatar Yi Su Committed by Commit Bot

Move didReceiveAuthenticationChallenge into CRWWKNavigationHandler.

This CL moves the WKNavigationDelegate method
"didReceiveAuthenticationChallenge" from CRWWebController into
CRWWKNavigationHandler.

Bug: 956511
Change-Id: I6c306b3553781651a6edec88325c7aa57499bc6d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1635255
Commit-Queue: Yi Su <mrsuyi@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#665520}
parent 814b6d05
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
@class CRWWKNavigationStates; @class CRWWKNavigationStates;
@class CRWJSInjector; @class CRWJSInjector;
@class CRWLegacyNativeContentController; @class CRWLegacyNativeContentController;
@class CRWCertVerificationController;
class GURL; class GURL;
namespace base { namespace base {
class RepeatingTimer; class RepeatingTimer;
...@@ -49,6 +50,11 @@ class WKBackForwardListItemHolder; ...@@ -49,6 +50,11 @@ class WKBackForwardListItemHolder;
certVerificationErrorsForNavigationHandler: certVerificationErrorsForNavigationHandler:
(CRWWKNavigationHandler*)navigationHandler; (CRWWKNavigationHandler*)navigationHandler;
// Returns associated certificate verificatio controller.
- (CRWCertVerificationController*)
certVerificationControllerForNavigationHandler:
(CRWWKNavigationHandler*)navigationHandler;
// Returns the associated js injector. // Returns the associated js injector.
- (CRWJSInjector*)JSInjectorForNavigationHandler: - (CRWJSInjector*)JSInjectorForNavigationHandler:
(CRWWKNavigationHandler*)navigationHandler; (CRWWKNavigationHandler*)navigationHandler;
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#import "ios/web/public/download/download_controller.h" #import "ios/web/public/download/download_controller.h"
#import "ios/web/public/url_scheme_util.h" #import "ios/web/public/url_scheme_util.h"
#import "ios/web/public/web_client.h" #import "ios/web/public/web_client.h"
#import "ios/web/security/crw_cert_verification_controller.h"
#import "ios/web/security/wk_web_view_security_util.h" #import "ios/web/security/wk_web_view_security_util.h"
#import "ios/web/web_state/ui/controller/crw_legacy_native_content_controller.h" #import "ios/web/web_state/ui/controller/crw_legacy_native_content_controller.h"
#import "ios/web/web_state/user_interaction_state.h" #import "ios/web/web_state/user_interaction_state.h"
...@@ -36,6 +37,7 @@ ...@@ -36,6 +37,7 @@
#include "ios/web/web_view/content_type_util.h" #include "ios/web/web_view/content_type_util.h"
#import "ios/web/web_view/wk_web_view_util.h" #import "ios/web/web_view/wk_web_view_util.h"
#import "net/base/mac/url_conversions.h" #import "net/base/mac/url_conversions.h"
#include "net/cert/x509_util_ios.h"
#include "url/gurl.h" #include "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
...@@ -76,6 +78,9 @@ using web::wk_navigation_util::IsWKInternalUrl; ...@@ -76,6 +78,9 @@ using web::wk_navigation_util::IsWKInternalUrl;
// Returns the CertVerificationErrorsCacheType from self.delegate. // Returns the CertVerificationErrorsCacheType from self.delegate.
@property(nonatomic, readonly, assign) @property(nonatomic, readonly, assign)
web::CertVerificationErrorsCacheType* certVerificationErrors; web::CertVerificationErrorsCacheType* certVerificationErrors;
// Returns the CRWCertVerificationController from self.delegate.
@property(nonatomic, readonly, weak)
CRWCertVerificationController* certVerificationController;
// Returns the docuemnt URL from self.delegate. // Returns the docuemnt URL from self.delegate.
@property(nonatomic, readonly, assign) GURL documentURL; @property(nonatomic, readonly, assign) GURL documentURL;
// Returns the session controller from self.navigationManagerImpl. // Returns the session controller from self.navigationManagerImpl.
...@@ -1082,6 +1087,41 @@ using web::wk_navigation_util::IsWKInternalUrl; ...@@ -1082,6 +1087,41 @@ using web::wk_navigation_util::IsWKInternalUrl;
(void (^)(NSURLSessionAuthChallengeDisposition, (void (^)(NSURLSessionAuthChallengeDisposition,
NSURLCredential*))completionHandler { NSURLCredential*))completionHandler {
[self didReceiveWKNavigationDelegateCallback]; [self didReceiveWKNavigationDelegateCallback];
NSString* authMethod = challenge.protectionSpace.authenticationMethod;
if ([authMethod isEqual:NSURLAuthenticationMethodHTTPBasic] ||
[authMethod isEqual:NSURLAuthenticationMethodNTLM] ||
[authMethod isEqual:NSURLAuthenticationMethodHTTPDigest]) {
[self handleHTTPAuthForChallenge:challenge
completionHandler:completionHandler];
return;
}
if (![authMethod isEqual:NSURLAuthenticationMethodServerTrust]) {
completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
return;
}
SecTrustRef trust = challenge.protectionSpace.serverTrust;
base::ScopedCFTypeRef<SecTrustRef> scopedTrust(trust,
base::scoped_policy::RETAIN);
__weak CRWWKNavigationHandler* weakSelf = self;
[self.certVerificationController
decideLoadPolicyForTrust:scopedTrust
host:challenge.protectionSpace.host
completionHandler:^(web::CertAcceptPolicy policy,
net::CertStatus status) {
CRWWKNavigationHandler* strongSelf = weakSelf;
if (!strongSelf) {
completionHandler(
NSURLSessionAuthChallengeRejectProtectionSpace, nil);
return;
}
[strongSelf processAuthChallenge:challenge
forCertAcceptPolicy:policy
certStatus:status
completionHandler:completionHandler];
}];
} }
- (void)webViewWebContentProcessDidTerminate:(WKWebView*)webView { - (void)webViewWebContentProcessDidTerminate:(WKWebView*)webView {
...@@ -1110,6 +1150,10 @@ using web::wk_navigation_util::IsWKInternalUrl; ...@@ -1110,6 +1150,10 @@ using web::wk_navigation_util::IsWKInternalUrl;
return [self.delegate JSInjectorForNavigationHandler:self]; return [self.delegate JSInjectorForNavigationHandler:self];
} }
- (CRWCertVerificationController*)certVerificationController {
return [self.delegate certVerificationControllerForNavigationHandler:self];
}
- (CRWLegacyNativeContentController*)legacyNativeContentController { - (CRWLegacyNativeContentController*)legacyNativeContentController {
return [self.delegate legacyNativeContentControllerForNavigationHandler:self]; return [self.delegate legacyNativeContentControllerForNavigationHandler:self];
} }
...@@ -1408,6 +1452,89 @@ using web::wk_navigation_util::IsWKInternalUrl; ...@@ -1408,6 +1452,89 @@ using web::wk_navigation_util::IsWKInternalUrl;
[self.navigationStates removeNavigation:navigation]; [self.navigationStates removeNavigation:navigation];
} }
#pragma mark - Auth Challenge
// Used in webView:didReceiveAuthenticationChallenge:completionHandler: to
// reply with NSURLSessionAuthChallengeDisposition and credentials.
- (void)processAuthChallenge:(NSURLAuthenticationChallenge*)challenge
forCertAcceptPolicy:(web::CertAcceptPolicy)policy
certStatus:(net::CertStatus)certStatus
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition,
NSURLCredential*))completionHandler {
SecTrustRef trust = challenge.protectionSpace.serverTrust;
if (policy == web::CERT_ACCEPT_POLICY_RECOVERABLE_ERROR_ACCEPTED_BY_USER) {
// Cert is invalid, but user agreed to proceed, override default behavior.
completionHandler(NSURLSessionAuthChallengeUseCredential,
[NSURLCredential credentialForTrust:trust]);
return;
}
if (policy != web::CERT_ACCEPT_POLICY_ALLOW &&
SecTrustGetCertificateCount(trust)) {
// The cert is invalid and the user has not agreed to proceed. Cache the
// cert verification result in |_certVerificationErrors|, so that it can
// later be reused inside |didFailProvisionalNavigation:|.
// The leaf cert is used as the key, because the chain provided by
// |didFailProvisionalNavigation:| will differ (it is the server-supplied
// chain), thus if intermediates were considered, the keys would mismatch.
scoped_refptr<net::X509Certificate> leafCert =
net::x509_util::CreateX509CertificateFromSecCertificate(
SecTrustGetCertificateAtIndex(trust, 0),
std::vector<SecCertificateRef>());
if (leafCert) {
bool is_recoverable =
policy == web::CERT_ACCEPT_POLICY_RECOVERABLE_ERROR_UNDECIDED_BY_USER;
std::string host =
base::SysNSStringToUTF8(challenge.protectionSpace.host);
self.certVerificationErrors->Put(
web::CertHostPair(leafCert, host),
web::CertVerificationError(is_recoverable, certStatus));
}
}
completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
}
// Used in webView:didReceiveAuthenticationChallenge:completionHandler: to reply
// with NSURLSessionAuthChallengeDisposition and credentials.
- (void)handleHTTPAuthForChallenge:(NSURLAuthenticationChallenge*)challenge
completionHandler:
(void (^)(NSURLSessionAuthChallengeDisposition,
NSURLCredential*))completionHandler {
NSURLProtectionSpace* space = challenge.protectionSpace;
DCHECK(
[space.authenticationMethod isEqual:NSURLAuthenticationMethodHTTPBasic] ||
[space.authenticationMethod isEqual:NSURLAuthenticationMethodNTLM] ||
[space.authenticationMethod isEqual:NSURLAuthenticationMethodHTTPDigest]);
self.webStateImpl->OnAuthRequired(
space, challenge.proposedCredential,
base::BindRepeating(^(NSString* user, NSString* password) {
[CRWWKNavigationHandler processHTTPAuthForUser:user
password:password
completionHandler:completionHandler];
}));
}
// Used in webView:didReceiveAuthenticationChallenge:completionHandler: to reply
// with NSURLSessionAuthChallengeDisposition and credentials.
+ (void)processHTTPAuthForUser:(NSString*)user
password:(NSString*)password
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition,
NSURLCredential*))completionHandler {
DCHECK_EQ(user == nil, password == nil);
if (!user || !password) {
// Embedder cancelled authentication.
completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
return;
}
completionHandler(
NSURLSessionAuthChallengeUseCredential,
[NSURLCredential
credentialWithUser:user
password:password
persistence:NSURLCredentialPersistenceForSession]);
}
#pragma mark - Public methods #pragma mark - Public methods
- (void)stopLoading { - (void)stopLoading {
......
...@@ -432,27 +432,6 @@ typedef void (^ViewportStateCompletion)(const web::PageViewportState*); ...@@ -432,27 +432,6 @@ typedef void (^ViewportStateCompletion)(const web::PageViewportState*);
// Called when a load ends in an SSL error and certificate chain. // Called when a load ends in an SSL error and certificate chain.
- (void)handleSSLCertError:(NSError*)error - (void)handleSSLCertError:(NSError*)error
forNavigation:(WKNavigation*)navigation; forNavigation:(WKNavigation*)navigation;
// Used in webView:didReceiveAuthenticationChallenge:completionHandler: to
// reply with NSURLSessionAuthChallengeDisposition and credentials.
- (void)processAuthChallenge:(NSURLAuthenticationChallenge*)challenge
forCertAcceptPolicy:(web::CertAcceptPolicy)policy
certStatus:(net::CertStatus)certStatus
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition,
NSURLCredential*))completionHandler;
// Used in webView:didReceiveAuthenticationChallenge:completionHandler: to reply
// with NSURLSessionAuthChallengeDisposition and credentials.
- (void)handleHTTPAuthForChallenge:(NSURLAuthenticationChallenge*)challenge
completionHandler:
(void (^)(NSURLSessionAuthChallengeDisposition,
NSURLCredential*))completionHandler;
// Used in webView:didReceiveAuthenticationChallenge:completionHandler: to reply
// with NSURLSessionAuthChallengeDisposition and credentials.
+ (void)processHTTPAuthForUser:(NSString*)user
password:(NSString*)password
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition,
NSURLCredential*))completionHandler;
// Loads request for the URL of the current navigation item. Subclasses may // Loads request for the URL of the current navigation item. Subclasses may
// choose to build a new NSURLRequest and call |loadRequest| on the underlying // choose to build a new NSURLRequest and call |loadRequest| on the underlying
// web view, or use native web view navigation where possible (for example, // web view, or use native web view navigation where possible (for example,
...@@ -2885,83 +2864,6 @@ typedef void (^ViewportStateCompletion)(const web::PageViewportState*); ...@@ -2885,83 +2864,6 @@ typedef void (^ViewportStateCompletion)(const web::PageViewportState*);
self.webStateImpl->ClearWebUI(); self.webStateImpl->ClearWebUI();
} }
#pragma mark - Auth Challenge
- (void)processAuthChallenge:(NSURLAuthenticationChallenge*)challenge
forCertAcceptPolicy:(web::CertAcceptPolicy)policy
certStatus:(net::CertStatus)certStatus
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition,
NSURLCredential*))completionHandler {
SecTrustRef trust = challenge.protectionSpace.serverTrust;
if (policy == web::CERT_ACCEPT_POLICY_RECOVERABLE_ERROR_ACCEPTED_BY_USER) {
// Cert is invalid, but user agreed to proceed, override default behavior.
completionHandler(NSURLSessionAuthChallengeUseCredential,
[NSURLCredential credentialForTrust:trust]);
return;
}
if (policy != web::CERT_ACCEPT_POLICY_ALLOW &&
SecTrustGetCertificateCount(trust)) {
// The cert is invalid and the user has not agreed to proceed. Cache the
// cert verification result in |_certVerificationErrors|, so that it can
// later be reused inside |didFailProvisionalNavigation:|.
// The leaf cert is used as the key, because the chain provided by
// |didFailProvisionalNavigation:| will differ (it is the server-supplied
// chain), thus if intermediates were considered, the keys would mismatch.
scoped_refptr<net::X509Certificate> leafCert =
net::x509_util::CreateX509CertificateFromSecCertificate(
SecTrustGetCertificateAtIndex(trust, 0),
std::vector<SecCertificateRef>());
if (leafCert) {
bool is_recoverable =
policy == web::CERT_ACCEPT_POLICY_RECOVERABLE_ERROR_UNDECIDED_BY_USER;
std::string host =
base::SysNSStringToUTF8(challenge.protectionSpace.host);
_certVerificationErrors->Put(
web::CertHostPair(leafCert, host),
web::CertVerificationError(is_recoverable, certStatus));
}
}
completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
}
- (void)handleHTTPAuthForChallenge:(NSURLAuthenticationChallenge*)challenge
completionHandler:
(void (^)(NSURLSessionAuthChallengeDisposition,
NSURLCredential*))completionHandler {
NSURLProtectionSpace* space = challenge.protectionSpace;
DCHECK(
[space.authenticationMethod isEqual:NSURLAuthenticationMethodHTTPBasic] ||
[space.authenticationMethod isEqual:NSURLAuthenticationMethodNTLM] ||
[space.authenticationMethod isEqual:NSURLAuthenticationMethodHTTPDigest]);
self.webStateImpl->OnAuthRequired(
space, challenge.proposedCredential,
base::BindRepeating(^(NSString* user, NSString* password) {
[CRWWebController processHTTPAuthForUser:user
password:password
completionHandler:completionHandler];
}));
}
+ (void)processHTTPAuthForUser:(NSString*)user
password:(NSString*)password
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition,
NSURLCredential*))completionHandler {
DCHECK_EQ(user == nil, password == nil);
if (!user || !password) {
// Embedder cancelled authentication.
completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
return;
}
completionHandler(
NSURLSessionAuthChallengeUseCredential,
[NSURLCredential
credentialWithUser:user
password:password
persistence:NSURLCredentialPersistenceForSession]);
}
#pragma mark - CRWWebViewScrollViewProxyObserver #pragma mark - CRWWebViewScrollViewProxyObserver
- (void)webViewScrollViewDidZoom: - (void)webViewScrollViewDidZoom:
...@@ -3562,41 +3464,6 @@ typedef void (^ViewportStateCompletion)(const web::PageViewportState*); ...@@ -3562,41 +3464,6 @@ typedef void (^ViewportStateCompletion)(const web::PageViewportState*);
[self.navigationHandler webView:webView [self.navigationHandler webView:webView
didReceiveAuthenticationChallenge:challenge didReceiveAuthenticationChallenge:challenge
completionHandler:completionHandler]; completionHandler:completionHandler];
NSString* authMethod = challenge.protectionSpace.authenticationMethod;
if ([authMethod isEqual:NSURLAuthenticationMethodHTTPBasic] ||
[authMethod isEqual:NSURLAuthenticationMethodNTLM] ||
[authMethod isEqual:NSURLAuthenticationMethodHTTPDigest]) {
[self handleHTTPAuthForChallenge:challenge
completionHandler:completionHandler];
return;
}
if (![authMethod isEqual:NSURLAuthenticationMethodServerTrust]) {
completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
return;
}
SecTrustRef trust = challenge.protectionSpace.serverTrust;
base::ScopedCFTypeRef<SecTrustRef> scopedTrust(trust,
base::scoped_policy::RETAIN);
__weak CRWWebController* weakSelf = self;
[_certVerificationController
decideLoadPolicyForTrust:scopedTrust
host:challenge.protectionSpace.host
completionHandler:^(web::CertAcceptPolicy policy,
net::CertStatus status) {
CRWWebController* strongSelf = weakSelf;
if (!strongSelf) {
completionHandler(
NSURLSessionAuthChallengeRejectProtectionSpace, nil);
return;
}
[strongSelf processAuthChallenge:challenge
forCertAcceptPolicy:policy
certStatus:status
completionHandler:completionHandler];
}];
} }
- (void)webViewWebContentProcessDidTerminate:(WKWebView*)webView { - (void)webViewWebContentProcessDidTerminate:(WKWebView*)webView {
...@@ -4387,6 +4254,12 @@ typedef void (^ViewportStateCompletion)(const web::PageViewportState*); ...@@ -4387,6 +4254,12 @@ typedef void (^ViewportStateCompletion)(const web::PageViewportState*);
return _certVerificationErrors.get(); return _certVerificationErrors.get();
} }
- (CRWCertVerificationController*)
certVerificationControllerForNavigationHandler:
(CRWWKNavigationHandler*)navigationHandler {
return _certVerificationController;
}
- (GURL)navigationHandlerDocumentURL: - (GURL)navigationHandlerDocumentURL:
(CRWWKNavigationHandler*)navigationHandler { (CRWWKNavigationHandler*)navigationHandler {
return _documentURL; return _documentURL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment