水平有限
于应用安全来说,推荐使用声明式的安全模型。(For application security it is highly recommended that you use the declarative JEE Servlet path role based security model. 不会译)而Click pages提供一个onSecurityCheck()方法让你使用编程的方式控制安全模型,声明式的JEE模型有很多优势。
这些优势包括:
- 它是业界的标准模式,使开发和维护更简单。
- 应用服务器通常提供多种安全基础结构的集成方式,包括LDAP目录和关系型数据库。
- Servlet安全模型支持用户bookmark页面,当用户以后访问这些页面时,容器会在允许他们访问这些资源之前,自动的认证他们。
- 使用声明式安全模型,可以使你的Page类不需要关心安全问题。这使代码的重用性更高,或者至少更容易编写。
如果你的应用有更高的安全要求,你可以混合使用声明式和编程式来达到你的要求。在这样的情况下,推荐使用声明式控制粗粒度的访问和编程式控制细粒度的访问(In these cases its recommended you use declarative security for course grained access and programmatic security for finner grained access control.)。
声明式
这种方式需要用户被认证并且是合适的角色,在他们可以访问受保护的资源。和许多JEE相比,Servlet安全模型是出奇的简单。
例如限制admin页面,在web.xml中加入安全限制。这要求用户是admin角色,在他们可以访问admin目录下的任何资源。
<security-constraint>
<web-resource-collection>
<web-resource-name>admin</web-resource-name>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
应用的用户角色在web.xml中定义,使用security-role元素。
<security-role>
<role-name>admin</role-name>
</security-role>
Servlet安全模型支持3种不同的认证方法:
- BASIC- 只推荐在安全不重要的内部应用中使用。这是最简单的认证方法,在用户可以访问受限资源前,会显示一个对话框要求认证用户。BASIC方法是相对不安全的,因为用户名和密码会被转为64位编码传回服务器。
- DIGEST-推荐在安全程度适中的内部应用中使用。和BASIC方式一样,在用户可以访问受限资源前,会显示一个对话框要求认证用户。不是所有的应用服务器都支持DIGEST认证,只有最近的版本的Apache Tomcat支持。
- FORM-推荐使用在需要定制登录页面的应用中。需要高安全度的应用推荐使用在HTTPS上的FORM方式。
认证方式使用<login-method>元素指定。例如使用BASIC方式你可以这样指定:
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Admin Realm</realm-name>
</login-config>
使用FORM方式,也需要指定登录页面和登录错误页面的路径:
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Secure Realm</realm-name>
<form-login-config>
<form-login-page>/login.htm</form-login-page>
<form-error-page>/login.htm?auth-error=true</form-error-page>
</form-login-config>
</login-config>
在login.htm页面你需要包括一个特殊的有j_username和j_password输入字段的j_security_check表单,例如:
#if ($request.getParameter("auth-error"))
<div style="margin-bottom:1em;margin-top:1em;color:red;">
Invalid User Name or Password, please try again.<br/>
Please ensure Caps Lock is off.
</div>
#end
<form method="POST" action="j_security_check" name="form">
<table border="0" style="margin-left:0.25em;">
<tr>
<td><label>User Name</label><font color="red">*</font></td>
<td><input type="text" name="j_username" maxlength="20" style="width:150px;"/></td>
<td> </td>
</tr>
<tr>
<td><label>User Password</label><font color="red">*</font></td>
<td><input type="password" name="j_password" maxlength="20" style="width:150px;"/></td>
<td><input type="image" src="$context/images/login.png" title="Click to Login"/></td>
</tr>
</table>
</form>
<script type="text/javascript">
document.form.j_username.focus();
</script>
在使用基于FORM方式的认证不要把应用逻辑写在Click的登录Page类中,因为它的角色只是简单的呈现登录表单。如果你试图把跳转逻辑放入,JEE容器可能会忽略或抛出错误。
把下面的是web.xml的片段,制定在admin和user路径下的安全限制。使用FORM方式认证,
并会将未认证的请求(403)转发到/not-authorized.htm。
<web-app>
..
<error-page>
<error-code>403</error-code>
<location>/not-authorized.htm</location>
</error-page>
<security-constraint>
<web-resource-collection>
<web-resource-name>admin</web-resource-name>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>user</web-resource-name>
<url-pattern>/user/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Secure Zone</realm-name>
<form-login-config>
<form-login-page>/login.htm</form-login-page>
<form-error-page>/login.htm?auth-error=true</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role>
<role-name>user</role-name>
</security-role>
</web-app>
可选的安全方案
也有可选的安全方案提供额外的JEE中不可用的特性,像RememberMe功能,更好的资源映射和支持Post Logon Page。(Post Logon Page允许用户成功登陆后会被转发到一个指定默认的URL,这个特性允许把登录表单嵌在所有非受限页面,并且在成功认证后,用户会进入他们的主页面。)
可用的可选的安全方案:
资源
关于安全的更多的信息资源: