URLs and URIs, Proxies and Passwords
Pages: 1, 2, 3, 4, 5
The PasswordAuthentication Class
PasswordAuthentication is a very simple final class that
supports two read-only properties: username and password. The
username is a String. The password is a
char array so that the password can be erased when
it's no longer needed. A String
would have to wait to be garbage collected before it could be erased,
and even then it might still exist somewhere in memory on the local
system, possibly even on disk if the block of memory that contained
it had been swapped out to virtual memory at one point. Both username
and password are set in the constructor:
public PasswordAuthentication(String userName, char[] password)
Each is accessed via a getter method:
public String getUserName( )
public char[] getPassword( )
The JPasswordField Class
One useful tool for asking users for their passwords in a more or
less secure fashion is the
JPasswordField component from Swing:
public class JPasswordField extends JTextField
This lightweight component behaves almost exactly like a text field. However, anything the user types into it is echoed as an asterisk. This way, the password is safe from anyone looking over the user's shoulder at what's being typed on the screen.
JPasswordField also stores the passwords as a
char array so that when you're
done with the password you can overwrite it with zeros. It provides
the getPassword( ) method to
return this:
public char[] getPassword( )
Otherwise, you mostly use the methods it inherits from the
JTextField superclass. Example 7-13 demonstrates a Swing-based
Authenticator subclass that brings up a dialog to
ask the user for his username and password. Most of this code handles
the GUI. A JPasswordField collects the password
and a simple JTextField retrieves the username. Figure 7-4 showed the rather simple dialog box this produces.
package com.macfaq.net;
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class DialogAuthenticator extends Authenticator {
private JDialog passwordDialog;
private JLabel mainLabel
= new JLabel("Please enter username and password: ");
private JLabel userLabel = new JLabel("Username: ");
private JLabel passwordLabel = new JLabel("Password: ");
private JTextField usernameField = new JTextField(20);
private JPasswordField passwordField = new JPasswordField(20);
private JButton okButton = new JButton("OK");
private JButton cancelButton = new JButton("Cancel");
public DialogAuthenticator( ) {
this("", new JFrame( ));
}
public DialogAuthenticator(String username) {
this(username, new JFrame( ));
}
public DialogAuthenticator(JFrame parent) {
this("", parent);
}
public DialogAuthenticator(String username, JFrame parent) {
this.passwordDialog = new JDialog(parent, true);
Container pane = passwordDialog.getContentPane( );
pane.setLayout(new GridLayout(4, 1));
pane.add(mainLabel);
JPanel p2 = new JPanel( );
p2.add(userLabel);
p2.add(usernameField);
usernameField.setText(username);
pane.add(p2);
JPanel p3 = new JPanel( );
p3.add(passwordLabel);
p3.add(passwordField);
pane.add(p3);
JPanel p4 = new JPanel( );
p4.add(okButton);
p4.add(cancelButton);
pane.add(p4);
passwordDialog.pack( );
ActionListener al = new OKResponse( );
okButton.addActionListener(al);
usernameField.addActionListener(al);
passwordField.addActionListener(al);
cancelButton.addActionListener(new CancelResponse( ));
}
private void show( ) {
String prompt = this.getRequestingPrompt( );
if (prompt == null) {
String site = this.getRequestingSite( ).getHostName( );
String protocol = this.getRequestingProtocol( );
int port = this.getRequestingPort( );
if (site != null & protocol != null) {
prompt = protocol + "://" + site;
if (port > 0) prompt += ":" + port;
}
else {
prompt = "";
}
}
mainLabel.setText("Please enter username and password for "
+ prompt + ": ");
passwordDialog.pack( );
passwordDialog.show( );
}
PasswordAuthentication response = null;
class OKResponse implements ActionListener {
public void actionPerformed(ActionEvent e) {
passwordDialog.hide( );
// The password is returned as an array of
// chars for security reasons.
char[] password = passwordField.getPassword( );
String username = usernameField.getText( );
// Erase the password in case this is used again.
passwordField.setText("");
response = new PasswordAuthentication(username, password);
}
}
class CancelResponse implements ActionListener {
public void actionPerformed(ActionEvent e) {
passwordDialog.hide( );
// Erase the password in case this is used again.
passwordField.setText("");
response = null;
}
}
public PasswordAuthentication getPasswordAuthentication( ) {
this.show( );
return this.response;
}
}
Example 7-14 is a revised
SourceViewer program that asks the user for a name
and password using the DialogAuthenticator class.
import java.net.*;
import java.io.*;
import com.macfaq.net.DialogAuthenticator;
public class SecureSourceViewer {
public static void main (String args[]) {
Authenticator.setDefault(new DialogAuthenticator( ));
for (int i = 0; i < args.length; i++) {
try {
//Open the URL for reading
URL u = new URL(args[i]);
InputStream in = u.openStream( );
// buffer the input to increase performance
in = new BufferedInputStream(in);
// chain the InputStream to a Reader
Reader r = new InputStreamReader(in);
int c;
while ((c = r.read( )) != -1) {
System.out.print((char) c);
}
}
catch (MalformedURLException ex) {
System.err.println(args[0] + " is not a parseable URL");
}
catch (IOException ex) {
System.err.println(ex);
}
// print a blank line to separate pages
System.out.println( );
} // end for
// Since we used the AWT, we have to explicitly exit.
System.exit(0);
} // end main
} // end SecureSourceViewer
Elliotte Rusty Harold is a noted writer and programmer, both on and off the Internet. His previous books include "Java Network Programming", Third Edition, "XML in a Nutshell", Third Edition, and "Java I/O", all from O'Reilly.
View catalog information for Java Network Programming, 3rd Edition
Return to ONJava.com.