All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.aerogear.android.authentication.basic.HttpBasicAuthenticationModule Maven / Gradle / Ivy

There is a newer version: 4.0.0
Show newest version
/**
 * JBoss, Home of Professional Open Source
 * Copyright Red Hat, Inc., and individual contributors.
 *
 * 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 org.jboss.aerogear.android.authentication.basic;

import java.net.CookieManager;
import java.net.CookieStore;
import java.net.HttpCookie;
import java.net.PasswordAuthentication;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jboss.aerogear.android.core.Callback;
import org.jboss.aerogear.android.authentication.AbstractAuthenticationModule;
import org.jboss.aerogear.android.pipe.http.HeaderAndBody;
import org.jboss.aerogear.android.pipe.Pipe;

import android.util.Base64;
import android.util.Pair;
import java.net.URI;
import static org.jboss.aerogear.android.authentication.AbstractAuthenticationModule.USERNAME_PARAMETER_NAME;
import org.jboss.aerogear.android.pipe.module.ModuleFields;
import org.jboss.aerogear.android.pipe.http.HttpException;

/**
 * This class provides Authentication using HTTP Basic
 * 
 * As per the HTTP RFC this
 * class will cache credentials and consumed by {@link Pipe} requests. This
 * module assumes that credentials provided are valid and will never fail on {@link #login(java.lang.String, java.lang.String, org.jboss.aerogear.android.core.Callback)
 * } or
 * {@link #logout(org.jboss.aerogear.android.core.Callback)
 * }.
 * 
 * {@link #enroll(java.util.Map, org.jboss.aerogear.android.core.Callback) } is not
 * supported and will always fail.
 * 
 */
public class HttpBasicAuthenticationModule extends AbstractAuthenticationModule {

    private final static String BASIC_HEADER = "Authorization";
    private final static String AUTHORIZATION_METHOD = "Basic";
    private final String loginEndpoint = "";
    private final String logoutEndpoint = "";
    private final String enrollEndpoint = "";
    private final URL baseURL;
    private boolean isLoggedIn = false;
    private PasswordAuthentication auth = new PasswordAuthentication("", new char[] {});

    /**
     * @param baseURL The base URL shared by a Pipe.
     */
    public HttpBasicAuthenticationModule(URL baseURL) {
        this.baseURL = baseURL;
    }

    @Override
    public URL getBaseURL() {
        return baseURL;
    }

    @Override
    public String getLoginEndpoint() {
        return loginEndpoint;
    }

    @Override
    public String getLogoutEndpoint() {
        return logoutEndpoint;
    }

    @Override
    public String getEnrollEndpoint() {
        return enrollEndpoint;
    }

    @Override
    public boolean isLoggedIn() {
        return isLoggedIn;
    }

    /**
     * This method stores username and password. Additionally, it sets {@link #isLoggedIn} to true and calls {@link Callback#onSuccess(java.lang.Object) immediately * }.
     * 
     * @param username the username of the user
     * @param password the password of the user
     * @param callback a callback to handle the result.
     */
    @Override
    public void login(String username, String password, final Callback callback) {
        isLoggedIn = true;
        auth = new PasswordAuthentication(username, password.toCharArray());
        THREAD_POOL_EXECUTOR.execute(new Runnable() {
            @Override
            public void run() {
                callback.onSuccess(new HeaderAndBody(new byte[] {}, new HashMap(1)));
            }
        });

    }

    /**
     * 
     * This method clears the username and password from the module, sets
     * isLoggedIn to false, and removes all cookies associated with {@link #baseURL}
     * 
     * This method always calls {@link Callback#onSuccess(java.lang.Object) }
     * 
     * @param callback the callback whose onsuccess method will be executed
     */
    @Override
    public void logout(final Callback callback) {
        clearPassword(auth.getPassword());
        auth = new PasswordAuthentication("", new char[] {});
        isLoggedIn = false;

        THREAD_POOL_EXECUTOR.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    CookieStore store = ((CookieManager) CookieManager.getDefault()).getCookieStore();
                    List cookies = store.get(baseURL.toURI());

                    for (HttpCookie cookie : cookies) {
                        store.remove(baseURL.toURI(), cookie);
                    }

                    callback.onSuccess((Void) null);
                } catch (URISyntaxException e) {
                    callback.onFailure(e);
                }

            }
        });

    }

    /**
     * 
     * Enrolling is not supported using http basic.
     * 
     * This method will call {@link Callback#onFailure(java.lang.Exception)} and pass
     * it a UnsupportedOperationException.
     * 
     * @param userData this value is ignored.
     * @param callback the callback to be called
     */
    @Override
    public void enroll(Map userData, final Callback callback) {
        THREAD_POOL_EXECUTOR.execute(new Runnable() {
            @Override
            public void run() {
                callback.onFailure(new UnsupportedOperationException());
            }
        });

    }

    /**
     * HTTP Basic defines a base 64 encoded hash to be pass as a header to serve
     * as authentication. This method calculates the value of that header.
     * 
     * @return the http basic hash of the username and password
     */
    private String getHashedAuth() {
        StringBuilder headerValueBuilder = new StringBuilder(AUTHORIZATION_METHOD).append(" ");
        String unhashedCredentials = new StringBuilder(auth.getUserName()).append(":").append(auth.getPassword()).toString();
        String hashedCrentials = Base64.encodeToString(unhashedCredentials.getBytes(), Base64.DEFAULT | Base64.NO_WRAP);
        return headerValueBuilder.append(hashedCrentials).toString();
    }

    /**
     * This method replaces the characters in a character array with '0'.
     * 
     * @param password a character array, usually a password
     */
    private void clearPassword(char[] password) {
        for (int i = 0; i < password.length; i++) {
            password[i] = '0';
        }
    }

    /**
     * This will log in the user using the keys "loginName" and "password".
     * 
     */
    @Override
    public void login(Map loginData, Callback callback) {
        login(loginData.get(USERNAME_PARAMETER_NAME), loginData.get(PASSWORD_PARAMETER_NAME), callback);
    }

    @Override
    public ModuleFields loadModule(URI relativeURI, String httpMethod, byte[] requestBody) {
     
        ModuleFields fields = new ModuleFields();

        List> headerList = new ArrayList>(1);
        headerList.add(new Pair(BASIC_HEADER, getHashedAuth()));
        
        fields.setHeaders(headerList);
        
        return fields;
    }

    @Override
    public boolean handleError(HttpException exception) {
        return false;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy