1. 程式人生 > >Sring MVC 環境下的Shiro整合測試

Sring MVC 環境下的Shiro整合測試

由於在Service層通過annotation限定了訪問許可權,並且需要根據使用者許可權進行業務資料過濾,因此shiro官方提供的方案實現不了。如果只是簡單的需求,可以參照官方文件

shiro配置

為了能夠整合測試,需要為shiro單獨設立一個測試用的配置檔案,和執行時配置檔案相比唯一的區別是使用了不同的SecurityManager,由於整合測試環境並不是真正的Web環境,所以使用DefaultSecurityManager.

applicationContext-shiro-test.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
       default-lazy-init="false">

    <bean id="securityManager" class="org.apache.shiro.mgt.DefaultSecurityManager">
        <property name="realm" ref="shiroDbRealm"/>
        <!--<property name="cacheManager" ref="shiroEhcacheManager" />-->
    </bean>
</beans>

測試基類

@ContextConfiguration({"classpath:spring/applicationContext.xml"})
@ActiveProfiles("dev")
public abstract class AbstractServiceTests extends AbstractTransactionalJUnit4SpringContextTests {
}

整合shiro的測試基類

@ContextConfiguration({"classpath:spring/applicationContext.xml", "classpath:/spring/applicationContext-shiro-test.xml"})
public abstract class AbstractServiceTestWithShiro extends AbstractServiceTests {
    private static ThreadState subjectThreadState;
    @Autowired
    private DefaultSecurityManager securityManager;


    protected void login(String userName, String password){
        assertTrue("userName can not be empty or null.", !StringUtils.isAnyEmpty(userName));
        assertTrue("password can not be empty or null.", !StringUtils.isAnyEmpty(password));
        setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        subject.login(new UsernamePasswordToken(userName, password));
    }


    private void setSubject(Subject subject){
        doClearSubject();
        createThreadState(subject).bind();
    }


    private Subject getSubject(){
        return SecurityUtils.getSubject();
    }


    private ThreadState createThreadState(Subject subject){
        return new SubjectThreadState(subject);
    }


    private static void setSecurityManager(SecurityManager securityManager){
        SecurityUtils.setSecurityManager(securityManager);
    }


    private SecurityManager getSecurityManager(){
        return SecurityUtils.getSecurityManager();
    }


    private void doClearSubject(){
        if(subjectThreadState != null){
            subjectThreadState.clear();
            subjectThreadState = null;
        }
    }


    @After
    public void tearDown(){
        SecurityUtils.getSubject().logout();
    }
}

具體測試類

public class MarketActionServiceTest extends AbstractServiceTestWithShiro {
    @Autowired
    private MarketActionService marketActionService;


    @Test
    public void getAllByDivisionManager(){
        login("user01","123456");
        Page<MarketAction> page = marketActionService.getAll(1, "專案");
        int rows = jdbcTemplate.queryForObject("select count(*) from ila_market_action where brief like ?", Integer.class, "%專案%");
        assertEquals(page.getTotalElements(), rows);
        assertEquals(page.getSize(), 10);
    }


    @Test
    public void getAllBySales(){
        login("user02", "123456");
        Page<MarketAction> page = marketActionService.getAll(1, "");
        int rows = jdbcTemplate.queryForObject("select count(*) from ila_market_action where brief like ? and user_id = ?", Integer.class, new Object[]{"%%", ((User)SecurityUtils.getSubject().getPrincipal()).getId()});
        assertEquals(rows, page.getTotalElements());
    }


}