com.loopj.android.http.sample.Http401AuthSample.java Source code

Java tutorial

Introduction

Here is the source code for com.loopj.android.http.sample.Http401AuthSample.java

Source

/*
Android Asynchronous Http Client Sample
Copyright (c) 2014 Marek Sebera <marek.sebera@gmail.com>
http://loopj.com
    
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    
    http://www.apache.org/licenses/LICENSE-2.0
    
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package com.loopj.android.http.sample;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.Base64;
import com.loopj.android.http.BaseJsonHttpResponseHandler;
import com.loopj.android.http.RequestHandle;
import com.loopj.android.http.ResponseHandlerInterface;
import com.loopj.android.http.sample.util.SampleJSON;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.message.BasicHeader;

import java.util.List;
import java.util.Locale;

/**
 * This sample demonstrates how to implement HTTP 401 Basic Authentication.
 *
 * @author Noor Dawod <github@fineswap.com>
 */
public class Http401AuthSample extends GetSample {

    private static final String LOG_TAG = "Http401Auth";
    private static final String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
    private static final String HEADER_AUTHORIZATION = "Authorization";
    private static final String HEADER_REALM_PREFIX = "realm=";
    private static final String HEADER_BASIC = "basic";

    private static final String SECRET_USERNAME = "ahc";
    private static final String SECRET_PASSWORD = "LetMeIn";

    private String userName;
    private String passWord;

    public void retryRequest() {
        // File is still smaller than remote file; send a new request.
        onRunButtonPressed();
    }

    @Override
    public String getDefaultURL() {
        return PROTOCOL + "httpbin.org/basic-auth/" + SECRET_USERNAME + "/" + SECRET_PASSWORD;
    }

    @Override
    public int getSampleTitle() {
        return R.string.title_401_unauth;
    }

    @Override
    public RequestHandle executeSample(AsyncHttpClient client, String URL, Header[] headers, HttpEntity entity,
            ResponseHandlerInterface responseHandler) {
        return client.get(this, URL, headers, null, responseHandler);
    }

    @Override
    public Header[] getRequestHeaders() {
        List<Header> headers = getRequestHeadersList();

        // Add authentication header.
        if (userName != null && passWord != null) {
            byte[] base64bytes = Base64.encode((userName + ":" + passWord).getBytes(), Base64.DEFAULT);
            String credentials = new String(base64bytes);
            headers.add(new BasicHeader(HEADER_AUTHORIZATION, HEADER_BASIC + " " + credentials));
        }

        return headers.toArray(new Header[headers.size()]);
    }

    @Override
    public ResponseHandlerInterface getResponseHandler() {
        return new BaseJsonHttpResponseHandler<SampleJSON>() {

            @Override
            public void onStart() {
                clearOutputs();
            }

            @Override
            public void onSuccess(int statusCode, Header[] headers, String rawJsonResponse, SampleJSON response) {
                debugHeaders(LOG_TAG, headers);
                debugStatusCode(LOG_TAG, statusCode);
                if (response != null) {
                    debugResponse(LOG_TAG, rawJsonResponse);
                }
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, Throwable throwable, String rawJsonData,
                    SampleJSON errorResponse) {
                debugHeaders(LOG_TAG, headers);
                debugStatusCode(LOG_TAG, statusCode);
                debugThrowable(LOG_TAG, throwable);

                // Ask the user for credentials if required by the server.
                if (statusCode == 401) {
                    String realm = "Protected Page";
                    String authType = null;

                    // Cycle through the headers and look for the WWW-Authenticate header.
                    for (Header header : headers) {
                        String headerName = header.getName();
                        if (HEADER_WWW_AUTHENTICATE.equalsIgnoreCase(headerName)) {
                            String headerValue = header.getValue().trim();
                            String headerValueLowerCase = headerValue.toLowerCase(Locale.US);

                            // Get the type of auth requested.
                            int charPos = headerValueLowerCase.indexOf(' ');
                            if (0 < charPos) {
                                authType = headerValueLowerCase.substring(0, charPos);

                                // The second part should begin with a "realm=" prefix.
                                if (headerValueLowerCase.substring(1 + charPos).startsWith(HEADER_REALM_PREFIX)) {
                                    // The new realm value, including any possible wrapping quotation.
                                    realm = headerValue.substring(1 + charPos + HEADER_REALM_PREFIX.length());

                                    // If realm starts with a quote, remove surrounding quotes.
                                    if (realm.charAt(0) == '"' || realm.charAt(0) == '\'') {
                                        realm = realm.substring(1, realm.length() - 1);
                                    }
                                }
                            }
                        }
                    }

                    // We will support basic auth in this sample.
                    if (authType != null && HEADER_BASIC.equals(authType)) {
                        // Show a dialog for the user and request user/pass.
                        Log.d(LOG_TAG, HEADER_REALM_PREFIX + realm);

                        // Present the dialog.
                        postRunnable(new DialogRunnable(realm));
                    }
                }
            }

            @Override
            protected SampleJSON parseResponse(String rawJsonData, boolean isFailure) throws Throwable {
                return new ObjectMapper().readValues(new JsonFactory().createParser(rawJsonData), SampleJSON.class)
                        .next();
            }
        };
    }

    private class DialogRunnable implements Runnable, DialogInterface.OnClickListener {

        final String realm;
        final View dialogView;

        public DialogRunnable(String realm) {
            this.realm = realm;
            this.dialogView = LayoutInflater.from(Http401AuthSample.this).inflate(R.layout.credentials,
                    new LinearLayout(Http401AuthSample.this), false);

            // Update the preface text with correct credentials.
            TextView preface = (TextView) dialogView.findViewById(R.id.label_credentials);
            String prefaceText = preface.getText().toString();

            // Substitute placeholders, and re-set the value.
            preface.setText(String.format(prefaceText, SECRET_USERNAME, SECRET_PASSWORD));
        }

        @Override
        public void run() {
            AlertDialog.Builder builder = new AlertDialog.Builder(Http401AuthSample.this);
            builder.setTitle(realm);
            builder.setView(dialogView);
            builder.setPositiveButton(android.R.string.ok, this);
            builder.setNegativeButton(android.R.string.cancel, this);
            builder.show();
        }

        @Override
        public void onClick(DialogInterface dialog, int which) {
            switch (which) {
            case DialogInterface.BUTTON_POSITIVE:
                // Dismiss the dialog.
                dialog.dismiss();

                // Update the username and password variables.
                userName = ((EditText) dialogView.findViewById(R.id.field_username)).getText().toString();
                passWord = ((EditText) dialogView.findViewById(R.id.field_password)).getText().toString();

                // Refetch the remote file.
                retryRequest();

                break;

            case DialogInterface.BUTTON_NEGATIVE:
                // Dismiss the dialog.
                dialog.dismiss();

                break;
            }
        }
    }
}