开发安全 Web 应用程序
当只有声明性安全性不足以表述应用程序的安全性模型时,具有安全性意识的应用程序使用程序性安全性。程序性安全性由下列步骤组成:
在 servlet 或 JSP 代码中添加必需的安全性方法。
(可选)创建具有角色名字段的安全性角色引用元素。因为安全性 API isUserInRole() 可使用实际的角色名来作为参数,所以不必创建安全性角色引用元素。但是,好的做法是使用角色引用,这样可以使软件组件可重复使用。
要获取完整的代码示例,参见示例:安全 Web 应用程序代码。
在 servlet 代码中添加必需的安全性方法。
程序性安全性由 HttpServletRequest 接口的下列方法组成:
getRemoteUser()
此方法返回客户机用来进行认证的用户名。如果尚未认证用户,则返回空。
isUserInRole (String rolename)
如果已将指定的安全性角色授予远程用户,则此方法返回 true。如果没有将指定的角色授予远程用户,或者没有认证用户,则此方法返回 false。
getUserPrincipal()
此方法返回包含远程用户名的 java.security.Principal 对象。如果没有认证用户,则返回空。
可在 servlet 的任何 doGet()、doPost()、doPut() 和 doDelete() 服务方法中添加程序 servlet 安全性方法。以下是程序性安全性 API 的用法示例:
public void doGet(HttpServletRequest request, HttpServletResponse response) {
...
// to get remote user using getUserPrincipal()
java.security.Principal principal = request.getUserPrincipal();
String remoteUser = principal.getName();
// to get remote user using getRemoteUser()
remoteUser = request.getRemoteUser();
// to check if remote user is granted Mgr role
boolean isMgr = request.isUserInRole("Mgr");
// use the above information in any way as needed by the application
...
}
创建具有角色名字段的安全性角色引用元素
此步骤是有计划地保护应用程序所必需的。如果在开发期间没有创建安全性角色引用,则确保在汇编阶段创建它。
使 用 isUserInRole() 方法时,应在部署描述符中使用包含传送给此方法的角色名的角色名元素来描述安全性角色引用。因为实际的角色是在应用程序的汇编期间创建的,所以开发者可使 用逻辑角色作为角色名,并在安全角色元素的描述中为汇编程序提供足够的线索以将该角色与实际角色链接。在汇编期间,汇编程序创建角色链接子元素以将角色名 与实际角色链接。如果使用诸如 WebSphere Studio Application Developer 之类的开发工具,则创建安全性角色引用元素是有可能的。也可以在汇编期间使用“应用程序汇编工具”来创建安全性角色引用元素。
定义逻辑角 色非常有用的情况示例是:您想使用 Web 应用程序自已的授权表(外部资源到远程用户的映射)来访问外部资源并控制对外部资源的访问。在这种情况下,可使用 getUserPrincipal() 或 getRemoteUser() 方法来获取远程用户,然后应用程序可查阅它自已的授权表来执行授权。远程用户信息还可用来从外部源(如数据库)或从企业 Bean 检索相应用户信息。同样,也可使用 isUserInRole()。
例如:
<security-role-ref>
<description>Provide hints to assembler for linking
this role-name to actual role here</description>
<role-name>Mgr</role-name>
</security-role-ref>
在汇编期间,汇编程序创建如下所示的角色链接:
<security-role-ref>
<description>Hints provided by developer to
map role-name to role-link</description>
<role-name>Mgr</role-name>
<role-link>Manager</role-link>
</security-role-ref>
在 servlet 或 JSP 代码中添加必需的安全性方法。
(可选)创建具有角色名字段的安全性角色引用元素。因为安全性 API isUserInRole() 可使用实际的角色名来作为参数,所以不必创建安全性角色引用元素。但是,好的做法是使用角色引用,这样可以使软件组件可重复使用。
要获取完整的代码示例,参见示例:安全 Web 应用程序代码。
示例:保护 Web 应用程序代码
此 示例说明使用程序性安全性模型的 Web 应用程序(servlet)。此示例是一种使用程序性安全性模型的方法,但不必是唯一的方法。应用程序可以以任何对该应用程序有意义的方式来使用 getUserPrincipal()、isUserInRole() 和 getRemoteUser() 方法返回的信息。然而,强烈建议您尽可能地使用声明性安全性模型。
import javax.servlet.*;
public class HelloServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, java.io.IOException {
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, java.io.IOException {
String s = "Hello";
// get remote user using getUserPrincipal()
java.security.Principal principal = request.getUserPrincipal();
String remoteUserName = "";
if (principal != null) {
remoteUserName = principal.getName();
}
// get remote user using getRemoteUser()
String remoteUser = request.getRemoteUser();
// check if remote user is granted Mgr role
boolean isMgr = request.isUserInRole("Mgr");
// display Hello username for managers and bob.
if (isMgr || remoteUserName.equals("bob")) {
s = "Hello " + remoteUserName;
}
String message = "<html> /n" +
"<head><title>Hello Servlet</title></head>/n" +
"<body> /n" +
"<h1> " + s + "</h1>/n ";
byte[] bytes = message.getBytes();
// displays "Hello" for ordinary users and
// displays "Hello username" for managers and "bob."
response.getOutputStream().write(bytes);
}
}
在开发 servlet 之后,可以为 HelloServlet 创建安全性角色引用,如下所示:
<security-role-ref>
<description>Manager</description>
<role-name>Mgr</role-name>
</security-role-ref>
在 servlet 代码中添加必需的安全性方法。
程序性安全性由 HttpServletRequest 接口的下列方法组成:
getRemoteUser()
此方法返回客户机用来进行认证的用户名。如果尚未认证用户,则返回空。
isUserInRole (String rolename)
如果已将指定的安全性角色授予远程用户,则此方法返回 true。如果没有将指定的角色授予远程用户,或者没有认证用户,则此方法返回 false。
getUserPrincipal()
此方法返回包含远程用户名的 java.security.Principal 对象。如果没有认证用户,则返回空。
可在 servlet 的任何 doGet()、doPost()、doPut() 和 doDelete() 服务方法中添加程序 servlet 安全性方法。以下是程序性安全性 API 的用法示例:
public void doGet(HttpServletRequest request, HttpServletResponse response) {
...
// to get remote user using getUserPrincipal()
java.security.Principal principal = request.getUserPrincipal();
String remoteUser = principal.getName();
// to get remote user using getRemoteUser()
remoteUser = request.getRemoteUser();
// to check if remote user is granted Mgr role
boolean isMgr = request.isUserInRole("Mgr");
// use the above information in any way as needed by the application
...
}
创建具有角色名字段的安全性角色引用元素
此步骤是有计划地保护应用程序所必需的。如果在开发期间没有创建安全性角色引用,则确保在汇编阶段创建它。
使 用 isUserInRole() 方法时,应在部署描述符中使用包含传送给此方法的角色名的角色名元素来描述安全性角色引用。因为实际的角色是在应用程序的汇编期间创建的,所以开发者可使 用逻辑角色作为角色名,并在安全角色元素的描述中为汇编程序提供足够的线索以将该角色与实际角色链接。在汇编期间,汇编程序创建角色链接子元素以将角色名 与实际角色链接。如果使用诸如 WebSphere Studio Application Developer 之类的开发工具,则创建安全性角色引用元素是有可能的。也可以在汇编期间使用“应用程序汇编工具”来创建安全性角色引用元素。
定义逻辑角 色非常有用的情况示例是:您想使用 Web 应用程序自已的授权表(外部资源到远程用户的映射)来访问外部资源并控制对外部资源的访问。在这种情况下,可使用 getUserPrincipal() 或 getRemoteUser() 方法来获取远程用户,然后应用程序可查阅它自已的授权表来执行授权。远程用户信息还可用来从外部源(如数据库)或从企业 Bean 检索相应用户信息。同样,也可使用 isUserInRole()。
例如:
<security-role-ref>
<description>Provide hints to assembler for linking
this role-name to actual role here</description>
<role-name>Mgr</role-name>
</security-role-ref>
在汇编期间,汇编程序创建如下所示的角色链接:
<security-role-ref>
<description>Hints provided by developer to
map role-name to role-link</description>
<role-name>Mgr</role-name>
<role-link>Manager</role-link>
</security-role-ref>