编写使用SpringSecurity的JUnit测试提醒
近日在使用SpringSecurity的项目中发现一个小问题,就是在接口上加了@Secured标注限制调用接口权限时,某些JUnit无法正常调用了。
例如:
@Secured(PrivilegeDAO.ROLE_REMIND_CREATE)
public Serializable save(Users user) throws BusinessException;
调用save方法时,必须具备 PrivilegeDAO.ROLE_REMIND_CREATE权限才行。
原因很简单,执行JUnit的时候并没有经过SpringSecurity的登录把资源设置到上下文,所以是无登录权限的。而调用接口的时候又要获取执行权限,这当然造成无法调用的局面了。
花了点时间,查找资源,找到个解决方案,分享下。其实就是覆盖原来认真配置信息,然后把供单元测试用的TestingAuthenticationToken设置回spring容器当中。所以之后执行单元测试时就有权限了。注意构造TestingAuthenticationToken的时候必须根据项目具体情况来添加GrantedAuthority[]。
具体代码参考如下:
import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import org.springframework.beans.factory.BeanFactory;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.TestingAuthenticationProvider;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl; import cn.com.timekey.drugmonitor.po.Privilege; /**
* @author kennylee
*
*/
public class SecurityTestingUnit { /**
* 设置SpringSecurity的登录用户权限。
*
* @param ctx
* @param auths
*/
public static void setAuthToken(BeanFactory ctx, GrantedAuthority[] auths) {
TestingAuthenticationToken token = new TestingAuthenticationToken(
"admin", "test", auths);
// Override the regular spring configuration
ProviderManager providerManager = (ProviderManager) ctx
.getBean("authenticationManager");
List<AuthenticationProvider> list = new ArrayList<AuthenticationProvider>();
TestingAuthenticationProvider testingAuthenticationProvider = new TestingAuthenticationProvider();
list.add(testingAuthenticationProvider);
providerManager.setProviders(list); // Create and store the SpringSecurity SecureContext into the
// SecurityContextHolder.
SecurityContextImpl secureContext = new SecurityContextImpl();
secureContext.setAuthentication(token);
SecurityContextHolder.setContext(secureContext);
} /**
* 构造权限组
*
* @param rolePrivileges
* @return
*/
public static GrantedAuthority[] generateAuthorities(
Collection<Privilege> privileges) {
GrantedAuthority[] auths = new GrantedAuthority[privileges.size()];
if (!privileges.isEmpty()) {
int count = 0;
for (Privilege rolePrivilege : privileges) {
String privilegeName = rolePrivilege.getPrivilegeName();
GrantedAuthority authority = new GrantedAuthorityImpl(
privilegeName);
auths[count] = authority;
count++;
}
}
return auths;
} }
其中generateAuthorities只是我的一个辅助构造方法。不是重点内容。setAuthToken为主体代码。
JUnit testing with Acegi Security Here's a tip if you are trying to do some unit testing with Acegi Security - particularly if you are doing role based authorization of method calls on your manager objects via interception. Basically, a secure method interceptor will a) need an authentication token to play with, and b) a way to find out what authorities the user has. We need to cater for this when running the tests. Acegi Security conveniently provides a TestingAuthenticationToken for unit testing purposes so we are Ok with the token part. You will now need to provide a suitable authentication provider. Somewhat unsurprisingly, there is a TestingAuthenticationProvider that you can add to your Spring config file to accommodate this. But here is the problem: we already have this configured for production using a different provider (obviously), so we would have to resort to changing the config files depending on if you are running tests or not. This is too fragile for me, so here is the essence of the tip: leave the configuration file alone and dynamically changes the provider in the setup of the unit test. Here is some code that I have in my JUnit setUp() method: // Grant all roles to noddy.
TestingAuthenticationToken token = new TestingAuthenticationToken(
"noddy", "test", new GrantedAuthority[] {
new GrantedAuthorityImpl("User"),
new GrantedAuthorityImpl("Administrator") }); // Override the regular spring configuration
ProviderManager providerManager = (ProviderManager) ctx.getBean("authenticationManager");
List list = new ArrayList();
list.add(new TestingAuthenticationProvider());
providerManager.setProviders(list); // Create and store the Acegi SecureContext into the ContextHolder.
SecureContextImpl secureContext = new SecureContextImpl();
secureContext.setAuthentication(token);
ContextHolder.setContext(secureContext);
So... it sets up an authentication token, then resets the authentication managers' provider list with one that contains the TestingAuthenticationProvider. It then creates the context for the method execution. The problem with this is it does it for every single test method - that is how JUnit works for better or worse. Hope it proves useful for you.
参考见:http://fishdujour.typepad.com/blog/2005/02/junit_testing_w.html
编写使用SpringSecurity的JUnit测试提醒的更多相关文章
- 单元测试实战 - Junit测试
一.对加法函数进行测试 1.实例化被测单元(方法):类名 实例名=new 类名([参数]) 2.调用被测单元,对比预期值和输出值(实际值): 在没有junit测试工具的情况下,我们要进行如下的测试代码 ...
- EditBox问题的实现以及Junit测试框架的简要说明
一.这周的EditBox由一个框改为三个框,同时进行测试,下面给出程序及截图 1 import java.util.regex.Matcher; 2 import java.util.regex.Pa ...
- Android Junit测试框架
对应用进行单元测试: 使用Junit测试框架,是正规Android开发的必用技术.在Junit中可以得到组件,可以模拟发送事件和检测程序处理的正确性. 1.配置指令集和函数库: (1)配置指令集,指定 ...
- 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)
1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...
- applicationContext.xml文件放置位置不同而导致的jUnit测试的时候路径的不同
如果applicationContext.xml文件放置在src下面的的时候使用jUint测试的时候编写的路径应该是这样的: @Test public void testFindByPage() { ...
- 使用Cobertura统计JUnit测试覆盖率
这是一个JavaProject,关于Cobertura的用法详见代码注释 首先是应用代码(即被测试的代码) package com.jadyer.service; public class Calcu ...
- junit测试Android项目
关于junit测试Android项目方法主要有一下步骤: 1.导入junit4的jar包 在工厂中Build Path中Add Library->JUnit->JUnit4->Fin ...
- Java进阶(五)Junit测试
我们在编写大型程序的时候,需要写成千上万个方法或函数,这些函数的功能可能很强大,但我们在程序中只用到该函数的一小部分功能,并且经过调试可以确定,这一小部分功能是正确的.但是,我们同时应该确保每一个函数 ...
- Java高级特性 第10节 IDEA和Eclipse整合JUnit测试框架
一.IDEA整合Junit测试框架 1.安装插件 打开File菜单的下拉菜单settings[设置] : 点击左侧Plugins[插件]菜单 在输入框中输入JUnitGenerator 2.0,点击I ...
随机推荐
- APNS IOS PHP 苹果推送
IOS---APNS 消息推送实践 首先,需要一个pem的证书,该证书需要与开发时签名用的一致. 具体生成pem证书方法如下: 1. 登录到 iPhone Developer Connection P ...
- Redis - hash类型操作
hash 类型操作设置操作:hset: hset key filed value 创建指定key的filed-value名值对 hsetnx: hsetnx key file ...
- C#基础指针类型
在C#的不安全的代码书写中,类型可以是指针类型.值类型或引用类型. 指针类型声明具有下列形式之一: type* identifier; void* identifier; //allowed bu ...
- hdu 3635
http://acm.hdu.edu.cn/showproblem.php?pid=3635 1-n个城市,对应放着编号1-n的龙珠. 两种操作 T A B 把编号A的龙珠所在城市内的全部龙珠放到有编 ...
- HDU 1052
http://acm.hdu.edu.cn/showproblem.php?pid=1052 田忌赛马本质就是一个贪心 res表示田忌的胜利场次 1.田忌最快马快于王的最快马,两个最快马比,res++ ...
- The u32 classifier
The u32 classifier The U32 filter is the most advanced filter available in the current implementatio ...
- Bean实例化(Spring源码阅读)-我们到底能走多远系列(33)
我们到底能走多远系列(33) 扯淡: 各位: 命运就算颠沛流离 命运就算曲折离奇 命运就算恐吓着你做人没趣味 别流泪 心酸 更不应舍弃 ... 主题: Spring源码阅读还在继 ...
- allpaths 使用
软件下载与说明:http://www.broadinstitute.org/software/allpaths-lg/blog/?page_id=12 原始数据的深度要达到100以上. 至少要两个库, ...
- web app 的技术参考 -- 来自 【百度移动建站指南】
优化页面性能 考虑到移动设备和移动互联网的特点,在进行移动网站的页面开发设计时,一个总的原则是考虑用户访问的效率,降低页面加载时间. 下面的内容来自百度,然后我自己做了笔记.另外可参考这个系列的文章 ...
- 总结 output 用法
第一种用法 返回受 INSERT.UPDATE 或 DELETE 语句影响的每行的信息,或者返回基于上述每行的表达式.这些结果可以返回到处理应用程序, 以供在确认消息.存档以及其他类似的应用程序要求中 ...