Rectangle 27 109

You can set the default authenticator for http requests like this:

Authenticator.setDefault (new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication ("username", "password".toCharArray());
    }
});

Also, if you require more flexibility, you can check out the Apache HttpClient, which will give you more authentication options (as well as session support, etc.)

How do you handle a bad authentication event? [For example, if the user supplies username and password authentication credentials that don't match anything]?

The above code works but is quite implicit as to whats going on. There's subclassing and method overriding going on there, dig into the docs for those classes if you care to know what's going on. The code here is more explicit javacodegeeks

Authenticator
URL.openConnection()

@Yura: no. It's got to be global. You can, however, do evil things such as setting a global authenticator which pulls the credentials out of thread-local variables, and set the credentials per thread before making the HTTP connection.

httpurlconnection - Connecting to remote URL which requires authentica...

java httpurlconnection
Rectangle 27 88

There's a native and less intrusive alternative, which works only for your call.

URL url = new URL(location address);
URLConnection uc = url.openConnection();
String userpass = username + ":" + password;
String basicAuth = "Basic " + new String(new Base64().encode(userpass.getBytes()));
uc.setRequestProperty ("Authorization", basicAuth);
InputStream in = uc.getInputStream();

The Base64 class can be provided by Apache Commons Codec.

Didn't work for me this way... Only the way that @James Van Huis was good

It's 'native' on Grails and many other Java frameworks because them all use Apache Commons Libs.

Does not work in general unless you .trim() the result, or call a method variant that does not produce chunked output. javax.xml.bind.DatatypeConverter seems safer.

httpurlconnection - Connecting to remote URL which requires authentica...

java httpurlconnection
Rectangle 27 60

You can also use the following, which does not require using external packages:

URL url = new URL(location address);
URLConnection uc = url.openConnection();

String userpass = username + ":" + password;
String basicAuth = "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(userpass.getBytes());

uc.setRequestProperty ("Authorization", basicAuth);
InputStream in = uc.getInputStream();

Thanks for the pointer to a 'native' Base64 encoder!

httpurlconnection - Connecting to remote URL which requires authentica...

java httpurlconnection
Rectangle 27 29

If you are using the normal login whilst entering the username and password between the protocol and the domain this is simpler. It also works with and without login.

URL url = new URL("http://user:pass@domain.com/url");
URLConnection urlConnection = url.openConnection();

if (url.getUserInfo() != null) {
    String basicAuth = "Basic " + new String(new Base64().encode(url.getUserInfo().getBytes()));
    urlConnection.setRequestProperty("Authorization", basicAuth);
}

InputStream inputStream = urlConnection.getInputStream();

This was exactly what I've been searching for the past 30 minutes. Thanks a lot!

Does not work if pass contains a #

If your username/password contain special characters, I believe you would need to urlencode those. Then, in the snippet of code above, you would pass url.getUserInfo() thorugh URLDecoder.decode() first (@Peter Rader).

httpurlconnection - Connecting to remote URL which requires authentica...

java httpurlconnection
Rectangle 27 7

As i have came here looking for an Android-Java-Answer i am going to do a short summary:

  • Use basic java.net.URLConnection and set the Authentication-Header manually like shown here

If you want to use java.net.URLConnection with Basic Authentication in Android try this code:

URL url = new URL("http://www.mywebsite.com/resource");
URLConnection urlConnection = url.openConnection();
String header = "Basic " + new String(android.util.Base64.encode("user:pass".getBytes(), android.util.Base64.NO_WRAP));
urlConnection.addRequestProperty("Authorization", header);
// go on setting more request headers, reading the response, etc

httpurlconnection - Connecting to remote URL which requires authentica...

java httpurlconnection
Rectangle 27 3

Be really careful with the "Base64().encode()"approach, my team and I got 400 Apache bad request issues because it adds a \r\n at the end of the string generated.

Here is our solution :

import org.apache.commons.codec.binary.Base64;

HttpGet getRequest = new HttpGet(endpoint);
getRequest.addHeader("Authorization", "Basic " + getBasicAuthenticationEncoding());

private String getBasicAuthenticationEncoding() {

        String userPassword = username + ":" + password;
        return new String(Base64.encodeBase64(userPassword.getBytes()));
    }

httpurlconnection - Connecting to remote URL which requires authentica...

java httpurlconnection
Rectangle 27 1

URL url = new URL(path);
String userPass = "username:password";
String basicAuth = "Basic " + Base64.encodeToString(userPass.getBytes(), Base64.DEFAULT);//or
//String basicAuth = "Basic " + new String(Base64.encode(userPass.getBytes(), Base64.No_WRAP));
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestProperty("Authorization", basicAuth);
urlConnection.connect();

httpurlconnection - Connecting to remote URL which requires authentica...

java httpurlconnection
Rectangle 27 0

A while back when i had this problem, i ended up using a scheme created by somebody else.

Worked for me when i had to get image files from and iis server with ntlm. Snippet using the code above..

AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, org.xyz.JCIFS_NTLMScheme.class);
            HttpClient client = new HttpClient();
            client.getState().setCredentials(AuthScope.ANY, new NTCredentials(userName, password, "", strDomain));
            GetMethod get = new GetMethod(strImageFile);
            get.setDoAuthentication(true);
            client.executeMethod(get);

Thanks for the response. This looks like it has potential, however, it does require an additional library outside of Java 6; which is what I was trying to work within. The blog also references relaxing the session security attribute to ensure the solution works, which would not work for my scenario. If I get some time to test I will post back. I would vote this up, but I don't have enough rep points :(

iis 6 - Java 6 HTTPURLConnection and Project Server NTLM Authenticatio...

java iis-6 httpurlconnection ntlm project-server
Rectangle 27 0

Be really careful with the "Base64().encode()"approach, my team and I got 400 Apache bad request issues because it adds a \r\n at the end of the string generated.

Here is our solution :

import org.apache.commons.codec.binary.Base64;

HttpGet getRequest = new HttpGet(endpoint);
getRequest.addHeader("Authorization", "Basic " + getBasicAuthenticationEncoding());

private String getBasicAuthenticationEncoding() {

        String userPassword = username + ":" + password;
        return new String(Base64.encodeBase64(userPassword.getBytes()));
    }

httpurlconnection - Connecting to remote URL which requires authentica...

java httpurlconnection
Rectangle 27 0

I'm having the same issue, but my target build level is 19. Does this work for you on 19?

java - Android 4.3 HTTPUrlConnection + Basic Auth - No authentication ...

java android httpurlconnection basic-authentication android-4.3-jelly-bean
Rectangle 27 0

HttpUrlConnection is OK for simple jobs, but if you want something with more advanced features (like digest authentication), I'd recommend Commons HTTP Client.

java - HTTP digest authentication with HttpUrlConnection - Stack Overf...

java
Rectangle 27 0

Use the following code, it works.

import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;

CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
                new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
                new UsernamePasswordCredentials(username, password));
        CloseableHttpClient httpclient = HttpClients.custom()
                .setDefaultCredentialsProvider(credsProvider)
                .build();


HttpResponse response = httpClient.execute(get);

java - HTTP digest authentication with HttpUrlConnection - Stack Overf...

java
Rectangle 27 0

The answer is, that HttpUrlConnection does not support digest.

You therefore have to implement RFC2617 by yourself.

You can use the following code as a baseline implementation: HTTP Digest Auth for Android.

WWW-Authenticate
  • Check if algorithm is MD5 or undefined, (optionally select the auth qop option), otherwise ignore the challenge and go to the next header.
Authenticator.requestPasswordAuthentication
  • Calculate H(A1) using the username, realm and password.
  • Store the canonical root URL, realm, HA1, username, nonce (+ optionally algorithm, opaque and the client selected qop option if present).
  • Calculate H(A2) using the request method and path.
  • Calculate H(A3) using HA1, nonce (+ optionally nc, cnonce, qop) and HA2.
Authorization
HttpUrlConnection

By using Authenticator, you can make sure, that as soon as HttpUrlConnection supports digest natively, your code is not being used anymore (because you wont receive the 401 in the first place).

This is just a quick summary on how to implement it, for you to get an idea.

If you want to go further you would probably like to implement SHA256 as well: RFC7616

Thanks for that answer. Is it only the Androids version of HttpUrlConnection, which does not support digest or also the default java.net.HttpURLConnection?

@Springrbua Only on Android its not supported, at least to my knowledge. Maybe you will find sources for the JDK implementation.

Okay thanks for your answer. I'll stick with the DefaultHttpClient for now, but it seems like i need to switch sooner or later so i'll have to implement digest myself. Thanks!

java - Digest authentication in Android using HttpURLConnection - Stac...

java android httpurlconnection digest-authentication
Rectangle 27 0

I finally replaced the deprecated DefaultHttpClient with my own implementation of the HttpUrlConnection and I implemented digest atuhentication myself, using this as a template. The finaly code looks something like this:

// requestMethod: "GET", "POST", "PUT" etc.
// Headers: A map with the HTTP-Headers for the request
// Data: Body-Data for Post/Put
int statusCode = this.requestImpl(requestMethod, headers, data);
if (statusCode == HttpURLConnection.HTTP_UNAUTHORIZED && hasUserNameAndPassword) {
    String auth = getResponseHeaderField("WWW-Authenticate");
    // Server needs Digest authetication
    if(auth.startsWith("Digest")){
          // Parse the auth Header
          HashMap<String, String> authFields = parseWWWAuthenticateHeader(auth);
          // Generate Auth-Value for request
          String requestAuth = generateDigestAuth(authFields);
          headers.put("Authorization", authStr);
          statusCode = this.requestImpl(requestMethod, headers, data);
    }
}

So basicly I make a request and if it returns 401, I look, if the server wants digest authentication and if I have username and password. If thats the case, I parse the auth header of the response, which contains all the necessary informations about the authentication. To parse the auth header I use some kind of StateMachine which is described here. After parsing the response auth header, I generate the request auth header using the informations from the response:

String digestAuthStr = null;

    String uri = getURL().getPath();
    String nonce = authFields.get("nonce");
    String realm = authFields.get("realm");
    String qop = authFields.get("qop");
    String algorithm = authFields.get("algorithm");
    String cnonce = generateCNonce();
    String nc = "1";
    String ha1 = toMD5DigestString(concatWithSeparator(":", username, realm, password));
    String ha2 = toMD5DigestString(concatWithSeparator(":", requestMethod, uri));
    String response = null;
    if (!TextUtils.isEmpty(ha1) && !TextUtils.isEmpty(ha2))
        response = toMD5DigestString(concatWithSeparator(":", ha1, nonce, nc, cnonce, qop, ha2));

    if (response != null) {
        StringBuilder sb = new StringBuilder(128);
        sb.append("Digest ");
        sb.append("username").append("=\"").append(username).append("\", ");
        sb.append("realm").append("=\"").append(realm).append("\", ");
        sb.append("nonce").append("=\"").append(nonce).append("\", ");
        sb.append("uri").append("=\"").append(uri).append("\", ");
        sb.append("qop").append("=\"").append(qop).append("\", ");
        sb.append("nc").append("=\"").append(nc).append("\", ");
        sb.append("cnonce").append("=\"").append(cnonce).append("\"");
        sb.append("response").append("=\"").append(response).append("\"");
        sb.append("algorithm").append("=\"").append(algorithm).append("\"");
        digestAuthStr = sb.toString();
    }

To generate the Client-Nonce I am using the following code:

private static String generateCNonce() {
    String s = "";
    for (int i = 0; i < 8; i++)
        s += Integer.toHexString(new Random().nextInt(16));
    return s;
}

I hope this helps someone. If the code contains any errors, please let me know so I can fix it. But right now it seems to work.

This is a very compact and efficient digest implementation, but it is good to be aware of that it only implements a small subset of digest. This is fine if you, for instance, only work with one particular server and can test with that. If you need to be compatible with many different servers and handle things like multiple challenges, escaped characters in quoted strings, SHA-256 digest, the opaque directive, reusing challenges, etc, then you are probably better of to use one of the libraries (bare-bones-digest, okhtt-digest, Apache HttpClient, etc) to cover the corner cases.

@user829876 I totaly agree with you. If you need full support of digest you should definitely go with a known and therefore tested library.

java - Digest authentication in Android using HttpURLConnection - Stac...

java android httpurlconnection digest-authentication
Rectangle 27 0

Digest authentication is far more complex than just sending username:password (that is actually Basic authentication... and the username:password tuple needs to be Base64 encoded!).

You can read all about digest here.

HttpUrlConnection

Both of them already support Digest (and other useful stuff) out of the box.

java - HTTP digest authentication with HttpUrlConnection - Stack Overf...

java
Rectangle 27 0

The problem was solved by raising the build target to API Level 18

I'm having the same issue, but my target build level is 19. Does this work for you on 19?

java - Android 4.3 HTTPUrlConnection + Basic Auth - No authentication ...

java android httpurlconnection basic-authentication android-4.3-jelly-bean
Rectangle 27 0

It is correct that HttpUrlConnection does not support Digest authentication. If your client must authenticate using Digest, you have a few options:

  • Write your own HTTP Digest implementation. This can be a good option if you know which servers that you need to authenticate with and can ignore the parts of the the digest specification that you do not need. Here is an example where a subset of digest is implemented: https://gist.github.com/slightfoot/5624590.
  • Use the external lib bare-bones-digest, which is a Digest lib for Android. You can use it to parse Digest challenges and generate responses to them. It supports the common digest use cases and some of the rarely used ones and can be used on top of HttpURLConnection.
  • Use OkHttp together with okhttp-digest, which is a plugin that adds Http Digest support to OkHttp. Supporting Digest with OkHttp is easy, just add okhttp-digest as an authenticator and you will have transparent Http digest support. If you already use OkHttp or are OK with switching to it this can be an attractive option.
  • Use the Apache HttpClient which supports Digest. The question explicitly states that HttpClient is not an option so I include it mostly for completion's sake. Google does not recommend using HttpClient and has deprecated it.

I replaced the DefaultHttpClient with the HttpUrlConnection a few months ago and I implemented Digest authentication mayself, using (this)[gist.github.com/slightfoot/5624590] as a template. I might add my code as an answer to, it might help someone else!

java - Digest authentication in Android using HttpURLConnection - Stac...

java android httpurlconnection digest-authentication
Rectangle 27 0

jdk.http.auth.tunneling.disabledSchemes = ""

java - HttpUrlConnection proxy authentication gets into redirect loop ...

java authentication proxy httpurlconnection basic-authentication
Rectangle 27 0

Sets the timeout value in milliseconds for establishing the connection to the resource pointed by this URLConnection instance. A SocketTimeoutException is thrown if the connection could not be established in this time. Default is 0 which stands for an infinite timeout.

httpConnection.setConnectTimeout(10000); /* connection timeout set to 10s */

yes, tried it but there is no difference..:( I can show Mjpeg fle but cant send a link:(( after tried connection with httpget-defaulthttpclent, and it works. What are there different between them??

Different implementations leads to different behaviours :) Maybe connection timeout and read timeout (setReadTimeout) should be set in order to handle the case when the server accepts the connection but does not answer to the request.

java - Authentication Problem..!! ON ANDROID WITH HTTPURLCONNECTION - ...

java android http http-status-codes
Rectangle 27 0

"user:pass"

Already with spaces, update question and remove them

This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post.

@KhaledLela Hmm, to make it really similar to the second code snippet you want USER+":"+PASS. I tried your fixed code snippet (spaces removed) with http ://httpbin.org/basic-auth/user/pass and it works fine for me.

@HansKratz The problem with digest authentication , I think that work with basic authentication.

java - Android HttpUrlConnection doesn't support digest authentication...

java android caching httpclient httpurlconnection