权限控制:spring 3.0 security配置例子

我几年前自己写过一个后台权限管理的东西,也是基于用户-角色-权限这样的结构,说实话代码结构写得不好,因为是硬编码的形式,虽然功能其实用起来还是挺好用的,用户、角色及权限的管理均可在后台轻松完成,但现在如果再用硬编码的形式写这样的系统就说不过去了。目前关于权限管理的java开源系统比较多,有的比较有名,有的不出名,比如像Spring Security就很出名,在权限管理方面做得也非常全面,子猴这篇文章也是对Spring Security做个简短介绍。

我以最新版的spring-security-3.0.2作为介绍对象,如果你了解Spring 2.0 Security的话,那就比较抱歉了,因为spring-security-3.0.2与2.0相比改动很大,在2.0中的一些配置拿到3.0几乎是行不通的,如果你还没有接触过spring,那么以下是其地址:

Spring官方网址:http://www.springsource.org/

spring-security下载地址:

http://static.springsource.org/spring-security/site/downloads.html

我以其自带的一个简单例子来介绍一下吧,因为这个例子配置不对的话极易报错(这个例子是个打包的War文件,但与文档中的又不一样,所以极易出错),我会对出现的错误给予出错原因及解决方法。

首先通过spring-security地址下载到最新版的spring-security-3.0.2.RELEASE.zip,然后解压开来,在解压开的目录dist中,你会看到如下一些文件:

权限控制:spring 3.0 security配置例子

看到spring-security-samples-tutorial-3.0.2.RELEASE.war了吗?我就以这个为例,把这个包拷贝到你Web服务器(如Tomcat)的webapps目录下,启动服务器后,会生成一个spring-security-samples-tutorial-3.0.2.RELEASE项目,可以把名字改短一点方便访问,比如我这里改名为:spring-security,这样通过http://127.0.0.1/spring-security可以直接访问了。

权限控制:spring 3.0 security配置例子

进入目录WEB-INF,可以看到如上的一些文件,其中,applicationContext-security.xml是权限控制配置文件,所有的权限控制都是在其中配置的,bank-servlet.xml是系统的上下文配置文件,可以在其中配置访问路径映射(类似于Struts-1.x中的struts-config.xml或struts-2.x中的struts.xml文件),也可以在其中进行一些装配等工作,属于spring级的,与安全配置没多大关系。

具体的文件内容我就不展示了,因为可以自己打开看,我这里只说要注意的一些地方:

1、在web.xml中的配置

服务启动时加载applicationContext-security.xml文件:

<context-param>



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



<param-value>



/WEB-INF/applicationContext-security.xml



</param-value>



</context-param>

要过滤链接的形式

<filter>

<filter-name>springSecurityFilterChain</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

</filter>

<filter-mapping>

<filter-name>springSecurityFilterChain</filter-name>

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

</filter-mapping>

你一定注意到了,这里的filter-class与Spring2.0的不同之处,如果你了解Spring2.0的话,的确,在Spring2.0中为:

<filter-name>acegiFilterChain</filter-name>

<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>

这就是3.0与2.0改变很大的一个地方,2.0用的为Acegi,后来Acegi嵌入到了Spring中,成为了Spring Security,所以包的路径也都改变了!

2、在applicationContext-security.xml中的配置
<http use-expressions=”true”>

<intercept-url pattern=”/secure/extreme/**” access=”hasRole(‘ROLE_SUPERVISOR’)”/>

<intercept-url pattern=”/secure/**” access=”isAuthenticated()” />

<!– Disable web URI authorization, as we’re using <global-method-security> and have @Secured the services layer instead

<intercept-url pattern=”/listAccounts.html” access=”isRememberMe()” />

<intercept-url pattern=”/post.html” access=”hasRole(‘ROLE_TELLER’)” />

–>

<intercept-url pattern=”/**” access=”permitAll” />

<form-login />

<logout />

<remember-me />

<!–

Uncomment to enable X509 client authentication support

<x509 />

–>

<!– Uncomment to limit the number of sessions a user can have –>

<session-management invalid-session-url=”/timeout.jsp”>

<concurrency-control max-sessions=”1″ error-if-maximum-exceeded=”true” />

</session-management>

</http>
上面这段是初用者比较容易出错的地方,这其实也是写这篇文章的主要原因之一,注意到第一行的黑体字:

<http use-expressions=”true”>

表示这里的配置可以使用一种表达式,这种表达式就是类似于isAuthenticated()这样的写法,在后面会看到与这种写法不一样但同样可以达到相同效果的写法。

intercept-url表示要拦截的url形式,比如

<intercept-url pattern=”/secure/**” access=”isAuthenticated()” />

表示根目录下的secure目录需要经过验证后才能访问的。

<form-login />是Spring Security自动为你生成的一个简陋的登录页面,即使你没有创建任何登录页面,当然你也可以修改,但不建议你修改,因为你可以不使用默认的,可以采用如下方式:<form-login login-page=’/ login.html’/>自定义一个登录页面。

其他的说明可以参考一个翻译的中文文档:

http://www.family168.com/tutorial/springsecurity3/html/ns-config.html

3、容易出错的地方

在上面的翻译文档(也是翻译自官方文档)或英文官方文档中,给出的与上面例子功能相似的说明大概是这样的:

  <http auto-config='true'>
    <intercept-url pattern="/**" access="ROLE_USER" />
  </http>

注意到与上面例子不同的地方了吗?

还是注意第一行,这回不是<http use-expressions=”true”>而是<http auto-config=’true’>了,而下面的配置

<intercept-url pattern=”/**” access=”ROLE_USER” />也与上面的写法不同,事实上如果是<http use-expressions=”true”>的话,这句access=”ROLE_USER”就是错的,正确的写法就应该为:hasRole(‘ROLE_USER’)。

这不得不说这是Spring Security的文档与例子不搭配的一个低级错误,因为当一个使用者在打开例子又看到文档说明时,他往往不知道这两者有何区别,就如同我刚使用的时候一样,我在使用<http use-expressions=”true”>的同时,将access=”ROLE_USER”这种写法也写了进来,结果可想而知,报了错!报错信息诸如:
org.apache.jasper.JasperException: java.lang.IllegalArgumentException: Failed to evaluate
expression ‘ROLE_SUPERVISOR’
就是说use-expressions这种表示法是不认识access=”ROLE_USER”这种写法的,另外,当使用了<http use-expressions=”true”>时,一定要在配置中至少有一个符合use-expressions的表示法,否则就会报类似如下错误:
org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Field or property
‘ROLE_SUPERVISOR’ cannot be found on object of type ‘org.springframework.security.web.access.
expression.WebSecurityExpressionRoot’
这个简单的配置例子大概就写这么多吧,最后说说我对Spring Security的看法,我个人觉得Spring Security的功能的确是很强大,考虑得也非常全面,几乎什么都想替使用者做完,但正是它的这点,我觉得倒是它的缺点,在我了解它并配置的过程中,我个人觉得是非常复杂繁琐的,而且它现在的文档支持也并不好,正如上面所看到的一样,文档与例子中的写法都不一致。事实上,使用者并不希望它什么都做到,比如它做的那个缺省登录页面,那个有意义吗?使用者比如我,其实就是希望一个很简单的权限判断,比如我打开某一个链接,然后你告诉我访问者有无权限访问,给我返回一个类似true或false的结果就够了!至于其他的事情,我是如何的处理后续过程并不用Spring Security操心的

 

 

做网站,贵在坚持。希望大家有空多访问我的网站:http://www.cnblogs.com/dairongle/

你可能感兴趣的:(Security)