Android-WebView's onReceivedHttpAuthRequest() not called again

7.9k views Asked by At

I am using a webview based application where i am rendering a url in the webview. The Url has a HTTP auth .

When i launch the url very first time,its onReceivedHttpAuthRequest() is called and I display a dialog for user to enter the authentication credentials that is auth username and password.

@Override
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
        final WebView mView = view;
        final HttpAuthHandler mHandler = handler;

        final EditText usernameInput = new EditText(mActivity);
        usernameInput.setHint("Username");

        final EditText passwordInput = new EditText(mActivity);
        passwordInput.setHint("Password");
        passwordInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);

        LinearLayout ll = new LinearLayout(mActivity);
        ll.setOrientation(LinearLayout.VERTICAL);
        ll.addView(usernameInput);
        ll.addView(passwordInput);

        Builder authDialog = new AlertDialog
                .Builder(mActivity)
                .setTitle("Authentication")
                .setView(ll)
                .setCancelable(false)
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        mHandler.proceed(usernameInput.getText().toString(), passwordInput.getText().toString());
                        dialog.dismiss();
                    }
                })
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.dismiss();
                        mView.stopLoading();
                        onLoadListener.onAuthCancel((MyWebView)mView, mTitleTextView);
                    }
                });

        if(view!=null)
            authDialog.show();

    }

On Submitting the request proceed well and the url is loaded. But After I exit the app using back button(not sending in background), if i launch it again and tru to load the same url it directly load the url without asking for credentials that is onReceivedHttpAuthRequest() is never called again.

I am also clearing the credentials on app exit using following code:

WebViewDatabase webDB = WebViewDatabase.getInstance(BrowserActivity.this);
    if(webDB!=null){
        if(webDB.hasFormData())
            webDB.clearFormData();
        if(webDB.hasUsernamePassword())
            webDB.clearUsernamePassword();
        if(webDB.hasHttpAuthUsernamePassword())
            webDB.clearHttpAuthUsernamePassword();
    }
webView.clearCache(true);

Also i am clearing all the webview cache, cookies, and application's cache directory and the webview databases:

BrowserActivity.this.deleteDatabase("webview.db");
BrowserActivity.this.deleteDatabase("webviewCache.db");

I don't know why this is happening. Is there anybody who can help me on this. At least on the issue that why onReceivedHttpAuthRequest() is not called?

3

There are 3 answers

0
hankin On
  1. before load the url,set Authorization information in http headers

    Map extraHeaders = new HashMap<>(); extraHeaders.put("Authorization", "TlRM");//the value is Casually set.
    webView.loadUrl(url, extraHeaders);

  2. in WebViewClient

    @Override public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler,
    String host, String realm) { view.loadUrl(url);//reload the url.
    handler.proceed(account, password); }

  3. I resolve this issue,but I can not speak English very well. Hope it can help you.

0
Thushara On

The reason for this is webview store previous connection cookies. So we need to manually clear them and store new cookie data for the current url. we can do it like this.

HttpURLConnection connection = null;
    try {
        URL urls = new URL(url);
        String authStr = "";
        if (!params.isEmpty()) {
            authStr = params.get(0).getValue() + ":"
                    + params.get(1).getValue();
        }

        String authEncoded = Base64.encodeBytes(authStr.getBytes());

        connection = (HttpURLConnection) urls
                .openConnection();
        connection.setConnectTimeout(5100);
        connection.setReadTimeout(5200);
        connection.setDoOutput(false);
        connection.setRequestProperty("Authorization", "Basic "
                + authEncoded);
        CookieManager cookieManager = CookieManager.getInstance();
        String cookie = cookieManager.getCookie(connection.getURL().toString());
        if (cookie != null) {
            connection.setRequestProperty("Cookie", cookie);
        }
        connection.connect();

        responseCode = connection.getResponseCode();
        InputStream content = connection.getInputStream();
        response = convertStreamToString(content);
        content.close();

        // Get cookies from responses and save into the cookie manager. session is created only in rest call url
        List<String> cookieList = connection.getHeaderFields().get("Set-Cookie");
        if (cookieList != null) {
            for (String cookieTemp : cookieList) {
                cookieManager.setCookie(connection.getURL().toString(), cookieTemp);
            }
        }

    }catch (SocketTimeoutException es){
        response = ConnectionStatus.TIME_OUT.name();
    } catch (Exception e) {
        response = e.getMessage();
        e.printStackTrace();
    }
    finally {
        connection.disconnect();
    }
1
Jesus Almaral - Hackaprende On

I solved it using "Authorization" header instead of using onReceivedHttpAuthRequest()