|
用 Java 2 标准版本 (J2SE) 1.4 进行 Internet 安全编程(4) SunJSSE 提供者 J2SE v1.4.1 和一个 JSSE 提供者,SunJSSE 一起发布。SunJSSE 安装并预登记了 Java 的加密体系。请把 SunJSSE 作为一个实现的名字来考虑,它提供了 SSL v3.0 和 TLS v1.0 的实现,也提供了普通的 SSL 和 TLS 密码组。如果你想找到你的实现 (这里是 SunJSSE) 所支持的密码组列表,可以调用 SSLSocket 的 getSupportedCipherSuites 方法。然而,不是所有这些密码组都是可用的。为了找出那些是可用的,调用 getEnabledCipherSuites 方法。这个列表可以用 setEnabledCipherSuites 方法来更改。 一个完整的例子我发现使用 JSSE 开发最复杂的事情关系到系统设置以及管理证书和密匙。在这个例子中,我演示了如何开发、配置和运行一个完整的支持 GET 请求方法的 HTTP 服务器应用。 HTTP 概览
超文本传输协议 (Hypertext Transfer Protocol, HTTP) 是一个“请求-回应”的应用协议。这个协议支持一套固定的方法如 GET、POST、PUT、DELETE 等。一般用 GET 方法向服务器请求资源。这里有两个 GET 请求的例子: GET / HTTP/1.0 <empty-line> GET /names.html HTTP/1.0 <empty-line> 不安全的 HTTP 服务器为了开发一个 HTTP 服务器,你得先搞明白 HTTP 协议是如何工作的。这个服务器是一个只支持 GET 请求方法的简单服务器。代码示例 1 是这个例子的实现。这是一个多线程的 HTTP 服务器,ProcessConnection 类用于执行不同线程中新的请求。当服务器收到一个来自浏览器的请求时,它解析这个请求并找出需要的文档。如果被请求的文档在服务器上可用,那么被请求的文档会由 shipDocument 方法送到服务器。如果被请求的文档没有打开,那么送到服务器的就是出错消息。 代码示例 1:HttpServer.Java import Java.io.*;import Java.net.*;import Java.util.StringTokenizer;/** * This class implements a multithreaded simple HTTP * server that supports the GET request method. * It listens on port 44, waits client requests, and * serves documents. */public class HttpServer { // The port number which the server // will be listening on public static final int HTTP_PORT = 8080; public ServerSocket getServer() throws Exception {return new ServerSocket(HTTP_PORT); } // multi-threading -- create a new connection // for each request public void run() {ServerSocket listen;try {listen = getServer();while(true) { Socket client = listen.accept(); ProcessConnection cc = newProcessConnection(client);}} catch(Exception e) {System.out.println("Exception: "+e.getMessage());} } // main program public static void main(String argv[]) throwsException {HttpServer httpserver = new HttpServer();httpserver.run(); }}class ProcessConnection extends Thread { Socket client; BufferedReader is; DataOutputStream os; public ProcessConnection(Socket s) { // constrUCtorclient = s;try {is = new BufferedReader(new InputStreamReader(client.getInputStream()));os = new DataOutputStream(client.getOutputStream());} catch (IOException e) {System.out.println("Exception: "+e.getMessage());}this.start(); // Thread starts here...this start() will call run()}public void run() {try {// get a request and parse it.String request = is.readLine();System.out.println( "Request: "+request );StringTokenizer st = new StringTokenizer( request );if ( (st.countTokens() >= 2) &&st.nextToken().equals("GET") ) { if ( (request =st.nextToken()).startsWith("/") )request = request.substring( 1 ); if ( request.equals("") )request = request + "index.html"; File f = new File(request); shipDocument(os, f);} else { os.writeBytes( "400 Bad Request" );} client.close();} catch (Exception e) {System.out.println("Exception: " +e.getMessage());}} /*** Read the requested file and ships it * to the browser if found.*/ public static void shipDocument(DataOutputStream out, File f) throws Exception {try {DataInputStream in = newDataInputStream(new FileInputStream(f));int len = (int) f.length();byte[] buf = new byte[len];in.readFully(buf);in.close();out.writeBytes("HTTP/1.0 200 OK\r\n");out.writeBytes("Content-Length: " + f.length() +"\r\n");out.writeBytes("Content-Type: text/html\r\n\r\n");out.write(buf);out.flush();} catch (Exception e) {out.writeBytes("<html><head><title>error</title></head><body>\r\n\r\n");out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");out.writeBytes("Content-Type: text/html\r\n\r\n");out.writeBytes("</body></html>");out.flush();} finally {out.close();} }}
实验一下 HttpServer 类: - 将 HttpServer 的代码保存在文件 HttpServer.Java 中,并选择一个目录把它存放在那里。
- 使用 Javac 编译 HttpServer.Java
- 建立一些 HTML 文件作为例子,要有一个“index.html”,因为它是这个例子中默认的 HTML 文档。
- 运行 HttpServer。服务器运行时使用 8080 端口。
- 打开网页浏览器,并发出请求:http://localhost:8080 或者 http://127.0.0.1:8080/index.html。
注意:你能想到 HttpServer 可能接收到一些恶意的 URL 吗?比如像 http://serverDomainName:8080/../../etc/passwd 或者 http://serverDomainName:8080//somefile.txt 等。作为一个练习,修改 HttpServer 以使其不允许这些 URL 的访问。提示:写你自己的 SecurityManager 或者使用 Java.lang.SecurityManager。你可以在 main 方法的第一行添加语句 System.setSecurityManager(new Java.lang.SecurityManager) 来安装这个安全的管理器。试试吧!
|