对JAVA安全性的讨论

1/5/2008来源:Java教程人气:7263


  众所周知,java小应用程序(Applet)在网络应用方面有着十分强大的功能,但是由于其存在着安全隐患,所以对于"她"的使用,JAVA语言做了很多的限制,想必大家都已经很清楚了,其中最让人不开心的就是,小应用程序只能够连接提供网页的计算机(Applet必需嵌入到一个Html页面中才能得以发布),但如何将您的小应用程序分发出去呢,这就是我们要讨论的。

JAVA语言的"强项"就在于其网络功能的强大和操作的简易性,而小应用程序(Applet)作为JAVA技术的一部分,更是"锦上添花"。然而,您可否碰到过这样的事情呢,"辛辛劳苦"做出了一个自认为很出色的Applet,可是运行时,却是"千呼万唤,她也不出来",原因何在呢,那就是JAVA语言对Applet的安全性做了多方面的限制,现在就让我们了解一下吧!

Applet的安全性

您有没有想过,通过Applet来连接一个网络服务器;您有没有想过,通过Applet来访问本地的文件,……。我想您一定做过不少的尝试,但结果总是让人难以满足,原困就是JAVA语言对Applet技术做了多方面的限制。

"Applet只能把电话打回家里"(摘自《JAVA2核心技术》),什么意思?大家不要会错意了,这是说,网络浏览器只答应一个小应用程序在给它提供服务的主机读取和写入数据。Applet只能连接其所驻留的计算机的套接字。

乍看起来,这个限制似乎毫无意义:为什么这个小应用程序被禁止执行四周浏览器一直在执行的操作,即是从网络上某台主机获取数据的操作。也许大家有些不大明白,让我们具体化这三个相关的主机,会有助于理解这个基本原理(参图一)。

源主机--给客户发送网页和JAVA小应用程序的计算机。

本地主机--运行你的小应用程序的用户计算机。

你的小应用程序预备访问的第三方的数据存储库。

Applet安全性规定:
Applet只能读取源主机上的数据。
Applet不能写入本地主机。
Applet不能读取本地主机上的数据。

不能让小应用程序写入本地主机是因为Applet可能会向本地主机传播病毒或修改它上面的重要文件,所以我们要保护运行小应用程序的客户机;不能让小应用程序读取本地主机的信息是因为本地可能保留着用户银行卡数字等这类敏感的信息,因为小应用程序支持多线程,当你打开一个漂亮的页面,使用它上面提供的有用的功能时,你可能不会意识到这个小应用程序背后的其它线程在做些什么。所以说,不能让小应用程序对本地计算机进行读写操作是同样重要的。

这样还可以理解,但为什么这个小应用程序不能从网上读取其它文件呢?网络不正是一个公用信息资源库吗?难道不是每个人都可以从网上读取信息吗?假如你在家里利用括号设备访问Internet的话,可能是能够随心所欲的。但是你假如是一名公司的职员,在公司内部使用网络资源,正好你们所在公司又恰好安装了防火墙(FireWall),那么情况就完全不一样了。

假如要具体介绍防火墙,可能最近几天大家都有不要睡觉了,所以这里只是说一下防火墙的功能。可以这样理解一个防火墙就是一个计算机,它过滤进出公司局域网的数据包。通过对安全策略的设置,它可以完成很多功能。例如:它可以拒绝局域网内除了邮件服务器以外的所有主机上邮件端口的访问请求防火墙也可以过滤公司局域网与Internet之间的通信规则,所有的这些完全取决于安全的需要。(参图二)

拥有一个防火墙可以让一个公司利用网络向雇员发送对他们有重要意义的内部信息,但同时拒绝来自公司外部的访问。一个公司只需简单的安装一台网络服务器,把其地址通知全部的雇员,并设立防火墙以拒绝任何来自公司外部的访问这个服务器的请求。而公司的职员可以用安全的使用公司内部的网络,浏览服务器。

假如一个雇员访问了你提供的网页(含有Applet的网页),那么就会有一个小应用程序被下载到装有防火墙的计算机并开始在那里运行。假如这个小应用程序可以读取它驻留的浏览器读取的所有网页,就可以访问这个公司内的住处接着,它可以连接一个主机,并利用这个主机接收和送回所有私人信息。显然这是不安全的。

这简直太糟糕了,真的,你不能自己编写运行于网上的小应用程序,获取信息,处理和格式化这些信息,并把它们发送给Applet用户。假如,我们的小应用程序只是想得到一些信息,而并不想向它的主机写回任何信息,难道这样也不行吗?为什么不能让浏览器和这个小应用程序签一个协议呢?假如这个小应用程序答应不向任何地方写入数据,那么它应该能读取任何地方的数据。这样的话,她只充当一个住处捕捉者和处理者,并在用户屏幕显示瞬息的结果。(实现上,这是可行的,这就是目前最为流行的"数字签名技术",以后我们在作介绍,这里我们介绍的是另外一种解决方法。)

代理服务器

除了"数字签名技术"这种高级技术外,我们还可以使用其它的方法来加以实现。比如,你可以建一个网页,它可以内嵌你想要运行的小应用程序(这时它用的是存储你的服务器的假数据)。你可以提供一个按钮,用户可以使用这个按钮下载这个小应用程序和相应的策略文件,这样用户就可以从这个小应用程序运行的浏览器中运行它了。虽然这是一个可行的方法,但却使你的小应用程序的"魅力"大打折扣。好在还有另外一种方法。

代理服务器方法是另外一种突破安全性的限制,实现信息的提取,现在我们就具体的介绍一下。

在你的WEB服务器上安装一个代理服务器。它是一个服务程序,随着服务器的启动而自动运行,这个程序可以获取来自于网页的请求信息,并发送给请求它的任何人。举个例子来看一下:假设你的小应用程序向驻留在同一台主机上的代理服务器发关一个GET请求

http://www.server.com/PRoxysvr?URL=http://www.yahoo.com/search.pl?Name=java

那么代理服务器会为这个小应用程序取回网页,并把它做为GET请求的答复发送回来,这样小应用程序就可以处理取回的信息了(参图三)

图三 通过代理服务器获取数据的流程
由此可见代理服务器可以实现这个功能,但现有的代理服务器都是功能丰富,而我们只是利用它的最基本的功能,所以建议大家用JAVA自己写一段代码。我们是用Servlet来实现的,一个Servlet是由一个Servlet引擎来启动的。现在大部分的网络服务器都可以运行Servlet。

代理服务器源代码(ProxySvr.java)

import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ProxySvr extends HPPTServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws SevletException, IOException {
String query = null;
response.setContentType("text/html");
PrintWriter out = response.getWriter();
query = request.getParameter("URL");
if(query == null) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Missing URL parameter");
return;
}
try {
query = URLDecoder.decode(query);
} catch(Exception exception) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
"URL decode error " + exception);
return;
}
try {
URL url = new URL(query);
BufferedReader in = new BufferedReader(new
InputStreamReader(url.openStream()));
String line;
while((line = in.readLine()) != null)
out.println(line);
out.flush();
} catch(IOException exception) {
response.sendError(HttpServletResponse.SC_NOT_FOUND,
"Exception: " + exception);
}
}
}

说明:WEB服务器的Servlet服务接收到一个GET请求时,它调用doGet()方法。HttpServletRequest参数包含请求参数。这个Servlet用getParameter()方法得到URL参数的值。在任何Servlet中,你需要把响应答复发送给HttpServletResponse类的getwriter()方法返回的PrintStream,这个Servlet连接URL参数指定的资源,每次读取它的数据,并把它发送给响应流。最后,用sendError()方法报告出现的错误。

小结

现在让我们回顾一下为什么代理服务器可以解决这个小应用程序的安全问题。当你的小应用程序要访问来自异地主机的信息时,它会将请求发送给驻留在本机上的代理服务器,然后代理服务器连接要访问的异地主机,取出所要求的数据,然后将数据返回给小应用程序。

虽然几经周折,但是却可以避免安全性的问题。OK,这也许并不是最好的解决方案,但是,它确实是一种实用的解决方案,欢迎大家一起研究。

参考资料
下面是上述程序的源代码(Zip格式)ProxySvr.zip

《JAVA2核心技术》机械工业出版社

java.sun.com http://java.sun.com/docs/books/jls/index.html