Agregar encabezado para HttpURLConnection

254

Estoy tratando de agregar encabezado para mi solicitud usando HttpUrlConnectionpero el método setRequestProperty()no parece funcionar. El lado del servidor no recibe ninguna solicitud con mi encabezado.

HttpURLConnection hc;
    try {
        String authorization = "";
        URL address = new URL(url);
        hc = (HttpURLConnection) address.openConnection();


        hc.setDoOutput(true);
        hc.setDoInput(true);
        hc.setUseCaches(false);

        if (username != null && password != null) {
            authorization = username + ":" + password;
        }

        if (authorization != null) {
            byte[] encodedBytes;
            encodedBytes = Base64.encode(authorization.getBytes(), 0);
            authorization = "Basic " + encodedBytes;
            hc.setRequestProperty("Authorization", authorization);
        }
Minh-Ha Le
fuente
Funciona para mí, ¿cómo sabes que el encabezado fue enviado y no recibido?
Tomasz Nurkiewicz
1
perdón si esto suena tonto, pero ¿dónde estás llamando connect()a URLConnection?
Vikdor
No estoy seguro de si esto tiene un efecto, pero puedes intentar agregar connection.setRequestMethod("GET");(o POST o lo que quieras).
noobed
1
Inicializa authorizationa la cadena vacía. Si usernameo passwordes nulo, authorizationserá la cadena vacía, no nula. Por lo tanto, la final ifse ejecutará, pero la "Authorization"propiedad se configurará como vacía, me parece.
zerzevul

Respuestas:

422

He usado el siguiente código en el pasado y había funcionado con la autenticación básica habilitada en TomCat:

URL myURL = new URL(serviceURL);
HttpURLConnection myURLConnection = (HttpURLConnection)myURL.openConnection();

String userCredentials = "username:password";
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userCredentials.getBytes()));

myURLConnection.setRequestProperty ("Authorization", basicAuth);
myURLConnection.setRequestMethod("POST");
myURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
myURLConnection.setRequestProperty("Content-Length", "" + postData.getBytes().length);
myURLConnection.setRequestProperty("Content-Language", "en-US");
myURLConnection.setUseCaches(false);
myURLConnection.setDoInput(true);
myURLConnection.setDoOutput(true);

Puedes probar el código anterior. El código anterior es para POST, y puede modificarlo para GET

Cyril Beschi
fuente
15
Una pequeña adición para desarrolladores de Android (en API> = 8 aka 2.2): android.util.Base64.encode (userCredentials.getBytes (), Base64.DEFAULT); Base64.DEFAULT le dice que use RFC2045 para la codificación base64.
Denis Gladkiy
@ Denis, ¿podría decirme por qué debería uno usar encabezados? Tengo que validar algunas credenciales de Android. Estoy usando php en xammp. ¿Cómo debo hacerlo? como no sé cómo escribir código php con encabezados
Pankaj Nimgade
11
¿De dónde vino la variable postDataen tu ejemplo?
GlenPeterson
22
¿Por qué se les llama "RequestProperty" cuando todos los llaman encabezados?
Philip Rego
2
Una adición para la versión Java8: la clase Base64 ha cambiado un poco. La decodificación debe hacerse usando:String basicAuth = "Basic " + java.util.Base64.getEncoder().encodeToString(userCredentials.getBytes());
Mihailo Stupar
17

Solo porque no veo este bit de información en las respuestas anteriores, la razón por la que el fragmento de código publicado originalmente no funciona correctamente es porque la encodedBytesvariable es byte[]un Stringvalor y no un valor. Si pasa el byte[]a a new String()como se muestra a continuación, el fragmento de código funciona perfectamente.

encodedBytes = Base64.encode(authorization.getBytes(), 0);
authorization = "Basic " + new String(encodedBytes);
Joseph Cozad
fuente
11

Si está utilizando Java 8, use el código a continuación.

URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) connection;

String basicAuth = Base64.getEncoder().encodeToString((username+":"+password).getBytes(StandardCharsets.UTF_8));
httpConn.setRequestProperty ("Authorization", "Basic "+basicAuth);
Chandubabu
fuente
6

Finalmente esto funcionó para mí

private String buildBasicAuthorizationString(String username, String password) {

    String credentials = username + ":" + password;
    return "Basic " + new String(Base64.encode(credentials.getBytes(), Base64.DEFAULT));
}
gori
fuente
2
@ d3dave. La cadena se creó a partir de una matriz de bytes y se concatena con "Básico". El problema en el código OP era que concatenaba "Básico" con el byte [] y lo enviaba como encabezado.
yurin
5

Su código está bien. También puede usar lo mismo de esta manera.

public static String getResponseFromJsonURL(String url) {
    String jsonResponse = null;
    if (CommonUtility.isNotEmpty(url)) {
        try {
            /************** For getting response from HTTP URL start ***************/
            URL object = new URL(url);

            HttpURLConnection connection = (HttpURLConnection) object
                    .openConnection();
            // int timeOut = connection.getReadTimeout();
            connection.setReadTimeout(60 * 1000);
            connection.setConnectTimeout(60 * 1000);
            String authorization="xyz:xyz$123";
            String encodedAuth="Basic "+Base64.encode(authorization.getBytes());
            connection.setRequestProperty("Authorization", encodedAuth);
            int responseCode = connection.getResponseCode();
            //String responseMsg = connection.getResponseMessage();

            if (responseCode == 200) {
                InputStream inputStr = connection.getInputStream();
                String encoding = connection.getContentEncoding() == null ? "UTF-8"
                        : connection.getContentEncoding();
                jsonResponse = IOUtils.toString(inputStr, encoding);
                /************** For getting response from HTTP URL end ***************/

            }
        } catch (Exception e) {
            e.printStackTrace();

        }
    }
    return jsonResponse;
}

Su código de respuesta de devolución 200 si la autorización es exitosa

pintu
fuente
1

Con RestAssurd también puede hacer lo siguiente:

String path = baseApiUrl; //This is the base url of the API tested
    URL url = new URL(path);
    given(). //Rest Assured syntax 
            contentType("application/json"). //API content type
            given().header("headerName", "headerValue"). //Some API contains headers to run with the API 
            when().
            get(url).
            then().
            statusCode(200); //Assert that the response is 200 - OK
Eyal Sooliman
fuente
1
¿Te importa formatear el código aquí un poco más limpio? Además, ¿qué se given()supone que es?
Nathaniel Ford
Hola, este es el uso base de rest-Assurd (prueba de descanso de la API) Agregué explicaciones al código.
Eyal Sooliman
-1

Paso 1: obtener el objeto HttpURLConnection

URL url = new URL(urlToConnect);
HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();

Paso 2: Agregue encabezados a HttpURLConnection usando el método setRequestProperty.

Map<String, String> headers = new HashMap<>();

headers.put("X-CSRF-Token", "fetch");
headers.put("content-type", "application/json");

for (String headerKey : headers.keySet()) {
    httpUrlConnection.setRequestProperty(headerKey, headers.get(headerKey));
}

Enlace de referencia

Hari Krishna
fuente