alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Android example source code file (HttpAuthHeader.java)

This example Android source code file (HttpAuthHeader.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Android by Example" TM.

Java - Android tags/keywords

algorithm_token, basic, basic_token, digest, digest_token, httpauthheader, nonce_token, opaque_token, qop_token, realm_token, stale_token, string, unknown

The HttpAuthHeader.java Android example source code

/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * 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 android.net.http;

/**
 * HttpAuthHeader: a class to store HTTP authentication-header parameters.
 * For more information, see: RFC 2617: HTTP Authentication.
 * 
 * {@hide}
 */
public class HttpAuthHeader {
    /**
     * Possible HTTP-authentication header tokens to search for:
     */
    public final static String BASIC_TOKEN = "Basic";
    public final static String DIGEST_TOKEN = "Digest";

    private final static String REALM_TOKEN = "realm";
    private final static String NONCE_TOKEN = "nonce";
    private final static String STALE_TOKEN = "stale";
    private final static String OPAQUE_TOKEN = "opaque";
    private final static String QOP_TOKEN = "qop";
    private final static String ALGORITHM_TOKEN = "algorithm";

    /**
     * An authentication scheme. We currently support two different schemes:
     * HttpAuthHeader.BASIC  - basic, and
     * HttpAuthHeader.DIGEST - digest (algorithm=MD5, QOP="auth").
     */
    private int mScheme;

    public static final int UNKNOWN = 0;
    public static final int BASIC = 1;
    public static final int DIGEST = 2;

    /**
     * A flag, indicating that the previous request from the client was
     * rejected because the nonce value was stale. If stale is TRUE
     * (case-insensitive), the client may wish to simply retry the request
     * with a new encrypted response, without reprompting the user for a
     * new username and password.
     */
    private boolean mStale;

    /**
     * A string to be displayed to users so they know which username and
     * password to use.
     */
    private String mRealm;

    /**
     * A server-specified data string which should be uniquely generated
     * each time a 401 response is made.
     */
    private String mNonce;

    /**
     * A string of data, specified by the server, which should be returned
     *  by the client unchanged in the Authorization header of subsequent
     * requests with URIs in the same protection space.
     */
    private String mOpaque;

    /**
     * This directive is optional, but is made so only for backward
     * compatibility with RFC 2069 [6]; it SHOULD be used by all
     * implementations compliant with this version of the Digest scheme.
     * If present, it is a quoted string of one or more tokens indicating
     * the "quality of protection" values supported by the server.  The
     * value "auth" indicates authentication; the value "auth-int"
     * indicates authentication with integrity protection.
     */
    private String mQop;

    /**
     * A string indicating a pair of algorithms used to produce the digest
     * and a checksum. If this is not present it is assumed to be "MD5".
     */
    private String mAlgorithm;

    /**
     * Is this authentication request a proxy authentication request?
     */
    private boolean mIsProxy;

    /**
     * Username string we get from the user.
     */
    private String mUsername;

    /**
     * Password string we get from the user.
     */
    private String mPassword;

    /**
     * Creates a new HTTP-authentication header object from the
     * input header string.
     * The header string is assumed to contain parameters of at
     * most one authentication-scheme (ensured by the caller).
     */
    public HttpAuthHeader(String header) {
        if (header != null) {
            parseHeader(header);
        }
    }

    /**
     * @return True iff this is a proxy authentication header.
     */
    public boolean isProxy() {
        return mIsProxy;
    }

    /**
     * Marks this header as a proxy authentication header.
     */
    public void setProxy() {
        mIsProxy = true;
    }

    /**
     * @return The username string.
     */
    public String getUsername() {
        return mUsername;
    }

    /**
     * Sets the username string.
     */
    public void setUsername(String username) {
        mUsername = username;
    }

    /**
     * @return The password string.
     */
    public String getPassword() {
        return mPassword;
    }

    /**
     * Sets the password string.
     */
    public void setPassword(String password) {
        mPassword = password;
    }

    /**
     * @return True iff this is the  BASIC-authentication request.
     */
    public boolean isBasic () {
        return mScheme == BASIC;
    }

    /**
     * @return True iff this is the DIGEST-authentication request.
     */
    public boolean isDigest() {
        return mScheme == DIGEST;
    }

    /**
     * @return The authentication scheme requested. We currently
     * support two schemes:
     * HttpAuthHeader.BASIC  - basic, and
     * HttpAuthHeader.DIGEST - digest (algorithm=MD5, QOP="auth").
     */
    public int getScheme() {
        return mScheme;
    }

    /**
     * @return True if indicating that the previous request from
     * the client was rejected because the nonce value was stale.
     */
    public boolean getStale() {
        return mStale;
    }

    /**
     * @return The realm value or null if there is none.
     */
    public String getRealm() {
        return mRealm;
    }

    /**
     * @return The nonce value or null if there is none.
     */
    public String getNonce() {
        return mNonce;
    }

    /**
     * @return The opaque value or null if there is none.
     */
    public String getOpaque() {
        return mOpaque;
    }

    /**
     * @return The QOP ("quality-of_protection") value or null if
     * there is none. The QOP value is always lower-case.
     */
    public String getQop() {
        return mQop;
    }

    /**
     * @return The name of the algorithm used or null if there is
     * none. By default, MD5 is used.
     */
    public String getAlgorithm() {
        return mAlgorithm;
    }

    /**
     * @return True iff the authentication scheme requested by the
     * server is supported; currently supported schemes:
     * BASIC,
     * DIGEST (only algorithm="md5", no qop or qop="auth).
     */
    public boolean isSupportedScheme() {
        // it is a good idea to enforce non-null realms!
        if (mRealm != null) {
            if (mScheme == BASIC) {
                return true;
            } else {
                if (mScheme == DIGEST) {
                    return
                        mAlgorithm.equals("md5") &&
                        (mQop == null || mQop.equals("auth"));
                }
            }
        }

        return false;
    }

    /**
     * Parses the header scheme name and then scheme parameters if
     * the scheme is supported.
     */
    private void parseHeader(String header) {
        if (HttpLog.LOGV) {
            HttpLog.v("HttpAuthHeader.parseHeader(): header: " + header);
        }

        if (header != null) {
            String parameters = parseScheme(header);
            if (parameters != null) {
                // if we have a supported scheme
                if (mScheme != UNKNOWN) {
                    parseParameters(parameters);
                }
            }
        }
    }

    /**
     * Parses the authentication scheme name. If we have a Digest
     * scheme, sets the algorithm value to the default of MD5.
     * @return The authentication scheme parameters string to be
     * parsed later (if the scheme is supported) or null if failed
     * to parse the scheme (the header value is null?).
     */
    private String parseScheme(String header) {
        if (header != null) {
            int i = header.indexOf(' ');
            if (i >= 0) {
                String scheme = header.substring(0, i).trim();
                if (scheme.equalsIgnoreCase(DIGEST_TOKEN)) {
                    mScheme = DIGEST;

                    // md5 is the default algorithm!!!
                    mAlgorithm = "md5";
                } else {
                    if (scheme.equalsIgnoreCase(BASIC_TOKEN)) {
                        mScheme = BASIC;
                    }
                }

                return header.substring(i + 1);
            }
        }

        return null;
    }

    /**
     * Parses a comma-separated list of authentification scheme
     * parameters.
     */
    private void parseParameters(String parameters) {
        if (HttpLog.LOGV) {
            HttpLog.v("HttpAuthHeader.parseParameters():" +
                      " parameters: " + parameters);
        }

        if (parameters != null) {
            int i;
            do {
                i = parameters.indexOf(',');
                if (i < 0) {
                    // have only one parameter
                    parseParameter(parameters);
                } else {
                    parseParameter(parameters.substring(0, i));
                    parameters = parameters.substring(i + 1);
                }
            } while (i >= 0);
        }
    }

    /**
     * Parses a single authentication scheme parameter. The parameter
     * string is expected to follow the format: PARAMETER=VALUE.
     */
    private void parseParameter(String parameter) {
        if (parameter != null) {
            // here, we are looking for the 1st occurence of '=' only!!!
            int i = parameter.indexOf('=');
            if (i >= 0) {
                String token = parameter.substring(0, i).trim();
                String value =
                    trimDoubleQuotesIfAny(parameter.substring(i + 1).trim());

                if (HttpLog.LOGV) {
                    HttpLog.v("HttpAuthHeader.parseParameter():" +
                              " token: " + token +
                              " value: " + value);
                }

                if (token.equalsIgnoreCase(REALM_TOKEN)) {
                    mRealm = value;
                } else {
                    if (mScheme == DIGEST) {
                        parseParameter(token, value);
                    }
                }
            }
        }
    }

    /**
     * If the token is a known parameter name, parses and initializes
     * the token value.
     */
    private void parseParameter(String token, String value) {
        if (token != null && value != null) {
            if (token.equalsIgnoreCase(NONCE_TOKEN)) {
                mNonce = value;
                return;
            }

            if (token.equalsIgnoreCase(STALE_TOKEN)) {
                parseStale(value);
                return;
            }

            if (token.equalsIgnoreCase(OPAQUE_TOKEN)) {
                mOpaque = value;
                return;
            }

            if (token.equalsIgnoreCase(QOP_TOKEN)) {
                mQop = value.toLowerCase();
                return;
            }

            if (token.equalsIgnoreCase(ALGORITHM_TOKEN)) {
                mAlgorithm = value.toLowerCase();
                return;
            }
        }
    }

    /**
     * Parses and initializes the 'stale' paramer value. Any value
     * different from case-insensitive "true" is considered "false".
     */
    private void parseStale(String value) {
        if (value != null) {
            if (value.equalsIgnoreCase("true")) {
                mStale = true;
            }
        }
    }

    /**
     * Trims double-quotes around a parameter value if there are any.
     * @return The string value without the outermost pair of double-
     * quotes or null if the original value is null.
     */
    static private String trimDoubleQuotesIfAny(String value) {
        if (value != null) {
            int len = value.length();
            if (len > 2 &&
                value.charAt(0) == '\"' && value.charAt(len - 1) == '\"') {
                return value.substring(1, len - 1);
            }
        }

        return value;
    }
}

Other Android examples (source code examples)

Here is a short list of links related to this Android HttpAuthHeader.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.