views:

55

answers:

1

Hi! the app i am currently building needs to perform a login with username and password. I am using the DefaultHttpClient to execute the request and setting the username and password as credentials. the server expects a htacces-login. The Result i get is not the Logintoken i hoped for. Instead it returns an Errormessage. Can anybody tell me where i went wrong in my Code? Thank you so much for your help! pr

private String httpLoginRequest() {
    String loginToken = null;
    String loginUrl = "https://somedomain.com/login";

    DefaultHttpClient client = new DefaultHttpClient();
    client.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), new UsernamePasswordCredentials("username", "password"));
    HttpResponse httpResponse;
    HttpEntity entity;
    try{
        httpResponse = client.execute(request);
        entity = httpResponse.getEntity();
        if (entity != null) {
            InputStream instream = entity.getContent();
            loginToken = convertInputStreamToString(instream);
        }
    } catch (ClientProtocolException e) {
        client.getConnectionManager().shutdown();
        e.printStackTrace();
    } catch (IOException e) {
        client.getConnectionManager().shutdown();
        e.printStackTrace();
    }
    return loginToken;
}

Thank you guys so much for your help. I finally figured it out. It was a mix of different things: 1. what you cant see in the code above (because i removed it by accident) is that the request is post. our api expects a get request though i was told otherwise 2. i put the credentials in the wrong place. they have to be set in the HttpGet-Object as in the Exampe given by CommonsWare 3. i actually do have to encode the credentials with base64 mentioned by you

here is the code that finally worked for me:

public String httpLoginRequest() {
    String loginToken = null;
    String loginUrl = "https://somedomain.com/login";
    //
    DefaultHttpClient client = new DefaultHttpClient();
    HttpResponse httpResponse;
    HttpEntity entity;
    HttpGet request = new HttpGet(loginUrl);
    request.addHeader("Authorization", "Basic " + Base64.encodeCredentials("username", "password"));
    try{
        httpResponse = client.execute(request);
        entity = httpResponse.getEntity();
        if (entity != null) {
            InputStream instream = entity.getContent();
            loginToken = convertInputStreamToString(instream);
            Log.d(LOG_TAG, "Login Token: " + loginToken);
        }
    } catch (ClientProtocolException e) {
        client.getConnectionManager().shutdown();
        e.printStackTrace();
    } catch (IOException e) {
        client.getConnectionManager().shutdown();
        e.printStackTrace();
    }
    return loginToken;
}

When i find the time i will try the example given in the answer as i looks a lot more like what i will need for some other requests in my project.

A: 

As far as I know you need to rewrite the HostnameVerifier to always return true:

public class MyHostnameVerifier implements HostnameVerifier {
    @Override
    public boolean verify(String hostname, SSLSession session) {
    return true;
    }
}

I use the HttpsURLConnection method. Therefore you need to create your own Base64 class for the authentication encryption and your own trust manager

//kObjects 
//
// Copyright (C) 2001 Stefan Haustein, Oberhausen (Rhld.), Germany
//
// Contributors: 
//
// License: LGPL
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either version 2.1 of
// the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA

import java.io.*;

/*
 * You can now use also javax.mail.internet.MimeUtility
 * and sun.misc.BASE64Encoder.encode.
 * There is a non-public class in Java 1.4+ called java.util.prefs.Base64
 */
public class MyBase64 {

    static final char[] charTab = 
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray (); 


    public static String encode (byte [] data) {
        return encode (data, 0, data.length, null).toString ();
    }


    /** Encodes the part of the given byte array denoted by start and
        len to the Base64 format.  The encoded data is appended to the
        given StringBuffer. If no StringBuffer is given, a new one is
        created automatically. The StringBuffer is the return value of
        this method. */


    public static StringBuffer encode (byte [] data, int start, int len, StringBuffer buf) {

        if (buf == null) 
            buf = new StringBuffer (data.length * 3 / 2);

        int end = len - 3;
        int i = start;
        int n = 0;

        while (i <= end) {
            int d = (((data [i]) & 0x0ff) << 16) 
                | (((data [i+1]) & 0x0ff) << 8)
                | ((data [i+2]) & 0x0ff);

            buf.append (charTab [(d >> 18) & 63]);
            buf.append (charTab [(d >> 12) & 63]);
            buf.append (charTab [(d >> 6) & 63]);
            buf.append (charTab [d & 63]);

            i += 3;

            if (n++ >= 14) {
                n = 0;
                buf.append ("\r\n");
            }
        }


        if (i == start + len - 2) {
            int d = (((data [i]) & 0x0ff) << 16) 
                | (((data [i+1]) & 255) << 8);

            buf.append (charTab [(d >> 18) & 63]);
            buf.append (charTab [(d >> 12) & 63]);
            buf.append (charTab [(d >> 6) & 63]);
            buf.append ("=");
        }
        else if (i == start + len - 1) {
            int d = ((data [i]) & 0x0ff) << 16;

            buf.append (charTab [(d >> 18) & 63]);
            buf.append (charTab [(d >> 12) & 63]);
            buf.append ("==");
        }

        return buf;
    }


    static int decode (char c) {
        if (c >= 'A' && c <= 'Z') 
            return c - 65;
        else if (c >= 'a' && c <= 'z') 
            return c - 97 + 26;
        else if (c >= '0' && c <= '9')
            return c - 48 + 26 + 26;
        else switch (c) {
        case '+': return 62;
        case '/': return 63;
        case '=': return 0;
        default:
            throw new RuntimeException (new StringBuffer("unexpected code: ").append(c).toString());
        }
    }


    /** Decodes the given Base64 encoded String to a new byte array. 
        The byte array holding the decoded data is returned. */


    public static byte [] decode (String s) {

        int i = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream ();
        int len = s.length ();

        while (true) { 
            while (i < len && s.charAt (i) <= ' ') i++;

            if (i == len) break;

            int tri = (decode (s.charAt (i)) << 18)
                + (decode (s.charAt (i+1)) << 12)
                + (decode (s.charAt (i+2)) << 6)
                + (decode (s.charAt (i+3)));

            bos.write ((tri >> 16) & 255);
            if (s.charAt (i+2) == '=') break;
            bos.write ((tri >> 8) & 255);
            if (s.charAt (i+3) == '=') break;
            bos.write (tri & 255);

            i += 4;
        }
        return bos.toByteArray ();
    }

   /**
    * java org.xmlBlaster.util.Base64 HelloWorld
    * java org.xmlBlaster.util.Base64 -decode Q2lBOGEyVjVJRzlwWkQwblNHVnNiRzhuSUdOdmJuUmxiblJOYVcxbFBTZDBaWGgwTDNodGJDY2dZMjl1ZEdWdWRFMXBiV1ZGZUhSbGJtUmxaRDBuTVM0d0p6NEtJQ0E4YjNKbkxuaHRiRUpzWVhOMFpYSStQR1JsYlc4dE16NDhMMlJsYlc4dE16NDhMMjl5Wnk1NGJXeENiR0Z6ZEdWeVBnb2dQQzlyWlhrKw==
    */
   public static void main(String[] args) {
      if (args.length == 2) {
         if (args[0].equals("-decode")) {
            String base64 = args[1];
            byte[] back = MyBase64.decode(base64);
            System.out.println("Decoded to '" + new String(back) + "'");
            return;
         }
      }
      {
         String hello = args.length > 0 ? args[0] : "Hello World";
         String base64 = MyBase64.encode(hello.getBytes());
         byte[] back = MyBase64.decode(base64);
         System.out.println("Before Base64 '" + hello + "' base64='" + (new String(base64)) + "' after '" + new String(back) + "'");
      }
   }
}

and

public class MyTrustManager implements X509TrustManager {

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) {
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) {
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}

After that you should be ready to go:

/*
 * Return the string from a authenticated SSL secured webserver call
 * */
public String sendHTTPSPostMessage(String userName, String userPass, String url, String[] postVars) throws NoSuchAlgorithmException, KeyManagementException, MalformedURLException, IOException {
    StringBuffer sb = new StringBuffer();

    final String serverAuth = userName + ":" + userPass;
    final String serverAuthBase64 = MyBase64.encode(serverAuth.getBytes());

    SSLContext sc = SSLContext.getInstance("TLS");
    sc.init(null, new TrustManager[] { new MyTrustManager() }, new SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    HttpsURLConnection.setDefaultHostnameVerifier(new MyHostnameVerifier());
    HttpsURLConnection con = (HttpsURLConnection) new URL(url).openConnection();

    try {
        StringBuffer urlParameters = new StringBuffer();
        String[] tmpPair = null;

        for (int i = 0; i < postVars.length; i++) {
            tmpPair = postVars[i].toString().split("=");

            if (i > 0)
                urlParameters.append("&" + tmpPair[0] + "=" + URLEncoder.encode(tmpPair[1], "UTF-8"));
            else
                urlParameters.append(tmpPair[0] + "=" + URLEncoder.encode(tmpPair[1], "UTF-8"));
        }

        con.setRequestMethod("POST");
        con.setRequestProperty("Authorization", "Basic " + serverAuthBase64);
        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        con.setRequestProperty("Content-Length", "" + Integer.toString(urlParameters.toString().getBytes().length));
        con.setUseCaches(false);
        con.setDoOutput(true);
        con.setDoInput(true);

        DataOutputStream wr = new DataOutputStream (con.getOutputStream());
        wr.writeBytes (urlParameters.toString());
        wr.flush();
        wr.close();

        BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()), 8192 );
        String line;
        while ( ( line = br.readLine() ) != null ) {
                sb.append(line);
        }
    }
    catch(Exception e) {
        Log.e("sendHTTPSPostMessage", e.getLocalizedMessage());
    }
    finally {
        if(con != null) {
            con.disconnect(); 
        }
    }
    return sb.toString();
}
Sotapanna