`
kiki1120
  • 浏览: 307949 次
  • 性别: Icon_minigender_2
  • 来自: 上海
社区版块
存档分类
最新评论

《Java安全性编程指南》学习笔记—第8章 Java中其他安全模块

阅读更多

Servlets

 

    Servlets是服务器端动态产生网页的Java部件。可以被看作是没有GUI的服务器端applet版本。用户通常通过浏览器来访问网络应用程序,这就与Web服务器建立连接并调用servlet。既然servlet用于网络应用,它的安全模块就是为了满足应用程序的需要,这些需要包括认证、访问控制、数据完整性、保密性。

 

认证

 

    认证就是确认用户是谁。Servlet以此决定谁能够访问哪些信息。在servlet规范2.2中定义了4种认证方式,在http://java.sun.com/products/servlet/index.html中可以找到,这4种形式是:

  • HTTP基本认证
  • HTTP摘要认证
  • 基于表单的认证
  • SSL客户端认证

HTTP基本认证

 

    HTTP基本认证是Servlet可以采用的最简单的认证方式,服务器询问浏览器端用户名和口令,并由用户输入,自此浏览器的每一个请求都包括由BASE64编码规则编码的用户名和口令。基本认证方式有两个问题,首先是很少有人喜欢浏览器蹦出来的对话框,很多设计者和用户喜欢与发出认证请求的站点设计相一致。其次是认证的安全性比较脆弱。因为每一次请求都包括用BASE64编码规则编码的用户名称和口令,这很容易被人截获并用BASE64编码规则获得用户名称和密码。解决这个问题的办法是让用户用SSL来访问受严格限制的页面,它可以防止在传输的过程中被非法解密。

 

HTTP摘要认证

 

    摘要认证方式交换摘要信息来证明用户知道他的口令但并不传输口令本身,下面说明这种协议是如何工作的:

  1. 服务器创建一个nonce,这是一个惟一的随机值。例如用户的IP地址跟一个时间戳,再加上服务器产生的一个随机值,就像“127.0.0.1:958579743033:upA1DVQnsTs=”。
  2. 服务器把这个nonce送到客户端。
  3. 客户用他的用户名和口令对这个名词进行杂凑。
  4. 客户端把这个杂凑结果送到服务器端。
  5. 服务器根据他已经知道的用户名称、口令和名称同样计算一个杂凑值。
  6. 服务器比较这两个杂凑值,如果相比配就允许用户访问受保护的资源,否则就拒绝。

    通过时间戳和一个随机值就可以保证重复攻击不会成功,也就是说,没有人能够窥探会话包,再重复使用相同的杂凑值,这是因为这个nonce值在不断变化,这就与基本的HTTP认证方式有很大的不同,因为后者的口令是明文发送,所以很容易被被人截获。

    不幸的是并不是所有的浏览器和服务器都支持摘要认证。通常大多数只支持基本和表单认证方式。

 

基于表单的认证

 

    基于表单的认证解决了基本认证方式的丑陋的蹦出对话框的方式。设计者和用户喜欢吸引人并与网站风格一致的界面。基于表单的认证方式就可以使用HTML页面来取得用户名称和口令,而不会蹦出一个灰色的对话框。

    当一个用户要访问受保护的资源,服务器就检查他是否通过认证。如果没有,服务器就保存请求的URL并把请求转移到认证页面。用户填完表格并提交到服务器。如果用户名和口令正确并可以授权访问原先的URL,客户请求就重新转换到那儿,否则请求被拒绝并显示错误页面。

    基于表单的认证方式没有摘要认证方式那么安全,因为口令使用明文的方式从客户端传到服务器。而且,口令发出之后,在客户端和服务器之间就会来回传送cookie以指示用户已经通过了认证。这个cookie同样可以被截获而被别人用以伪装。解决的办法同样要使用SSL连接服务器和客户机来防止口令(或者cookie)被截获。

 

HTTPS客户端认证(SSL)

 

    HTTPS客户端认证是最安全的认证方式,HTTPS是在SSL文上的简单HTTP,它不同于上面讲述的三种认证方式只需要用户名和密码,而HTTPS客户端认证要求客户端有一个私钥及对应的证书以用于认证。这就大大增加了安全性。

    基本上服务器只允许有经过认证的证书的用户访问有关资源。这就比用户名/口令的方式要更难以实施,因为大多数用户都没有证书。为了保证每一个用户有一个证书,必须与CA联系或自己建立CA来发布浏览器证书。

    配置HTTPS客户端认证是服务器高度依赖的。许多并不支持HTTPS认证。然而大多数J2EE servlet容器都支持它。

    注意客户端认证并不是非要用SSL不可,当使用基本和基于表单的认证方式时使用SSL可以隐含用户名和口令。

 

访问控制

 

    servlet安全模块是基于角色的。也就是说资源访问权限赋给角色,通过角色把权限赋给用户。要检查用户是否有访问权限,服务器就检查用户所属的角色以及角色所具有的权限。

    服务器用特定的工具来处理用户与角色之间的映射。供应商有自己的方法来告诉服务器哪个用户属于角色。有的使用操作系统的安全机制,有的把用户和角色信息保存在数据库中或文件中。有两种方法来指出什么角色可以访问哪些资源——声明和编程。

 

声明中定义安全性

 

    在网络应用程序的配置描述符中,开发人员可以指定是否某个资源是受保护的,什么角色可以访问它。使用这种声明限制的优点是容易修改并且不需要编码。

    配置描述符定义了网络应用程序的配置。包括初始参数,URL到servlet映射和安全信息。配置描述符在文件web.xml中位于网络应用程序的WEB-INF目录中,从文件名称你就可以看出它采用XML格式。

    你可以在配置描述符中增加security-constraint元素来防止对资源的非法访问。它包括一个web-resource-collection来定义受保护的资源以及一个auth-constraint元素来指定可以访问这些资源的角色。用户认证采用前面所讲的几种方式之一,然后映射到角色,并与配置描述符比较出是否有访问权限。

 

程序中定义安全性

 

    对于有些应用程序,在声明中定义安全性是不够的。在javax.servlet.http.HttpServletRequest中有三个方法可供开发人员选用,以便在程序中定义基于用户请求的动作:

  • String getRemoteUser():getRemoteUser()返回登录到网站的用户名字符串。如果用户没有登录就返回null。
  • boolean isUserInRole(String role):isUserInRole()指出访问servlet的用户是否在给定的角色中。
  • Principal getUserPrincipal():getUserPrincipal()返回代表登录用户的java.security.Principal对象。如果用户没有登录就返回null。

 

数据完整性

 

    servlet安全性的另一个主要功能是保证数据的完整性,也就是说数据在传输的过程中无论如何也不会改变。SSL会自动地处理这些问题,并向发送到线路上的数据中添加校验和,如果发现任何变化,服务器会及时通知浏览器。

    你不需要再你的servlet中处理数据完整性的问题,这是servlet容器的事情。如果你需要这个层次的安全性,你就可以配置你的服务器使用SSL进行通信。

 

保密性

 

    保密性是很多人考虑网站安全性是所必须考虑的问题。加密浏览器和服务器之间的通信可以确保保密性。与数据完整性一样,SSL也总是处理保密性的问题。

    类ServletRequest包括一个方法isSecure()用于程序判断是否用SSL建立连接。如果isSecure()返回布尔值true,就表示建立了安全连接。安全性的定义取决于servlet容器程序员。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics