Sunday, February 25, 2007

Accessing password protected URL

How do you access a password protected URL (requiring basic authentication) programmatically? well, there are two ways

  1. If you know that the URL is protected : This is the simple one. Since you know the URL is protected, add the required authorization header in the request and you are done. What if you are not making the socket connection but instead using java.net.URL or java.net.URLConnection to retrieve the content of url? You can use setRequestProperty() method of URLConnection to add any request header you want. So the code would look like


    URL url = new URL(someurlstring)
    URLConnection conn = url.openConnection();
    String encoding = new sun.misc.BASE64Encoder().encode("username:password".getBytes());
    conn.setRequestProperty ("Authorization", "Basic " + encoding);
    InputStream in = conn.getInputStream()
    ...


  2. What if you dont know in advance whether the URL is protected or not? You can not arbitrarily add the authorization heder for all the URLs. The answer to this is "java.net.Authenticator". You need to install an instance of java.net.Authenticator using setDefault() method of Authenticator. Whenever URLConnection sees that the url is protected, it will use this installed authenticator to get the username and password and set the required authorization header automatically.
    Here is how the code snippet for doing this


    Authenticator.setDefault(new MyAuthenticator());
    ....

    public class MyAuthenticator extends Authenticator
    {
    protected PasswordAuthentication getPasswordAuthentication()
    {
    return new PasswordAuthentication ("username", "password");
    }
    }

    This particular technique is particularly useful for people who need a workaround for retrieving password protected images in cfdocument. Here is what you need to do.

    • Use the source below to create Authenicator class

      import java.net.*;
      public class MyAuthenticator extends Authenticator
      {
      private String user;
      private String passwd;

      public MyAuthenticator(String user, String passwd)
      {
      this.user = user;
      this.passwd = passwd;
      }

      protected PasswordAuthentication getPasswordAuthentication()
      {
      return new PasswordAuthentication(user, passwd.toCharArray());
      }
      }

      Compile this and put MyAuthenticator.class in wwwroot/WEB-INF/classes.

    • Put the following code in your application.cfm or application.cfc

      <cfif not IsDefined("Application.authenticator")>
      <!--- Do initializations --->
      <cfset authenticator= createObject("java", "java.net.Authenticator")>
      <cfset myauthenticator = createObject("java", "MyAuthenticator").init("username", "password")>
      <cfset authenticator.setDefault(myauthenticator)>
      <cfset Application.authenticator=myauthenticator>
      </cfif>

      replace "username" and "password" with actual username and password.

    • give the request for the cfdocument page for which you were getting the red-x for image. The images should appear this time.

No comments: