Browse Source

feat(wkwebview): create api to allow clients to present a client credential for authentication (#141)

* In order for TLS Mutual Auth to work for webviews, the caller must present a credential. Expose a setter that can be called to set a credential.
Maosen Jason Hu 5 years ago
parent
commit
fc5fd242e2
3 changed files with 31 additions and 0 deletions
  1. 10
    0
      docs/Custom-iOS.md
  2. 1
    0
      ios/RNCWKWebView.h
  3. 20
    0
      ios/RNCWKWebView.m

+ 10
- 0
docs/Custom-iOS.md View File

132
 }
132
 }
133
 ```
133
 ```
134
 
134
 
135
+### Setting Client Certificate Authentication Credential
136
+
137
+If you open webpages that needs a Client Certificate for Authentication, you can create a credential and pass it to the webview:
138
+
139
+```
140
+[RNCWKWebView setClientAuthenticationCredential:credential];
141
+```
142
+
143
+This can be paired with a call from Javascript to pass a string label for the certificate stored in keychain and use native calls to fetch the certificate to create a credential object. This call can be made anywhere that makes sense for your application (e.g. as part of the user authentication stack). The only requirement is to make this call before displaying any webviews.
144
+
135
 ## JavaScript Interface
145
 ## JavaScript Interface
136
 
146
 
137
 To use your custom web view, you'll need to create a class for it. Your class must:
147
 To use your custom web view, you'll need to create a class for it. Your class must:

+ 1
- 0
ios/RNCWKWebView.h View File

44
 @property (nonatomic, assign) BOOL cacheEnabled;
44
 @property (nonatomic, assign) BOOL cacheEnabled;
45
 @property (nonatomic, assign) BOOL allowsLinkPreview;
45
 @property (nonatomic, assign) BOOL allowsLinkPreview;
46
 
46
 
47
++ (void)setClientAuthenticationCredential:(nullable NSURLCredential*)credential;
47
 - (void)postMessage:(NSString *)message;
48
 - (void)postMessage:(NSString *)message;
48
 - (void)injectJavaScript:(NSString *)script;
49
 - (void)injectJavaScript:(NSString *)script;
49
 - (void)goForward;
50
 - (void)goForward;

+ 20
- 0
ios/RNCWKWebView.m View File

15
 
15
 
16
 static NSTimer *keyboardTimer;
16
 static NSTimer *keyboardTimer;
17
 static NSString *const MessageHandlerName = @"ReactNativeWebView";
17
 static NSString *const MessageHandlerName = @"ReactNativeWebView";
18
+static NSURLCredential* clientAuthenticationCredential;
18
 
19
 
19
 // runtime trick to remove WKWebView keyboard default toolbar
20
 // runtime trick to remove WKWebView keyboard default toolbar
20
 // see: http://stackoverflow.com/questions/19033292/ios-7-uiwebview-keyboard-issue/19042279#19042279
21
 // see: http://stackoverflow.com/questions/19033292/ios-7-uiwebview-keyboard-issue/19042279#19042279
386
   return [[NSMutableDictionary alloc] initWithDictionary: event];
387
   return [[NSMutableDictionary alloc] initWithDictionary: event];
387
 }
388
 }
388
 
389
 
390
++ (void)setClientAuthenticationCredential:(nullable NSURLCredential*)credential {
391
+  clientAuthenticationCredential = credential;
392
+}
393
+
394
+- (void)                    webView:(WKWebView *)webView
395
+  didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
396
+                  completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable))completionHandler
397
+{
398
+  if (!clientAuthenticationCredential) {
399
+    completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
400
+    return;
401
+  }
402
+  if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate) {
403
+    completionHandler(NSURLSessionAuthChallengeUseCredential, clientAuthenticationCredential);
404
+  } else {
405
+    completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
406
+  }
407
+}
408
+
389
 #pragma mark - WKNavigationDelegate methods
409
 #pragma mark - WKNavigationDelegate methods
390
 
410
 
391
 /**
411
 /**