Tomcat 域认证和Struts

安全差不多是迷信。实际上它并不存在,总体上人类的子民也没有体验到它。避免危险并不比直面危险更安全。人生或者是一个勇敢的冒险,或者什么也不是。

——Helen Keller

你是你声称的那个人吗?因为你 就是 那个人,相对于我的应用程序来说你是谁?

如果你完全地了解以上所述,那么你就知道认证和授权的区别。 当你深入到应用程序的工作方式中去时,这并不简单。在应用程序的目的和本质方面和你希望使用的支撑体系结构上,有许多问题需要回答。

我们首先看看认证。 我们将采用0、1世界外的例子,而使用人群互动的例子。 让我们假定你坐在一个拥挤的咖啡店的桌子旁边,还有两把椅子。 你正在读报纸,没和其他人打交道,所剩无几的椅子中的一张就在你的桌子边。有人端了一杯咖啡来了,问你他能不能坐在你的桌子旁边,因为还有一个空位。你说,“当然可以了。如果你愿意读我报纸的话,我已经读完了运动和娱乐部分。”你此刻正在和一个匿名用户共享信息。

时间流转,你啜饮着咖啡,几乎同时,你和你的同座把眼光从报纸上移开,抬起头。短暂的尴尬后,陌生人说“感谢你这个座位,今天这里很拥挤,我需要坐一会。我的名字叫Dean。”Dean 不再是匿名了,你现在知道了他的一些情况。到这里你需要决定是否信任他,并且就分享一张桌子和报纸来说,知道这个名字就足够了。你们聊得很愉快。

几天以后,你到该咖啡店,定了你常喝的咖啡,坐下来读报纸。几分钟后Dean来了,虽然这时候店里不是很挤,他来到你桌子旁边,拿了另一种报纸和你分享。你们安静地坐着读报,交换了一些看法,彼此更了解了。以后,这成了常事儿,只要你们同时都在咖啡店,就一起坐一下,喝咖啡、聊天。在几周内你们交换个人信息和详细情况,你知道了Dean的很多信息,所以当你见到他,你和他之间的交往就更个人化,比之Dean是一个完全陌生人的情况,障碍更少。你可能买咖啡,或者Dean 可能再拿起一块脆饼。你现在从陌生人中知道了Dean,任何时候他和你同桌都会受到欢迎。他被“认证”为Dean,并且“授权”成为一个可以和你分享桌子、报纸、和共同聊天的人。

在上面的场景中,你做了好几个决定:你决定让别人共享你的空间和信息;进而,你决定把这个决定施用到某个特定的人,并且基于他是谁和他是做什么的来和他交往。现在来和Web应用比较一下。

在我们的“咖啡店”Web应用中,我们有一个给所有用户(那些要求坐在桌子边,分享报纸的陌生人)提供信息的网站。来客给我们一些细节和请求,我们就提供更多信息。

到这里,我们已经决定了应该具备“安全”级别是,一个名字,因为该来客并不是要求借一千美金,而我们也不打算借给他。随着我们决定分享更多信息,我们知道谁是“Dean”了,并且因为除了他的名字以外,我们知道他的更多情况,我们已经基于他到底是“谁”,来“授权”给他,使他可以分享更多的信息。如果另一个人请求坐在你桌子旁边,他或者她也得通过和Dean同样得步骤。

在这章中,我们要揭示对于应用程序的一般和特殊的领域,使用不同的方法去实现安全策略。涉及下列四个方面:

n 一个简单的登录/注销认证策略——这是一个轻量级的安全模型,因为它安全性比较低,本质上非常普通。这是个非常基本的模型,并不基于容器,并且可以扩展、缩放。

n 把域认证和Struts集成起来——这种更一般性和更具有“工业强度”,基于容器的认证的变化,就如同我们咖啡店的例子是一个会员制情况:任何进来的人都必须根据一个可理解的,被同意的政策,进行认证,然后由管理部门发给胸卡。当Dean请求坐在你桌子旁的时候,你已经知道他的名字,并且确信他是这个咖啡店的会员。

n 防止一组用户访问个别的字段——这与第一次和某人见面相似。当你更了解他们以后,他们就可以访问更多信息。即使在你的桌子旁边坐了许多人,他们可以使用关于回话的上下文的不同信息。

n 防止某些分组的用户访问页面的某些区域——和上面字段级别的方法类似,但这是在页面级别上。

n 使用Struts保护 Action 避免未授权的访问。你不想让咖啡店里的陌生人在你的杯子里喝一口,或者在你的甜饼上咬一口!我们已经想出了几个方法来找到用各种机制来防护 Actions。

本章中的方法给用户可选择的方法——从很简单到相当复杂——控制访问,保护信息并指导用户。虽然认证和授权通常是用来实现以防止有害的或者恶意的用户, 但是,把这些策略看作是“指导”特定用户到更可用和更相关的信息的方法,这是明智的。

多数情况下用户不是恶意的,他们只是寻找最有密切关系的信息,这种情况下授权和认证就是服务于此的,可被接受的标准。

7.1 Tomcat 域认证和Struts
Tomcat domain authentication and Struts

◆ 问题

如何把域认证和Struts集成。

◆ 背景

就Web应用来说,安全是个热门话题。许多企业级的项目把敏感的商业逻辑和处理过程暴露给浏览器,这没有什么不寻常的。重要的是要防止恶意的或者“错乱”的用户访问到这种信息。

Tomcat 和其他servlet 容器具有很好的在域的级别上认证的系统,该系统可以与数据库或者普通文件相集成来进行认证用户并通过分配给用户的“角色”来建立对不同区域进行访问的级别。这一系统是Servlet 2.2 规范的一部分:

当前对于servlet容器中的用户认证,有四个独立机制。

n HTTP Basic——这是到目前为止实现的最简单的认证类型。当浏览器向一个受容器保护的区域发出请求的时候,会弹出一个系统级的认证对话框,要求用户填入一个用户名和口令(许多基于web的邮件应用程序的用户会立刻认出这个对话框)。这个对话框是通过从Web容器返回的一个响应“401unauthorized”消息触发的,该消息从符合HTTP 协议的任何浏览器中触发该对话框。该登录和口令信息经由Base64认证送回到服务器。一旦这个信息被处理,在Web容器的配置当中设置的访问级别就会授予给对该页面的请求以及所有对被该Web容器


保护的页面的请求。HTTP Basic 极为便于设置,对它的支持也是普遍的,但是它的外观是固定的,并且虽然它是Base64编码的,但是这不是一个安全的加密方法。

n HTTP 表单——把这个认证类型当作是HTTP Basic认证再多一个“友好”的界面。代替系统级别的对话框的是,用户被显示一个HTML页面,带有登录和密码文本框,这包括一个HTML 表单(不属于Struts),上面带有特定的表单和字段的名字,以便把收集的信息发送给服务器。如果认证失败,会显示一个特定的错误页面。注意很重要的一点是,仅当一个会话是用cookie或者用HTTPS被维护时,该方法才应该被实现。

n HTTPS 客户端——这是通过一个Secure Sockets Layer (安全的插座层)进行的HTTP认证。所有的数据是使用公钥密码转送的,并且开发者不必知道实现该系统的加密方法。这种方法需要从权威机构颁发的证书,例如VeriSign。更多关于这种认证的信息可以在这章最后的方法中找到。

n HTTP 摘要——这和HTTP Basic 认证方法一样,只是口令除了被编码外,还被加密。这提供了比Basic 认证方法更多的安全性,但只在Internet Explorer 5和更新的版本上被支持。并非所有的servlet 容器实现了这个方法,因为它不是servlet 规范强制要求的。

这个方法将讨论Basic 和 基于表单的认证,并把他们集成到Struts框架中。本章的其他方法将于此展开。

一个servlet 容器可以使用用户名和分配给用户的角色,把整个应用程序或者应用程序的一部分从用户那里保护起来,这个定义是在web 应用程序和servlet 容器的配置文件中创建的。Servlet 容器可以被配置成使用任何类型的可用的持久层, 从一个简单的XML 文件到一个开源数据库,或者符合Servlet 安全模型的完全功能的LDAP。在容器或在应用程序级别上,看哪一个适用,通过该应用程序被保护的目录和页面,被定义在web.xml文件里面。如果你打算加固一个或者许多应用程序的安全性,你有一致的和明确的方法可以完成这一任务。

对于Struts, 使用这个方法的安全性,是从该框架外面被访问的。使用Basic 认证可以使整个应用程序具有安全性。当使用基于表单的机制时,创建不被容器的配置所保护的目录很重要,因为任何servlets、图片、CSS文件、或者HTML页面不会被显示,如果他们在应用程序的安全区域里面,并且,多数情况下,你并不希望他们这样。

◆ 方法

这里讨论了两个方法。第一个是HTTP Basic 认证方法,它打开一个提示对话框,上面有登录和密码输入字段,类似图7.1中所示窗口。

这种方法避开了任何HTML 代码并且一旦Tomcat 判定了你是谁和你有什么角色就能立即装载索引或者指定的欢迎文件。对于我们的第二个方法(HTTP基于表单的认证),你需要使用标准HTML 建立一个登录和登录错误

页面,当任何受保护的页面被一个未被授权用户请求的时候,登录页面被请求,并且显示指定的欢迎文件。如果该用户认证失败,你已经创建的页面就会被发送给浏览器。

我们必须首先决定我们希望保护什么。如果你希望保护整个应用程序直到用户被知道的时候才能被访问,你必须使用Basic 方法,因为它使用一个警告框并且不需要HTML 页面、图片、或者链接来做这一工作。如果我们希望使用表单方法,那么必须创建两个简单的HTML 或者JSP 页面,并且任何我们想在这些页面上使用的文件(比如图片、包含文件等等)也都要被放在一个非保护的区域以备用。


图7.1 Basic 认证所使用的对话框。

注意

这个方法显示怎样使用普通文件认证。更多健壮的应用程序很容易被改造,但这是在Struts 方法之外了。许多资料来源有关于怎样把特定的数据源配置到容器系统的信息。

第一步,打开在应用程序的Web-INF 目录下的web.xml文件。找到在</web-app>标签处的文件末尾并且在它前面插入以下信息(根据你的目录需要取舍)

Basic 和表单类型两者都在清单7.1中显示如下:

清单7.1 在 web.xml 文件中的 Basic 认证

</taglib>

<!--Security for entire application-->

<security-constraint>

<web-resource-collection>

<web-resource-name>My web application</web-resource-name>

<url-pattern>/*</url-pattern>

<http-method>GET</http-method>

<http-method>POST</http-method>

<http-method>PUT</http-method>

<http-method>DELETE</http-method>

<http-method>HEAD</http-method>

<http-method>OPTIONS</http-method>

<http-method>TRACE</http-method>

</web-resource-collection>

<auth-constraint>

<role-name>applicationuser</role-name>

<!--more roles can be added here -->

</auth-constraint>

</security-constraint>

<login-config>

<auth-method>BASIC</auth-method>

</login-config>

</web-app>

以上所述方法保护整个目录,但是没有定制的登录或者错误屏幕提供。要提供登录和错误屏幕,指定被保护的目录和文件至关紧要,如同在清单7.2中所示:

清单 7.2 在web.xml 文件中的表单认证清单

</taglib>

<!--Security for application with custom log-in and error pages -->

<security-constraint>

<web-resource-collection>

<web-resource-name>My Custom Page Application</web-resource-name>

<url-pattern>/index.jsp</url-pattern>

<url-pattern>/pages/*</url-pattern>

<http-method>POST</http-method>

<http-method>PUT</http-method>

<http-method>DELETE</http-method>

<http-method>HEAD</http-method>

<http-method>OPTIONS</http-method>

<http-method>TRACE</http-method>

</web-resource-collection>

<auth-constraint>

<!--more roles can be added here -->

<role-name>customuser</role-name>

</auth-constraint>

</security-constraint>

<login-config>

<auth-method>FORM</auth-method>

<form-login-config>

<!--These are the two pages that must be created, if you attach

images, css, or include files it is important that they be in a

non-protected area or your results will not be what you intend -->

<form-login-page>/login.html</form-login-page>

<form-error-page>/error.html</form-error-page>

</form-login-config>

</login-config>

</web-app>

下一步,让我们看一下在{Tomcat-目录}/conf/folder目录下的server.xml 文件。它被重重地注释了,但是我们要找到在默认文件中,<engine>和<logger>标签以后的部分。 对于普通文件域认证,取消该行的注释:

<Realm className="org.apache.catalina.realm.MemoryRealm"/>

确信其他的任何域标签被注解掉。注意当使用Tomcat 4.1+时,这个取消注释的步骤没有必要,因为UserDatabaseRealm 是作为默认激活的。现在已经准备好在tomcat-users .xml 文件中命名你的用户了,也在{Tomcat-目录}/conf/folder目录中。清单7.3 演示了一个例子 tomcat-users.xml 文件,当中为基于表单的登录创建了几个用户,在上述清单7.2列出的web.xml 文件中有描述:

清单7.3 使用基于表单认证的 tomcat-users.xml 文件

<?xml version="1.0" encoding="utf-8"?>

<tomcat-users>

<role rolename="customuser"/>

<user username="aguy" password="thisPassword" roles="customuser"/>

<!-- you may comma delimit more roles in the "roles" attribute-->

<user username="anotherguy" password="thisGuysPwd" roles="customuser"/>

</tomcat-users>

最后,让我们看看在清单7.3和7.4中的JSP 登录和错误页面。这里使用的HTML 表单中的粗体变量名是被Web容器识别出并且必须被使用的。

清单7.4 用于基于表单的认证 Login.html

<html>

<head>

<title>My Log In Page</title>

</head>

<body>

<form action="j_security_check">

<table style="width: 50%">

<tr>

<td>Username:</td>

<td><input type="text" name="j_username" /></td>

</tr>

<tr>

<td>Password:</td>

<td><input type="password" name="j_password" /></td>

</tr>

<td> </td>

<td><input type="submit" value="Login" /></td>

</tr>

</table>

</form>

</body>

</html>

清单7.5 用于处理上述登录页面的任何登录错误的error.html 页面

<html>

<head>

<title>Log in error</title>

</head>

<body>

<p style="font-size: 125%; color: red">Log-In Error</p>

<p>The user name and/or password are incorrect.</p>

<p><a href="login.html">try again</a></p>

</body>

</html>

◆ 讨论

也许有这样一个情况,你仅仅希望保护Action,而不是——或者说除了——保护个别的页面。这可以通过在<web-resource-collection/>中增加如下xml标签实现:

<url-pattern>*.do</url-pattern>

这个实现保护了你方法,但是因为没有辅助的模式匹配,存在一个安全漏洞,因为用户可能会直接敲入一个URL——http://www.mysite.com/pages/myFooPage.jsp 并且可能访问它。

这是个讨论选择解决这个特别问题的好地方:

1 把所有JSPs放置在WEB-INF之下。

2 用一个限制条件把*.jsp保护起来,限制条件保证没有用户拥有使用这些jsp的许可,藉此阻止直接存取jsp。

虽然和用一个数据库可以完成的事情比起来,单调文件安全的局限是明显的,但是它其实信赖于所创建的应用程序的规模和范围。随着更多的角色和域被需要,有可能要在某些角色被创建的时候,保护网站的区域以限制这些角色。这在和本方法相关的的方法中加以说明和扩展。

最后,你也许想通过列出在WEB-INF目录内的一些或者全部JSP文件来使整个网站安全。这种保密类型允许你很容易地使用*.do 安全限制条件,因为仅有那些你希望保护的文件可以通过Struts Action访问。请参考“最优方法:使用容器保护资源”中的细节。

◆ 相关

n 7.2—处理注销

n 7.4—使用容器使动作映射安全

n 7.5—定制动作映射安全

n 7.6—保护页面上的区域

n 7.7—保护字段
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值