这里有三种方式可以选择:
使用global-method-security和protect-point标签来管理全局范围的方法权限。
为了在spring中使用AOP,我们要为项目添加几个依赖库。
<dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>2.1_3</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.6.4</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.6.4</version> </dependency>
首先来看看我们将要保护的java类。
package com.family168.springsecuritybook.ch12; public class MessageServiceImpl implements MessageService { public String adminMessage() { return "admin message"; } public String adminDate() { return "admin " + System.currentTimeMillis(); } public String userMessage() { return "user message"; } public String userDate() { return "user " + System.currentTimeMillis(); } }
这里使用的是spring-2.0中的aop语法,对MessageService中所有以admin开头的方法进行权限控制,限制这些方法只能由ROLE_ADMIN调用。
<global-method-security> <protect-pointcut expression="execution(* com.family168.springsecuritybook.ch12.MesageServiceImpl.admin*(..))" access="ROLE_ADMIN"/> </global-method-security>
现在只有拥有ROLE_ADMIN权限的用户才能调用MessageService中以admin开头的方法了,当我们以user/user登陆系统时,尝试调用MessageService类的adminMessage()会跑出一个“访问被拒绝”的异常。
在bean中嵌入intercept-methods和protect标签。
这需要改造配置文件。
<beans:bean id="messageService" class="com.family168.springsecuritybook.ch12.MessageServiceImpl"> <intercept-methods> <protect access="ROLE_ADMIN" method="userMessage"/> </intercept-methods> </beans:bean>
现在messageService中的userMessage()方法只允许拥有ROLE_ADMIN权限的用户才能调用了。
使用intercept-methods面临着几个问题
首先,intercept-methods只能使用jdk14的方式拦截实现了接口的类,而不能用cglib直接拦截无接口的类。
其次,intercept-methods和global-method-security一起使用,同时使用时,global-method-security一切正常,intercept-methods则会完全不起作用。
借助jdk5以后支持的annotation,我们直接在代码中设置某一方法的调用权限。
现在有两种选择,使用Spring Security提供的Secured注解,或者使用jsr250规范中定义的注解。
首先修改global-method-security中的配置,添加支持annotation的参数。
<global-method-security secured-annotations="enabled"/>
然后添加依赖包。
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core-tiger</artifactId> <version>2.0.4</version> </dependency>
现在我们随便在java代码中添加注解了。
package com.family168.springsecuritybook.ch12;
import org.springframework.security.annotation.Secured;
public class MessageServiceImpl implements MessageService {
@Secured({"ROLE_ADMIN", "ROLE_USER"})
public String userMessage() {
return "user message";
}
}
在Secured中设置了ROLE_ADMIN和ROLE_USER两个权限,只要当前用户拥有其中任意一个权限都可以调用这个方法。
首先还是要修改配置文件。
<global-method-security secured-annotations="enabled"
jsr250-annotations="enabled"/>
然后添加依赖包。
<dependency> <groupId>javax.annotation</groupId> <artifactId>jsr250-api</artifactId> <version>1.0</version> </dependency>
现在可以在代码中使用jsr250中的注解了。
package com.family168.springsecuritybook.ch12; import javax.annotation.security.DenyAll; import javax.annotation.security.PermitAll; import javax.annotation.security.RolesAllowed; public class MessageServiceImpl implements MessageService { @RolesAllowed({"ROLE_ADMIN", "ROLE_USER"}) public String userMessage() { return "user message"; } @DenyAll public String userMessage2() { return "user message"; } @PermitAll public String userMessage2() { return "user message"; } }
从实际使用上来讲,jsr250里多出来的DenyAll和PermitAll纯属浪费,谁会定义谁也不能调用的方法呢?实际上,要是annotation支持布尔操作就好了,比如逻辑并,逻辑或,逻辑否之类的。
还有jsr250中未被支持的RunAs注解,如果能利用起来估计更有趣。
实例在ch201。