proxyauthenticator.java

来自「MyUploader 是一款使用 http 协议(RFC 1867)用于上传文件」· Java 代码 · 共 202 行

JAVA
202
字号
/*
 * Copyright 2006-2007 JavaAtWork All rights reserved.
 * Use is subject to license terms.
 */
package javaatwork.myuploader.net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.PasswordAuthentication;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;

import javaatwork.myuploader.dialog.ProxyLoginDialog;
import javaatwork.myuploader.utils.LocaleManager;
import javaatwork.myuploader.utils.Logger;

import javax.swing.JOptionPane;

/**
 * Responsible for determing the proxy authentication data.
 * 
 * @author Johannes Postma
 */
public class ProxyAuthenticator {

	private URL uploadURL = null;
	private ProxyLoginDialog loginDialog = null;
	private PasswordAuthentication passwordAuthentication = null;
	private String proxy = null;
	private LocaleManager localeManager = null;
	
	/**
	 * Creates a new ProxyAuthenticator.
	 * 
	 * @param proxyLoginDialog The ProxyLoginDialog.
	 * @param url The uploadURL.
	 */
	public ProxyAuthenticator(ProxyLoginDialog proxyLoginDialog, URL url) {
		
		this.uploadURL = url;	
		loginDialog = proxyLoginDialog;
		localeManager = LocaleManager.getInstance();
	}

	/**
	 * Returns the PasswordAuthentication.
	 * 
	 * @return The PasswordAuthentication. 
	 * @throws ProxyAuthenticatorException If an error occurred.
	 */
	public PasswordAuthentication getPasswordAuthentication() throws ProxyAuthenticatorException  {
		
		NetUtils netUtils = new NetUtils();
		proxy = netUtils.detectProxyForUrl(uploadURL);
				
		if (proxy == null) {
			return null;
		} else {
		
			if(authenticate(null, false)) {
				return passwordAuthentication;
			} else {
				return null;
			}			
		}
	}

	/**
	 * True if the user is authenticated or authenticated is not needed.
	 * 
	 * @param passwordAuthentication The PasswordAuthentication.
	 * @param loginIncorrect Needed for defining the title of the logindialog.
	 * @return True if the user is authenticated or authenticated is not needed.
	 * @throws ProxyAuthenticatorException If an error occurred
	 */
	public boolean authenticate(PasswordAuthentication passwordAuthentication, boolean loginIncorrect) throws ProxyAuthenticatorException {
		
		this.passwordAuthentication = passwordAuthentication; 
		
		boolean showLoginDialog = false; 
		boolean retrieveRealm = false; 
		boolean statusLine = true;
		String line = null;	// a single line of the response		
		String realm = null; // the realm in case authentication is needed
		Socket socket = null;
		String host = null;
		String port = null;
		
		try {
		
			// creates the (proxy)socket
			host = proxy.substring(0, proxy.indexOf(":"));
			port = proxy.substring(proxy.indexOf(":") + 1);
			socket = new Socket(host, Integer.parseInt(port));
			
			// creates the streams
			BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
		
			// creates the request
			out.write("HEAD " + uploadURL.toString() + " HTTP/1.1\r\n");
			out.write("Host: " + uploadURL.getHost() + "\r\n");
		
			if (passwordAuthentication != null) {
				
				String loginData = new sun.misc.BASE64Encoder().encode ((passwordAuthentication.getUserName() + ":" + new String(passwordAuthentication.getPassword())).getBytes());
				
				out.write("Proxy-Authorization: Basic " + loginData + "\r\n");
			}
		
			out.write("\r\n");
			out.flush();
		
			// parse the response
			while (!(line = in.readLine()).equals("")) {
	
				if (statusLine) {
					if (line.indexOf("407") > -1) {
						retrieveRealm = true;
						statusLine = false;
					
					}
				} else if (retrieveRealm) {
	
					// retrieve realm
					if (line.toLowerCase().startsWith("proxy-authenticate")) {
	
						String value = line.substring("proxy-authenticate:".length()).trim();
	
						// check kind of authorisation only basic authentication is implemented
						if (!value.toLowerCase().startsWith("basic")) {
							
							// log
							Logger.log("ProxyAuthenticator", "authenticate()", "Only basic authentication is supported.");
							throw new ProxyAuthenticatorException(localeManager.getString("basic_proxy_authentication"));
							
						} else {
							realm = value.substring(value.indexOf("\"") + 1, value.lastIndexOf("\""));						
						}
					}
				
					showLoginDialog = true;
				}	
			}
	
		} catch (NumberFormatException e) {
			
			// log
			Logger.log("ProxyAuthenticator", "authenticate()", "Port must be numeric: " + port);
			throw new ProxyAuthenticatorException(localeManager.getString("uploadurl"));
			
		} catch (UnknownHostException e) {
			
			// log
			Logger.log("ProxyAuthenticator", "authenticate()", "Unkown host: " + host);
			throw new ProxyAuthenticatorException(localeManager.getString("unkown_host"));
			
		} catch (IOException e) {
			
			// log
			Logger.log("ProxyAuthenticator", "authenticate()", e.toString());
			throw new ProxyAuthenticatorException(localeManager.getString("technical_error"));
		}
	
		try {
			socket.close();
		} catch (Exception ex) {
			// do nothing
		}
		
		// show the login dialog
		if (showLoginDialog) {
			
			int returnValue = loginDialog.showLoginDialog(socket.getInetAddress().toString(), realm, loginIncorrect);
		
			// OK Option
			if (returnValue == JOptionPane.OK_OPTION) {
			
				// check if correct login data
				boolean value = authenticate(loginDialog.getPasswordAuthentication(), true);
			
				if (value) {						
					return true;
				} else {
					return false;
				}
			
			// CANCEL Option
			} else {
				return false;	
			}
		
		} else {
			return true;
		}
	}

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?