近日在使用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; } } |