验证是检验某个人是否是他/她所声称的那个人的过程。在Servlet/JSP应用程序中,验证一般是通过要求用户输入用户名和密码来完成的。
授权主要是确定一个用户具有什么样的访问级别。它使用于包含多个访问区域的应用程序,使用户能够访问应用程序的某一部分,但是不能访问其他部分。例如,网上商店可以分为公共区(供一般的公共浏览和查找商品),买家区(供已注册用户下单用),以及需要最高访问级别的管理区。不仅管理员用户自身也需要进行验证,并且还必须是已经被允许访问管理区的用户才行。访问级别经常被称作角色。
每一种兼容的Servlet/JSP容器都必须提供一种定义用户和角色的方法。如果你使用的是Tomcat,就可以通过编辑conf目录下的tomcat-users.xml文件来创建用户和角色。tomcat-users.xml文件范例如下:
<?xml version=’1.0’ encoding=’utf-8’?>
<tomcat-users>
<role rolename=”manager”/>
<role rolename=”member”/>
<user username=”tom” password=”secret” roles=”manager,member”/>
<user username=”jerry” password=”secret” roles=”member”/>
</tomcat-users>
tomcat-users.xml文件是一个带有tomcat-users根源素的XML文档。其中有role和user元素。role元素定义角色,user元素定义用户。role元素有一个rolename属性,用来指定角色的名称。user元素有username、password和roles属性。username属性指定用户名称,password属性指定密码,roles属性则指定该用户所属的一个或多个角色
前面讲过,将静态资源和JSP页面保存在WEB-INF或其下的某一个目录下,可以讲他们隐藏起来。放在这里的资源无法直接通过输入网址而访问到,但是仍然可以通过一个Servlet或者JSP页面跳转到那里。虽然这种方法简单直接,但缺点是藏在这里的资源就永远被藏起来了。它们永远无法被直接访问到。如果只是想避免未授权的用户访问这些资源,那么可以讲它们放在应用程序目录下的某一个目录中,并在部署描述符中声明一个安全性约束。
security-constraint元素用于指定一个资源集合,以及可以访问这些资源的一个或多个角色。这个元素可以有两个子元素:web-resource-collection和auth-constraint。
web-resource-collection元素用于指定一个资源集合,并且可以带有以下元素:web-resource-name、description、url-pattern、http-method和http-method-ommission。
web-resource-collection元素可以带有多个url-pattern元素,每一个子元素都表示所包含安全性约束实行的一种URL模式。我们可以在url-pattern元素中用一个星号(*)表示一种特定的资源类型(如*.jsp),或者表示某个目录下的所有资源(如/*或/jsp/*)。但是这两种不能合二为一,比如,无法表示某一个特定目录下的某一种特定的类型。因此,如果用/jsp/*.jsp表示jsp目录下的所有jsp页面,那么这个URL模式将是无效的,而是要用/jsp/*来表示,但是这样又限制了jsp目录下那些非jsp的页面。
http-method元素中定义了一个HTTP方法,包含的安全性约束即应用到该方法中。例如,web-resource-collection元素带有一个GET http-method元素,表示web-resource-collection元素只应用于HTTP的get方法。包含资源集合的安全性约束并不能保护其他的HTTP方法,例如Post方法和Put方法。如果没有http-method元素,表示这个安全性约束将会限制对所有HTTP方法的访问。同一个web-resource-collection元素中可以带有多个http-method元素。
http-method-omission元素指定的是不再所包含安全性约束中的HTTP方法。因此,指定<http-method-omission>GET</http-method-omission>限制了对除GET之外的所有HTTP方法的访问。
http-method和http-method-omission元素不能同时出现在同一个web-resource-collection元素中。
部署描述符中可以有多个security-constraint元素。如果安全性约束元素中没有auth-constraint元素,那么这个资源集合将不能受到保护。此外,如果你指定了一个没有在容器中定义的角色,那么将没有人能够直接访问这个资源集合。但是,你还是可以通过一个Servlet或者JSP页面跳转到集合中的某个资源。
举个例子。下面的web.xml文件中的security-constraint元素限制了对所有jsp页面的访问。由于auth-constraint元素中没有包含role-name元素,因此不能通过url来访问这些资源。
Servlet容器会发送一条HTTP403错误,温柔地告诉你:Access to the requested resource has been denied(禁止访问)。
学会如何对一个资源集合强加安全性约束之后,还应该知道如何对访问这些资源的用户进行验证。对于声明式保护的资源,可以在部署描述符中使用security-constraint元素,通过使用HTTP 1.1提供的解决方案来完成验证:基本访问验证和摘要访问验证。此外,也可以使用基于表单的访问验证。
基本访问验证,简称基本验证,是一种接受用户名和密码的HTTP验证。在基本访问验证中,如果用户访问受保护的资源,将会遭到服务器的拒绝,并返回一个401(未授权)响应。该响应中包含一个WWW-Authenticate标头,其中至少包含一个适用于被请求资源的角色,例如:
HTTP/1.1 401 Authorization Required
Server: Apache-Coyote/1.1
Date: Wed, 21 Dec 2011 11:32:09 GMT
WWW-Authenticate: Basic realm=”Members Only”
随后浏览器屏幕上回显示一个登录对话框,供用户输入用户名和密码。当用户单击Login登录按钮时,用户名后面会被添上一个冒号,并和密码结合在一起。这个字符串被送到服务器之前,将先用Base64算法进行编码。登录成功之后,服务器就会发出被请求的资源。
Base64是一种很弱的算法,因此Base64消息很容易被破解。因此,要考虑使用摘要访问来代替。
下面展示了如何使用基本访问验证。第一个security-constraint元素是避免JSP页面被直接访问。第二个是限制只有manager和member角色的用户才能访问Servlet1 Servlet。Servlet1类是一个跳转到1.jsp页面的简单Servlet
web.xml由于映射到Servlet1的auth-constraint元素指定了manager和member两种角色,因此通过tom或者jerry都可以登录。