Spring的Acegi security的配置,和JDK1.5的一些问题

    技术2022-05-11  126

    SpringAcegi security的配置,和JDK1.5的一些问题

    新的项目没有开始于是抽空做一个通用一些的Security,后来又考虑到CASSSL的认证问题俺还没有弄懂,就选择直接使用Spring的子项目acegi

    acegi是基于Spring的的一个安全框架,支持HTTP基本(basic)验证、HTTP Request Session验证、安全通道、ACL等等,功能强大。配置比较简单,但是还是要写一下:

    1.   下载Spring Acegijar文件和它的源代码,在它的binary包中有一个contacts.war,这个是acegi的示例,把它放在tomcatwebapps下直接运行即可,这个是acegi很好的参考。

    2.   acegiHttp Servlet Filter配置在web.xml中。

        <!-- Acegi Security-->

        <filter>

           <filter-name>Acegi Filter Chain Proxy</filter-name>       <filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>

           <init-param>

               <param-name>targetClass</param-name>

               <param-value>org.acegisecurity.util.FilterChainProxy</param-value>

           </init-param>

        </filter>

     

        <filter-mapping>

           <filter-name>Acegi Filter Chain Proxy</filter-name>

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

        </filter-mapping>

    3.   contract示例下的applicationContext-acegi-security.xml放在ClassPath下或WEB-INF下,并且在web.xml中指出该文件的位置:

    <context-param>

           <param-name>contextConfigLocation</param-name>

           <param-value>

           classpath*:/net/chinasam/common/applicationContext-*.xml

           /WEB-INF/ applicationContext-acegi-security.xml</param-value>

        </context-param>

    4.   applicationContext-acegi-security.xml中找到下面的bean定义

    <bean id="jdbcDaoImpl" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">

           <property name="dataSource">

               <ref bean="dataSource" />

           </property>

        </bean>可以看到dataSource属性必须引用一个DataSource,修改这个bean,是之使用一个Spring管理的DataSource实例。JdbcDaoImpl是查询数据库的实现类,这个类使用下面的SQL进行查询:

    "SELECT username,password,enabled FROM users WHERE username = ?";

    "SELECT username,authority FROM authorities WHERE username = ?";

    前者查询用户,后者查询角色,你可以根据实际项目的情况进行修改:设置JdbcDaoImplauthoritiesByUsernameQueryusersByUsernameQuery属性。这个我没有设置过,因为我的数据库结构和这个一样。Acegi没有包含用户管理,关于UserCRUD你必须自己完成,然后通过这两个属性告诉acegi如何查询用户和角色。

       

    5.   密码编码,经常需要给密码进行编码,常用的算法包括MD5SHA等,applectionContext –acegi-Security.xml中的配置为:

    <bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.Md5PasswordEncoder" />

     

    注意,如果使用上述配置,数据库中的password字段内容必须是实际内容的MD5摘要。

    6.   ApplicationContext-acegi-securtiy.xml缺省的使用HTTP Request验证,也就是通过普通的HTML标单提交用户名和口令,所以你必须编写自己的login页面,以下是一个例子,注意黑体字部分:

    <form name="login_form" action="<c:url value='j_acegi_security_check'/>" method="POST">

    <table width="241" border="0" cellpadding="0" cellspacing="0" align="center">

      <tr>

        <td><img src="<fmt:message key="login.title.img"/>" width="241" height="26"></td>

      </tr>

      <tr>

      <td>

          <table width="241" align="center" cellpadding="0" cellspacing="0">

         

          <tr>

           <td width="1" bgcolor="#D2DBE8"></td>

           <td align="left"> <fmt:message key="username"/></td>

           <td  align="left">

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

           <td rowspan="4">

           <img src="<fmt:message key="login.button.img"/>" onclick="javascript:login_form.submit()" style="cursor:hand">

           </td>

           <td width="1" bgcolor="#D2DBE8"></td>

          </tr>

          <tr>

           <td width="1" bgcolor="#D2DBE8"></td>

           <td align="left"> <fmt:message key="password"/></td>

           <td align="left"><input type="password" class="text" name="j_password"></td>

           <td width="1" bgcolor="#D2DBE8"></td>

          <tr>

           <td width="1" bgcolor="#D2DBE8"></td>

           <td align="left" colspan="3"> <fmt:message key="rememberme"/>

           <input type="checkbox" name="_acegi_security_remember_me"></td>

           <td width="1" bgcolor="#D2DBE8"></td>

          </tr>

          </table>

      </td></tr>

      <c:if test="${! empty param.login_error}">

          <tr><td><br>

          <fmt:message key="login.failed"/>

    <%= ((AuthenticationException) session.getAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY)).getMessage() %>

          </td>   </tr>  </c:if>   </table>  </form>

    最后,你需要配置URL权限,关于POJO的方法权限俺还没有弄懂,而且,如果不提供远程访问的情况下,一般来说也不需要。在ApplicationContext-acegi-securtiy.xml找到beanfilterInvocationInterceptor  这个是基于Http Request验证的权限terceptor注意设置bjectDefinitionSource属性,下面是例子,URL的格式是参考ANT的格式,也可以根据正则表达式的写法:

    <property name="objectDefinitionSource">

               <value>

               <![CDATA[

    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON

    PATTERN_TYPE_APACHE_ANT

    /index.faces=ROLE_SUPERVISOR,ROLE_ANONYMOUS,ROLE_USER

    /login.jsp*=ROLE_SUPERVISOR,ROLE_ANONYMOUS,ROLE_USER

    /images/*.*=ROLE_SUPERVISOR,ROLE_ANONYMOUS,ROLE_USER

    /common/*.*=ROLE_SUPERVISOR,ROLE_ANONYMOUS,ROLE_USER

    /styles/*.*=ROLE_SUPERVISOR,ROLE_ANONYMOUS,ROLE_USER

    /**=ROLE_USER

                  ]]>

               </value>

    各个权限入口的顺序十分重要,注意必须把特殊的URL权限写在一般的URL权限之前。

     

    7. Acegi 1.0是基于JDK1.5的,虽然你可以在1.4下使用,但是我还是把我的项目改为JDK1.5,没成想还出现了一些问题。另外JSTL的也不同了,如果你想使用EL,则必须这样引用core:<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>

    JDK1.4下使用String.replaceFirstreplaceAll方法没有问题,但是在JDK1.5下却报IllegalArgumentExceptiongetMessage指出Illegal group arguments,但是单独写测试类运行却没有任何问题,我只好些了自己的replace算法,可是总觉得应该使用JDK提供的,希望达人指教。

    8.关于如何使用ACLSSL等验证,俺需要进一步研究。


    最新回复(0)