Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8156736

java.net.Authenticator will retry the request many times if 401 is received(BASIC Authentication)

XMLWordPrintable

    • generic
    • generic

      FULL PRODUCT VERSION :
      java version "1.7.0_79"
      Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
      Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.3.9600]

      A DESCRIPTION OF THE PROBLEM :
      If you try to connect to a secured web service for example which is protected by BASIC authentication and you use Authenticator with PasswordAuthentication and you provide an incorrect password for example, then the application will retry (20 times for example) to submit the same username and password.




      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Create a custom Authenticator:
      /////////////////////////////////////////////////////////////////
      package com.vvirlan.jaxrsclient;

      import java.net.Authenticator;
      import java.net.PasswordAuthentication;

      public class SimpleAuthenticator extends Authenticator {

      private String username, password;

      public SimpleAuthenticator(String username, String password) {
      this.username = username;
      this.password = password;
      }

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

      2. Write a simple Client
      /////////////////////////////////////////////////////////////////

      package com.vvirlan.jaxrsclient;

      import java.io.BufferedReader;
      import java.io.IOException;
      import java.io.InputStreamReader;
      import java.io.OutputStream;
      import java.io.OutputStreamWriter;
      import java.net.Authenticator;
      import java.net.URL;
      import java.net.URLConnection;

      public class URLConnectionWriter {

      public static void main(String[] args) throws IOException {
      String username = "acv";
      String password = "acv2"; //THIS IS THE WRONG PASSWORD

      Authenticator.setDefault(new SimpleAuthenticator(username, password));
      URL url = new URL("http://localhost:8080/JaxRsSimpleServer/rest/one/hi");
      URLConnection conn = url.openConnection();
      conn.setDoOutput(true);

      OutputStream outStream = conn.getOutputStream();
      OutputStreamWriter writer = new OutputStreamWriter(outStream);
      writer.write("p1=Hello");
      writer.close();
      outStream.close();
      BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
      String response;
      while ((response = in.readLine()) != null) {
      System.out.println("RESPONSEL: " + response);
      }
      in.close();
      }
      }

      3. Expose a service with web.xml like:

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
               http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
      version="3.1">


      <security-role>
      <role-name>user</role-name>
      </security-role>


      <security-constraint>
      <web-resource-collection>
      <web-resource-name>myrest</web-resource-name>
      <url-pattern>/rest/one/*</url-pattern>
      </web-resource-collection>
      <auth-constraint>
      <role-name>USER</role-name>
      </auth-constraint>
      </security-constraint>

      <login-config>
      <auth-method>BASIC</auth-method>
      <realm-name>file</realm-name>
      </login-config>
      </web-app>

      4. Define the realm called file with the username acv and password acv in your server (I used Glassfish).

      5. Try all this.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Application to fail on the first 401 response encountered.
      ACTUAL -
      the application will retry (20 times for example) to submit the same username and password.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Exception in thread "main" java.net.ProtocolException: Server redirected too many times (20)
      at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1637)
      at com.vvirlan.jaxrsclient.URLConnectionWriter.main(URLConnectionWriter.java:28)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      1. Create a custom Authenticator:
      /////////////////////////////////////////////////////////////////
      public class SimpleAuthenticator extends Authenticator {
      private String username, password;
      public SimpleAuthenticator(String username, String password) {
      this.username = username;
      this.password = password;
      }
      protected PasswordAuthentication getPasswordAuthentication() {
      return new PasswordAuthentication(username, password.toCharArray());
      }
      }

      2. Write a simple Client
      /////////////////////////////////////////////////////////////////
      public class URLConnectionWriter {

      public static void main(String[] args) throws IOException {
      String username = "acv";
      String password = "acv2"; //THIS IS THE WRONG PASSWORD

      Authenticator.setDefault(new SimpleAuthenticator(username, password));
      URL url = new URL("http://localhost:8080/JaxRsSimpleServer/rest/one/hi");
      URLConnection conn = url.openConnection();
      conn.setDoOutput(true);

      OutputStream outStream = conn.getOutputStream();
      OutputStreamWriter writer = new OutputStreamWriter(outStream);
      writer.write("p1=Hello");
      writer.close();
      outStream.close();
      BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
      String response;
      while ((response = in.readLine()) != null) {
      System.out.println("RESPONSEL: " + response);
      }
      in.close();
      }
      }

      3. Expose a service with web.xml like:

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
               http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
      version="3.1">

      <security-role>
      <role-name>user</role-name>
      </security-role>


      <security-constraint>
      <web-resource-collection>
      <web-resource-name>myrest</web-resource-name>
      <url-pattern>/rest/one/*</url-pattern>
      </web-resource-collection>
      <auth-constraint>
      <role-name>USER</role-name>
      </auth-constraint>
      </security-constraint>

      <login-config>
      <auth-method>BASIC</auth-method>
      <realm-name>file</realm-name>
      </login-config>
      </web-app>

      4. Define the realm called file with the username acv and password acv in your server (I used Glassfish).

      5. Try all this.

      ---------- END SOURCE ----------

            jboes Julia Boes (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: