Skip to content

Commit

Permalink
feat(auth): Basic Authentication Support (#1467)
Browse files Browse the repository at this point in the history
Some people prefer using this new prop over the http://username:password@example.com syntax, now webview supports both
  • Loading branch information
iwashi1t committed Sep 30, 2021
1 parent c74c1fd commit 0c42a98
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 0 deletions.
Expand Up @@ -28,6 +28,7 @@
import android.webkit.CookieManager;
import android.webkit.DownloadListener;
import android.webkit.GeolocationPermissions;
import android.webkit.HttpAuthHandler;
import android.webkit.JavascriptInterface;
import android.webkit.RenderProcessGoneDetail;
import android.webkit.SslErrorHandler;
Expand Down Expand Up @@ -556,6 +557,19 @@ public void setSource(WebView view, @Nullable ReadableMap source) {
view.loadUrl(BLANK_URL);
}

@ReactProp(name = "basicAuthCredential")
public void setBasicAuthCredential(WebView view, @Nullable ReadableMap credential) {
@Nullable BasicAuthCredential basicAuthCredential = null;
if (credential != null) {
if (credential.hasKey("username") && credential.hasKey("password")) {
String username = credential.getString("username");
String password = credential.getString("password");
basicAuthCredential = new BasicAuthCredential(username, password);
}
}
((RNCWebView) view).setBasicAuthCredential(basicAuthCredential);
}

@ReactProp(name = "onContentSizeChange")
public void setOnContentSizeChange(WebView view, boolean sendContentSizeChangeEvents) {
((RNCWebView) view).setSendContentSizeChangeEvents(sendContentSizeChangeEvents);
Expand Down Expand Up @@ -849,11 +863,16 @@ protected static class RNCWebViewClient extends WebViewClient {
ReadableArray mUrlPrefixesForDefaultIntent;
protected RNCWebView.ProgressChangedFilter progressChangedFilter = null;
protected @Nullable String ignoreErrFailedForThisURL = null;
protected @Nullable BasicAuthCredential basicAuthCredential = null;

public void setIgnoreErrFailedForThisURL(@Nullable String url) {
ignoreErrFailedForThisURL = url;
}

public void setBasicAuthCredential(@Nullable BasicAuthCredential credential) {
basicAuthCredential = credential;
}

@Override
public void onPageFinished(WebView webView, String url) {
super.onPageFinished(webView, url);
Expand Down Expand Up @@ -938,6 +957,15 @@ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request
return this.shouldOverrideUrlLoading(view, url);
}

@Override
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
if (basicAuthCredential != null) {
handler.proceed(basicAuthCredential.username, basicAuthCredential.password);
return;
}
super.onReceivedHttpAuthRequest(view, handler, host, realm);
}

@Override
public void onReceivedSslError(final WebView webView, final SslErrorHandler handler, final SslError error) {
// onReceivedSslError is called for most requests, per Android docs: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedSslError(android.webkit.WebView,%2520android.webkit.SslErrorHandler,%2520android.net.http.SslError)
Expand Down Expand Up @@ -1463,6 +1491,10 @@ public void setIgnoreErrFailedForThisURL(String url) {
mRNCWebViewClient.setIgnoreErrFailedForThisURL(url);
}

public void setBasicAuthCredential(BasicAuthCredential credential) {
mRNCWebViewClient.setBasicAuthCredential(credential);
}

public void setSendContentSizeChangeEvents(boolean sendContentSizeChangeEvents) {
this.sendContentSizeChangeEvents = sendContentSizeChangeEvents;
}
Expand Down Expand Up @@ -1737,3 +1769,13 @@ public boolean isWaitingForCommandLoadUrl() {
}
}
}

class BasicAuthCredential {
String username;
String password;

BasicAuthCredential(String username, String password) {
this.username = username;
this.password = password;
}
}
1 change: 1 addition & 0 deletions apple/RNCWebView.h
Expand Up @@ -67,6 +67,7 @@
@property (nonatomic, assign) BOOL directionalLockEnabled;
@property (nonatomic, assign) BOOL ignoreSilentHardwareSwitch;
@property (nonatomic, copy) NSString * _Nullable allowingReadAccessToURL;
@property (nonatomic, copy) NSDictionary * _Nullable basicAuthCredential;
@property (nonatomic, assign) BOOL pullToRefreshEnabled;
@property (nonatomic, assign) BOOL enableApplePay;
#if !TARGET_OS_OSX
Expand Down
9 changes: 9 additions & 0 deletions apple/RNCWebView.m
Expand Up @@ -840,6 +840,15 @@ - (void) webView:(WKWebView *)webView
}
}
}
if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodHTTPBasic) {
NSString *username = [_basicAuthCredential valueForKey:@"username"];
NSString *password = [_basicAuthCredential valueForKey:@"password"];
if (username && password) {
NSURLCredential *credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceNone];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
return;
}
}
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
}

Expand Down
1 change: 1 addition & 0 deletions apple/RNCWebViewManager.m
Expand Up @@ -76,6 +76,7 @@ - (RCTUIView *)view
RCT_EXPORT_VIEW_PROPERTY(cacheEnabled, BOOL)
RCT_EXPORT_VIEW_PROPERTY(allowsLinkPreview, BOOL)
RCT_EXPORT_VIEW_PROPERTY(allowingReadAccessToURL, NSString)
RCT_EXPORT_VIEW_PROPERTY(basicAuthCredential, NSDictionary)

#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
RCT_EXPORT_VIEW_PROPERTY(contentInsetAdjustmentBehavior, UIScrollViewContentInsetAdjustmentBehavior)
Expand Down
12 changes: 12 additions & 0 deletions docs/Reference.md
Expand Up @@ -79,6 +79,7 @@ This document lays out the current public properties and methods for the React N
- [`limitsNavigationsToAppBoundDomains`](Reference.md#limitsNavigationsToAppBoundDomains)
- [`autoManageStatusBarEnabled`](Reference.md#autoManageStatusBarEnabled)
- [`setSupportMultipleWindows`](Reference.md#setSupportMultipleWindows)
- [`basicAuthCredential`](Reference.md#basicAuthCredential)
- [`enableApplePay`](Reference.md#enableApplePay)
- [`forceDarkOn`](Reference.md#forceDarkOn)

Expand Down Expand Up @@ -1440,6 +1441,17 @@ Example:
<WebView forceDarkOn={false} />
```

### `basicAuthCredential`

An object that specifies the credentials of a user to be used for basic authentication.

- `username` (string) - A username used for basic authentication.
- `password` (string) - A password used for basic authentication.

| Type | Required |
| ------ | -------- |
| object | No |

## Methods

### `goForward()`[](#methods-index)<!-- Link generated with jump2header -->
Expand Down
18 changes: 18 additions & 0 deletions src/WebViewTypes.ts
Expand Up @@ -251,6 +251,18 @@ export type OnShouldStartLoadWithRequest = (
event: ShouldStartLoadRequest,
) => boolean;

export interface BasicAuthCredential {
/**
* A username used for basic authentication.
*/
username: string;

/**
* A password used for basic authentication.
*/
password: string;
}

export interface CommonNativeWebViewProps extends ViewProps {
cacheEnabled?: boolean;
incognito?: boolean;
Expand Down Expand Up @@ -279,6 +291,7 @@ export interface CommonNativeWebViewProps extends ViewProps {
* Append to the existing user-agent. Overridden if `userAgent` is set.
*/
applicationNameForUserAgent?: string;
basicAuthCredential?: BasicAuthCredential;
}

export interface AndroidNativeWebViewProps extends CommonNativeWebViewProps {
Expand Down Expand Up @@ -1170,4 +1183,9 @@ export interface WebViewSharedProps extends ViewProps {
* Append to the existing user-agent. Overridden if `userAgent` is set.
*/
applicationNameForUserAgent?: string;

/**
* An object that specifies the credentials of a user to be used for basic authentication.
*/
basicAuthCredential?: BasicAuthCredential;
}

0 comments on commit 0c42a98

Please sign in to comment.