继续,先来看看登录功能能简化到什么程度:
ModelAndView mv = new ModelAndView();
try{
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(login_name,login_password);
subject.login(token);
mv.setViewName("redirect:/home");
}
catch(Exception ex){
ex.printStackTrace();
mv.addObject("errorMessage", ex.getMessage());
mv.setViewName("login");
}
return mv;
正如上一篇说的,我们的APP只需要与Subject打交道,是吧,所以,简单到我们只需要做三件事:一得到subject,二封装一个UsernamePasswordToken,三登录。
但是,没完,真得这么简单吗?
背后我们还有一些事情需要做的,因为我们都是做WEB项目的,所以常规教程中的本地APP就不弄了,直接集成到SpringMVC的WEB项目中来做演示代码吧。本文的示例代码我放在Github上(http://github.com/sharetop/shiro-example)。
一一道来。
1:因为我们都是使用maven,所以,需要先在pom中增加相关的三个引用,我们都是WEB项目,除了core以外,还要shiro-web和shiro-spring,这个很好理解。
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.3</version>
</dependency>
2:修改web.xml文件,通过filter将shiro套进去,让所有的请求都进入安全的通道。注意两点,一是名称要与applicationContext中的对应上(比如叫shiroFilter),二是注意到这个class其实是springframework自带的,而不是shiro提供的,说明其实shiro只是借助spring的过滤器proxy代理到它在applicationContext中定义的filter中即可。
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3:修改applicationContext,这是重头戏,其实用spring,修改配置文件总是重头戏。
- 先装配一个realm(自定义的,稍后再详谈这个东西),
- 再装配一个securityManager,让它知道我有一个安全realm,
- 然后再装配一个shiroFilter,名字就是我们在web.xml中配置的那个,属性较多,比较重要的包括securityManager,loginUrl,filterChainDefinitions,见示例。
<bean id="helloWorldRealm" class="cn.chinaunicom.woplus.shiro.HelloWorld.HelloWorldRealm"/>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realms">
<list>
<ref bean="helloWorldRealm" />
</list>
</property>
</bean>
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login" />
<property name="filters">
<map/>
</property>
<property name="filterChainDefinitions">
<value>
/login = anon
/** = user
</value>
</property>
</bean>
4:自定义realm,以后再单聊这个。事实上,shiro为我们定义了一些缺省的realm,但个人以为,用处不大,没必要深究。
最后,我的示例代码放在GitHub上了,可以随意查阅。地址是:https://github.com/sharetop/shiro-example
欢迎讨论。