`

源码提供 —— 使用Apache Commons HttpClient灵活实现JAAS签权

阅读更多
JavaEE提供了JAAS安全机制,在架构一个web系统时,可以根据这个标准来保护系统的安全。

先对JAAS标准作个简单介绍,JAAS为Java企业应用提供了安全规范和接口,规范主要由JavaEE服务器实现,接口则面向服务实现以及应用开发。一个安全的web系统,必须对其访问用户进行访问范围的控制,在JAAS中,这种控制体现在用户的角色上。举个例子,假设一个web系统(假设为http://www.asys.com)有两个受保护的url资源分别为Area-1(http://www.asys.com/areaone)和Area-2(http://www.asys.com/areatwo),系统中有两种角色Role1和Role2,根据约定,只有属于Role1的用户才能访问Area-1,另外只有拥有Role2角色的用户才能访问Area-2,如何实现呢?很简单,根据JAAS标准,可以通过在一个JavaEE服务器中进行相应的配置来实现声明式的JAAS安全。以tomcat5.0为例,首先,在conf/tomcat-users.xml这个文件,你可以定义用户信息和角色对应关系:
xml 代码
 
  1. xml version='1.0' encoding='utf-8'?>  
  2. <tomcat-users>  
  3.   <role rolename="Role1"/>  
  4.   <role rolename="Role2"/>  
  5.   <user username="user1" password="123" roles="Role1"/>  
  6.   <user username="user2" password="456" roles="Role2"/>  
  7. <!---->tomcat-users>  

以上设置相当于定义了安全机制依赖的用户角色元数据,那么接下来就是将角色与受保护的资源进行关联声明设置,这一步需要在你具体的web应用程序的部署文件web.xml(也可以是其他部署文件比如ejb描述文件)中进行:
xml 代码
 
  1. xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.4"   
  3.     xmlns="http://java.sun.com/xml/ns/j2ee"   
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   
  6.     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
  7.       
  8.   <login-config>  
  9.     <auth-method>FORM<!---->auth-method>  
  10.     <form-login-config>  
  11.         <form-login-page>/login.jsp<!---->form-login-page>  
  12.         <form-error-page>/error.jsp<!---->form-error-page>  
  13.     <!---->form-login-config>  
  14.   <!---->login-config>  
  15.     
  16.   <security-constraint>  
  17.     <web-resource-collection>  
  18.         <web-resource-name>Area-1<!---->web-resource-name>  
  19.         <url-pattern>/areaone<!---->url-pattern>  
  20.     <!---->web-resource-collection>  
  21.     <auth-constraint>  
  22.         <role-name>Role1<!---->role-name>  
  23.     <!---->auth-constraint>  
  24.   <!---->security-constraint>  
  25.     
  26.   <security-constraint>  
  27.     <web-resource-collection>  
  28.         <web-resource-name>Area-2<!---->web-resource-name>  
  29.         <url-pattern>/areatwo<!---->url-pattern>  
  30.     <!---->web-resource-collection>  
  31.     <auth-constraint>  
  32.         <role-name>Role2<!---->role-name>  
  33.     <!---->auth-constraint>  
  34.   <!---->security-constraint>  
  35.   
  36.   <security-role>  
  37.     <role-name>Role1<!---->role-name>  
  38.   <!---->security-role>  
  39.   
  40.   <security-role>  
  41.     <role-name>Role2<!---->role-name>  
  42.   <!---->security-role>  
  43.   
  44. <!---->web-app>  

由于xml有很好的自我描述性,上面的信息意义比较明确,如果看过前面的假设案例,再具体琢磨一下应该明白,在这里就不过多解释。不过需要交待的是这个<login-config><login-config>标签,这个用途就是指定登陆签权的方式,根据JAAS标准,有BASIC/FORM/DIGEST等几种登陆方式,BASIC估计很多人在访问一些网站时碰到过,浏览器中打开一个登陆窗口,需要输入用户名密码才能访问某个资源,这种方式非常简单,是真正意义上的“声明式安全”,根本不需要编写任何代码,但是安全性和灵活性较差,这里姑且先不讨论BASIC和DIGEST模式,只讨论用得非常多的FORM模式,这种模式就是用html表单来提交用户名和密码,优点是灵活,比如你可以把登陆界面搞得更为花哨,但是有一点也比较讨厌的是,根据JAAS标准,这个登陆表单的提交Action必须是"action=/j_security_check",另外用户名密码参数名必须是j_username和j_password,为什么说它讨厌,就是你想搞得自我一些是没辙了,比如你要先通过自己的action,做一些业务逻辑或者往数据库写些什么,对不起没门,你只能提交到/j_security_check这个 url,而且,服务器验证通过后,它会自动转向你想访问的受保护资源,当然你可以通过filter来实现后置的登陆处理,但是这种方式也有问题,比如,你想加个验证码机制,用户除了输入用户名密码外,还要输对验证码才能登陆,那就无法用后置处理加以实现了。到这里你可能会咒骂,“这个JAAS是什么个标准?!居然如此不灵活!“,解决这个问题可以通过服务器端的response.sendRedirect来实现自定义登陆操作验证再执行 j_security_check,但这有个毛病是用户名密码再来回一次浏览器和服务器,安全性和效率都不好,在本文中,老黄博客用一种不同的方式,就是在服务器端通过httpclient代替用户端的浏览器来执行j_security_check操作,这样就解决了这个矛盾,你想前置或者后置进行 j_security_check检查都可以,并且完全提供开源源代码,:)

具体思路是这样的,在服务器端获取到用户名、密码、sessionid、并生成j_security_check的完整url路径,调用 JSecurityCheckHelper这个对象的doCheck方法就可以完成签权,同时JSecurityCheckHelper还支持SSL和服务代理(这可是花了老黄近一个月的心血啊)。JSecurityCheckHelper的代码骨架如下:

java 代码
  1. package laohuang.helper.jaas;  
  2.   
  3. /** 
  4.  * <code>JSecurityCheckHelper</code>利用HttpClient实现JAAS签权。 
  5.  *  
  6.  * @author newman.huang 
  7.  * @version 1.0 2007/2/26 
  8.  */  
  9. public class JSecurityCheckHelper {  
  10.       
  11.     private HttpClient httpClient;  
  12.       
  13.     static{  
  14.         loadProxyConfig();  
  15.         registerHttps();  
  16.     }  
  17.           
  18.     //加载代理属性  
  19.     private static void loadProxyConfig(){  
  20.         ...  
  21.     }  
  22.       
  23.     //注册https协议以支持HttpClient通过SSL通讯  
  24.     @SuppressWarnings("deprecation")  
  25.     private static void registerHttps(){  
  26.         ...  
  27.     }  
  28.       
  29.     /** 
  30.      * 构建。 
  31.      * 
  32.      */  
  33.     public JSecurityCheckHelper(){  
  34.         ...  
  35.     }  
  36.       
  37.     /** 
  38.      * 执行j_security_check。 
  39.      */  
  40.     public String doCheck(String userName, String password,  
  41.         String jSessionId, String jSecCheckFullURL) throws SecurityCheckException {  
  42.           
  43.         ...  
  44.     }  
  45.       
  46.     //设置代理以通过代理执行j_security_check校验  
  47.     private void setProxy(){  
  48.         ...  
  49.     }  
  50.       
  51.     //生成HttpClient Cookie  
  52.     private Cookie genRequestCookie(String jSessionId,String fullURL){  
  53.         ...  
  54.     }  
  55.       
  56.     //通过url获取cookie的域名  
  57.     private static String parseCookieDomainName(String url){  
  58.         ...  
  59.     }  
  60.       
  61.     //辅助方法,执行一个get请求,仅供测试使用  
  62.     private void doGetRequest(String url){  
  63.         ...  
  64.     }  
  65.       
  66.     //辅助方法,获取当前JSESSIONID,仅供测试使用  
  67.     private String getJSessionId(){  
  68.         ...  
  69.     }  
  70.       
  71.     ...  
  72. }  

本实现可以解决j_security_check Form验证的不灵活弊端,也可以将代码集成到有需要的客户端测试当中,另外,可以充当学习HttpClient的范例代码。正如硬币都有正反两面,这个解决方案没有遵循server/Client分离的实现原则,如果放置在服务器端,在不同的应用环境下,需要处理的细节过多,比如需要关注传输协议细节(SSL),是否使用代理等等,尽管如此,</login-config></login-config>JSecurityCheckHelper还是都为你提供了这些实现。
<login-config><login-config>
</login-config></login-config>
分享到:
评论

相关推荐

    可用org.apache.commons.httpclient-3.1.0.jar.zip

    import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods....

    org.apache.commons.httpclient-3.1.jar

    - `LICENSE.txt`:包含了Apache Commons HttpClient的许可协议,它遵循Apache 2.0许可证,允许免费使用和修改源代码。 - `README.txt`:一般提供了项目的简介和快速入门指南。 - `NOTICE.txt`:通常列出库中可能包含...

    org.apache.commons.httpclient相关架包

    Apache Commons HttpClient是一个流行的Java库,用于...总的来说,Apache Commons HttpClient是一个强大且灵活的HTTP客户端库,适用于各种Java应用,无论是在服务器端还是桌面端,它都能帮助开发者轻松地处理HTTP通信。

    org.apache.commons.httpclient

    在实际开发中,HttpClient还可以与其他Apache Commons库,如IO和Lang,一起使用,以增强功能,例如处理输入/输出流,字符串操作等。 总的来说,Apache Commons HttpClient是一个强大的工具,提供了丰富的功能来处理...

    org.apache.commons.httpclient相关资源包

    2. **commons-httpclient-3.0.jar**:这就是Apache HttpClient的核心库,提供了HTTP客户端接口和实现。这个版本(3.0)支持HTTP/1.0和HTTP/1.1协议,包含了处理连接管理、多线程请求、SSL/TLS安全连接等功能。用户...

    commons-httpclient-3.1 java API详细index格式文档

    Apache Commons HttpClient 3.1的apidocs提供了详细的类和方法文档,帮助开发者理解和使用这个库。例如,你可以通过`GetMethod`实例化并调用`execute()`方法来发送GET请求,通过`HttpPost`设置`NameValuePair`列表并...

    org.apache.commons.httpclient 远程下载文件

    在本篇讨论中,我们将深入理解如何使用HttpClient来实现远程文件下载。 首先,我们需要导入必要的依赖。如果你使用的是Maven,可以在pom.xml文件中添加以下依赖: ```xml &lt;groupId&gt;commons-httpclient ...

    commons-httpclient-3.1jar包下载

    http://jakarta.apache.org/commons/httpclient/ org.apache.commons.httpclient.URI org.apache.commons.httpclient.Wire org.apache.commons.httpclient.Cookie org.apache.commons.httpclient.Header org.apache.commons...

    commons-httpclient-3.1jar包

    《Apache Commons HttpClient 3.1详解》 Apache Commons HttpClient 是一个功能强大的Java库,专为实现客户端HTTP通信而设计。这个3.1版本是HttpClient的一个重要里程碑,它提供了丰富的功能和改进,使得开发者能够...

    org.apache.commons.httpclient资源包(4.2)

    Apache Commons HttpClient是一个流行的Java库,专门用于执行HTTP客户端请求。这个资源包,"org.apache.commons.httpclient资源包(4.2)",是...使用HttpClient,可以高效、灵活地实现HTTP通信,提升应用的网络功能。

    commons-httpclient.rar

    在实际开发中,使用Apache Commons HttpClient库时,通常需要以下步骤: 1. **导入依赖**:将Apache Commons HttpClient相关的JAR文件添加到项目的类路径中。 2. **创建HttpClient实例**:根据项目需求初始化...

    apache commonshttpclient源码

    真正的 org.apache.commons.httpclient.source 源码

    commons-httpclient相关jar包

    对于新的项目,推荐使用Apache HttpClient 4.x或更高版本,或者考虑使用Java 7及以后版本提供的内置`java.net.HttpURLConnection`,因为这些更新的解决方案通常有更好的性能和兼容性,并且与现代Java生态系统更好地...

    apache-commons-httpclient.jar

    在"apache-commons-httpclient.jar"中,包含了以下关键知识点: 1. **HTTP请求**: HttpClient允许开发者构建复杂的HTTP请求,如设置请求头、添加POST参数、定义HTTP方法等。通过`HttpMethod`接口(如HttpGet、...

    commons-httpclient-3.0.jar JAVA中使用HttpClient可以用到

    《JAVA中使用HttpClient:commons-httpclient-3.0.jar详解》 在JAVA开发中,进行HTTP请求时,Apache的HttpClient库是一个不可或缺的工具。本文将深入解析`commons-httpclient-3.0.jar`,它是HttpClient的一个重要...

    ApacheCommons-HTTPClient组件的应用.doc

    由于JDK内置的java.net.URL和URLConnection类在功能上可能不足以满足复杂的需求,Commons-HTTPClient 提供了更为丰富和灵活的功能。 HttpClient 支持HTTP 1.0和1.1协议的全部方法,包括GET、POST、PUT、DELETE、...

    最新org.apache.commons.httpclient.rar

    3. **使用方式**:在项目中引入`org.apache.commons.httpclient-3.1.0.jar`后,可以通过创建`HttpClient`实例,配置各种参数,然后调用`executeMethod`方法来发送HTTP请求。例如,发送一个GET请求: ```java ...

    commons-httpclient-3.0.jar

    在httpclient4.x中没有commons-httpclient-3.0.jar,无法使用import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient....

Global site tag (gtag.js) - Google Analytics