开发安全应用程序(二)——开发用于进行表单登录处理的 servlet 过滤器

开发用于进行表单登录处理的 servlet 过滤器
可以使用基于表单的登录机制来控制登录屏幕的外观。使用基于表单的登录,可以指定要显示的用于检索用户标识和密码信息的登录页面。还可以指定认证失败时要显示的错误页面。

如 果需要在认证之前和之后进行附加的认证或附加的处理,则可以使用 servlet 过滤器。Servlet 过滤器可用来动态地拦截请求和响应以转换或使用包含在请求或响应中的信息。可以将一个或多个 servlet 过滤器连接到一个 servlet 或一组 servlet。也可以将 servlet 过滤器连接到 JSP 和 HTML 页面。在调用 servlet 之前将调用所有与该 servlet 相连接的 servlet 过滤器。

任何与 Servlet 2.3 规范相符的 Web 容器都同时支持基于表单的登录和 servlet 过滤器。表单登录 servlet 执行认证,而 servlet 过滤器可用来执行附加的认证或审计或者记录信息。

要 使用 servlet 过滤器来执行登录前操作和登录后操作,可以为表单登录页面或为 /j_security_check URL 配置 servlet 过滤器。带有 j_username 参数(它包含用户名)和 j_password 参数(它包含密码)的表单登录页面公布 j_security_check。这样,servlet 过滤器就可使用用户名和密码信息来执行更多认证或其它处理。有关示例,参见示例:Servlet 过滤器。
Copy code
示例:Servlet 过滤器
此示例说明在表单登录期间使用 servlet 过滤器来执行登录前及登录后处理的一种方法。有关此代码示例的法律信息,参见代码示例不保证声明。

// Servlet Filter source code: LoginFilter.java
/**
* A Servlet filter example: This example filters j_security_check and
* performs pre-login action to determine if the user trying to log in
* is in the revoked list. If the user is in revoked list, an error is
* sent back to the browser.
*
* This filter reads the revoked list file name from the FilterConfig
* passed in the init() method. Reads the revoked user list file and
* creates a revokedUsers list.
*
* When doFilter method is called, the user being logged in is checked
* to make sure that the user is not in the revoked User list.
*
*/

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class LoginFilter implements Filter {

protected FilterConfig filterConfig;
java.util.List revokeList;
 

/**
* init() : init() method called when the filter is instantiated. This
* filter is instantiated first time j_security_check is invoked for the
* application (when a protected servlet in the application is accessed).
*/
public void init(FilterConfig filterConfig) throws ServletException {
  this.filterConfig = filterConfig;

  // read revoked user list
  revokeList = new java.util.ArrayList();
  readConfig();
}


/**
* destroy() : destroy() method called when the filter is taken out of service.
*/
public void destroy() {
  this.filterConfig = null;
  revokeList = null;
}

/**
* doFilter() : doFilter() method called before the servlet that this filter
* is mapped is invoked. Since this filter is mapped to j_security_check,
* this method is called before j_security_check action is posted.
*/
public void doFilter(ServletRequest request,
              ServletResponse response,
              FilterChain chain)
  throws java.io.IOException, ServletException {

  HttpServletRequest req = (HttpServletRequest)request;
  HttpServletResponse res = (HttpServletResponse)response;

  // pre login action
   
  // get username
  String username = req.getParameter("j_username");

  // if user is in revoked list send error
  if ( revokeList.contains(username) ) {
    res.sendError(javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED);
    return;
  }
   
  // call next filter in the chain : let j_security_check authenticate user
  chain.doFilter(request, response);

  // post login action
  }

/**
* readConfig() : Reads revoked user list file and creates a revoked user list.
*/
private void readConfig() {
  if ( filterConfig != null ) {

    // get the revoked user list file and open it.
    BufferedReader in;

    try {
    String filename = filterConfig.getInitParameter("RevokedUsers");
    in = new BufferedReader( new FileReader(filename));
    }
    catch (FileNotFoundException fnfe) {
    return;
    }
   
    // read all the revoked users and add to revokeList.
    String userName;
    try {
    while ( (userName = in.readLine()) != null ) {
      revokeList.add(userName);
    }
    }
    catch (IOException ioe) {
    }
  }
}
}
此示例显示应用程序部署描述符(web.xml)的一部分,此部分列示了 LoginFilter 配置以及指向 j_security_check 的映射:

<filter id="Filter_1">
  <filter-name>LoginFilter</filter-name>
  <filter-class>LoginFilter</filter-class>
  <description>Performs pre-login and post-login operation</description>
  <init-param>
    <param-name>RevokedUsers</param-name>
    <param-value>
    /QIBM/UserData/WebAS5/Base/instance/installedApps/application/revokedUsers.lst
    </param-value>
  </init-param>
  </filter-id>
<filter-mapping>
  <filter-name>LoginFilter</filter-name>
  <url-pattern>/j_security_check</url-pattern>
</filter-mapping>
下面是所取消的用户列表文件的示例:

user1
cn=user1,o=ibm,c=us
user99
cn=user99,o=ibm,c=us


Servlet 过滤器应该实现 javax.servlet.Filter 类。下面是 Filter 类中需要实现的方法:

init(javax.servlet.FilterConfig cfg)
当开始使用 servlet 过滤器服务时,容器调用此方法一次。传送给此方法的 FilterConfig 参数包含 servlet 过滤器的初始化参数。在使用“应用程序汇编工具”进行配置期间,可对 servlet 过滤器指定初始化参数。

destroy()
当不再使用 servlet 过滤器服务时,容器调用此方法。

doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
容 器为每个映射至此过滤器的 servlet 请求调用此方法,然后才调用该 servlet 本身。传送至此方法的 FilterChain 参数可用来调用过滤器链中的下一个过滤器。当链中的最后一个过滤器调用 chain.doFilter() 方法时,将运行最初请求的 servlet。因此,所有过滤器都应该调用 chain.doFilter() 方法。如果过滤器代码中的附加认证检查导致故障,则不需要将原始 servlet 实例化。在这种情况下,不需要调用 chain.doFilter() 方法,相反,可将其重定向至其它一些错误页面。

如果 servlet 映射至许多 servlet 过滤器,则按照应用程序的部署描述符(web.xml)中的列示次序来调用 servlet 过滤器。

下面显示了 servlet 过滤器的示例:此“登陆过滤器”可映射至 /j_security_check 以执行登录前操作和登录后操作。

import javax.servlet.*;

public class LoginFilter implements Filter {

protected FilterConfig filterConfig;

// Called once when this filter is instantiated. If this is mapped to
// j_security_check, called very first time j_security_check is invoked.
public void init(FilterConfig filterConfig) throws ServletException {
  this.filterConfig = filterConfig;
}

public void destroy() {
  this.filterConfig = null;
}
     
// Called for every request that is mapped to this filter. If mapped to
// j_security_check, called for every j_security_check action
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  throws java.io.IOException, ServletException {

  // perform pre-login action here
 
  // calls the next filter in chain. j_security_check if
  // this filter is mapped to j_security_check.
  chain.doFilter(request, response);
 
  // perform post-login action here.
  }    
}
应该将 servlet 过滤器类文件放在应用程序的 WEB-INF/classes 目录中。

配置 servlet 过滤器

可使用 WebSphere Application Development Studio 或“应用程序汇编工具”(AAT)来配置 servlet 过滤器。执行下列步骤:

配置 servlet 过滤器
在此步骤中,可以对 servlet 过滤器指定名称,并可以将相应的实现类指定给 servlet 过滤器。(可选)还可指定传送至 servlet 过滤器的 init() 方法的初始化参数。

在配置 servlet 过滤器之后,应用程序部署描述符(web.xml)包含类似于以下的 servlet 过滤器配置:

<filter id="Filter_1">
  <filter-name>LoginFilter</filter-name>
  <filter-class>LoginFilter</filter-class>
  <description>Performs pre-login and post-login operation</description>
  <init-param>// optional
    <param-name>ParamName</param-name>
    <param-value>ParamValue</param-value>
  </init-param>
</filter>
将 servlet 过滤器映射至 URL 或 servlet
在此步骤中,可以将 servlet 或 URL 模式映射至 servlet 过滤器。在将 servlet 过滤器映射至 servlet 或 URL 之后,应用程序部署描述符(web.xml)包含类似于以下的 servlet 映射:

<filter-mapping>
  <filter-name>LoginFilter</filter-name>
  <url-pattern>/j_security_check</url-pattern> // can be servlet  
  <servlet>servletName</servlet>
</filter-mapping>
Servlet 过滤器可用来替换 CustomLoginServlet。Servlet 过滤器还可以用来执行附加的认证、审计和记录。 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值