1、准备Shiro的架包和spring 的架包
2、项目的架构
3、配置web.xml
- <?xmlversion="1.0"encoding="UTF-8"?>
- <web-appversion="2.5"xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
- http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
- <display-name>simpleSpringMCV</display-name>
- <!--加载文件-->
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>
- classpath:applicationContext-shiro.xml
- </param-value>
- </context-param>
- <!--shiro-->
- <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>
- <!--加载springmvc-->
- <servlet>
- <servlet-name>SpringMVC</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:mvc.xml</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <!--以.htm结尾的都被mvc拦截-->
- <servlet-mapping>
- <servlet-name>SpringMVC</servlet-name>
- <url-pattern>*.htm</url-pattern>
- </servlet-mapping>
- <!--启动spring加载-->
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener>
- </web-app>
4、配置applicationContext-shiro.xml
- <?xmlversion="1.0"encoding="UTF-8"?>
- <beansxmlns="http://www.springframework.org/schema/beans"
- xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsdhttp://www.springframework.org/schema/data/jpahttp://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd">
- <beanid="shiroFilter"class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <propertyname="securityManager"ref="securityManager"/>
- <propertyname="successUrl"value="/member/index.htm"/>
- <propertyname="loginUrl"value="/login.htm"/>
- <propertyname="unauthorizedUrl"value="/error.htm"/>
- <propertyname="filters">
- <map>
- <entrykey="authc"value-ref="shiro"></entry>
- </map>
- </property>
- <propertyname="filterChainDefinitions">
- <value>
- /login.htm=anon
- /submit.htm=anon
- /error.htm=anon
- /member/**=authc,roles["member"]
- </value>
- </property>
- </bean>
- <beanid="shiro"class="com.cat.shiro.ShiroFilter">
- </bean>
- <beanid="shiroRealm"class="com.cat.shiro.ShiroRealm"/>
- <beanid="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <propertyname="realm"ref="shiroRealm"/>
- <!--需要使用cache的话加上这句
- <propertyname="cacheManager"ref="shiroEhcacheManager"/>
- -->
- </bean>
- <!--用户授权信息Cache,采用EhCache,需要的话就配置上此信息
- <beanid="shiroEhcacheManager"class="org.apache.shiro.cache.ehcache.EhCacheManager">
- <propertyname="cacheManagerConfigFile"value="classpath:ehcache-shiro.xml"/>
- </bean>
- -->
- <beanid="lifecycleBeanPostProcessor"class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
- <bean
- class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
- depends-on="lifecycleBeanPostProcessor">
- <propertyname="proxyTargetClass"value="true"/>
- </bean>
- <bean
- class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
- <propertyname="securityManager"ref="securityManager"/>
- </bean>
- </beans>
5、配置mvc.xml
- <?xmlversion="1.0"encoding="UTF-8"?>
- <beansxmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.0.xsd
- http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
- <mvc:annotation-driven/>
- <!--自动扫描包-->
- <context:component-scanbase-package="com.cat.spring.controller"/>
- <!--mvc返回页面的配置-->
- <beanid="viewResolver"
- class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <!--模板路径为WEB-INF/pages/-->
- <propertyname="prefix">
- <value>/WEB-INF/pages/</value>
- </property>
- <!--视图模板后缀为.JSP-->
- <propertyname="suffix">
- <value>.jsp</value>
- </property>
- </bean>
- </beans>
6、创建ShiroFilter和ShiroRealm
ShiroFilter.java
- /**
- *
- */
- packagecom.cat.shiro;
- importjava.io.IOException;
- importjava.security.Principal;
- importjavax.servlet.Filter;
- importjavax.servlet.FilterChain;
- importjavax.servlet.FilterConfig;
- importjavax.servlet.ServletException;
- importjavax.servlet.ServletRequest;
- importjavax.servlet.ServletResponse;
- importjavax.servlet.http.HttpServletRequest;
- importjavax.servlet.http.HttpServletResponse;
- importorg.apache.shiro.SecurityUtils;
- importorg.apache.shiro.authc.UsernamePasswordToken;
- importorg.apache.shiro.subject.Subject;
- importcom.cat.spring.entity.Role;
- importcom.cat.spring.entity.User;
- /**
- *@authorchenlf
- *
- *2014-3-24
- */
- publicclassShiroFilterimplementsFilter{
- /*
- *(non-Javadoc)
- *
- *@seejavax.servlet.Filter#destroy()
- */
- @Override
- publicvoiddestroy(){
- //TODOAuto-generatedmethodstub
- }
- /*
- *(non-Javadoc)
- *
- *@seejavax.servlet.Filter#doFilter(javax.servlet.ServletRequest,javax.servlet.ServletResponse,javax.servlet.FilterChain)
- */
- @Override
- publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)
- throwsIOException,ServletException{
- HttpServletRequesthttpRequest=(HttpServletRequest)request;
- HttpServletResponsehttpResponse=(HttpServletResponse)response;
- Principalprincipal=httpRequest.getUserPrincipal();
- if(principal!=null){
- Subjectsubjects=SecurityUtils.getSubject();
- //为了简单,这里初始化一个用户。实际项目项目中应该去数据库里通过名字取用户:
- //例如:Useruser=userService.getByAccount(principal.getName());
- Useruser=newUser();
- user.setName("shiro");
- user.setPassword("123456");
- user.setRole(newRole("member"));
- if(user.getName().equals(principal.getName())){
- UsernamePasswordTokentoken=newUsernamePasswordToken(user.getName(),user
- .getPassword());
- subjects=SecurityUtils.getSubject();
- subjects.login(token);
- subjects.getSession();
- }else{
- //如果用户为空,则subjects信息登出
- if(subjects!=null){
- subjects.logout();
- }
- }
- }
- chain.doFilter(httpRequest,httpResponse);
- }
- /*
- *(non-Javadoc)
- *
- *@seejavax.servlet.Filter#init(javax.servlet.FilterConfig)
- */
- @Override
- publicvoidinit(FilterConfigarg0)throwsServletException{
- //TODOAuto-generatedmethodstub
- }
- }
ShiroRealm.java
- /**
- *
- */
- packagecom.cat.shiro;
- importjava.util.ArrayList;
- importjava.util.List;
- importorg.apache.shiro.authc.AuthenticationException;
- importorg.apache.shiro.authc.AuthenticationInfo;
- importorg.apache.shiro.authc.AuthenticationToken;
- importorg.apache.shiro.authc.SimpleAuthenticationInfo;
- importorg.apache.shiro.authc.UsernamePasswordToken;
- importorg.apache.shiro.authz.AuthorizationException;
- importorg.apache.shiro.authz.AuthorizationInfo;
- importorg.apache.shiro.authz.SimpleAuthorizationInfo;
- importorg.apache.shiro.realm.AuthorizingRealm;
- importorg.apache.shiro.subject.PrincipalCollection;
- importcom.cat.spring.entity.Role;
- importcom.cat.spring.entity.User;
- /**
- *@authorchenlf
- *
- *2014-3-24
- */
- publicclassShiroRealmextendsAuthorizingRealm{
- /*
- *(non-Javadoc)
- *
- *@seeorg.apache.shiro.realm.AuthorizingRealm#doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)
- */
- @Override
- protectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipals){
- //根据用户配置用户与权限
- if(principals==null){
- thrownewAuthorizationException("PrincipalCollectionmethodargumentcannotbenull.");
- }
- Stringname=(String)getAvailablePrincipal(principals);
- List<String>roles=newArrayList<String>();
- //简单默认一个用户与角色,实际项目应Useruser=userService.getByAccount(name);
- Useruser=newUser("shiro","123456");
- Rolerole=newRole("member");
- user.setRole(role);
- if(user.getName().equals(name)){
- if(user.getRole()!=null){
- roles.add(user.getRole().getName());
- }
- }else{
- thrownewAuthorizationException();
- }
- SimpleAuthorizationInfoinfo=newSimpleAuthorizationInfo();
- //增加角色
- info.addRoles(roles);
- returninfo;
- }
- /*
- *(non-Javadoc)
- *
- *@seeorg.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)
- */
- @Override
- protectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokenauthcToken)
- throwsAuthenticationException{
- UsernamePasswordTokentoken=(UsernamePasswordToken)authcToken;
- //简单默认一个用户,实际项目应Useruser=userService.getByAccount(token.getUsername());
- Useruser=newUser("shiro","123456");
- if(user==null){
- thrownewAuthorizationException();
- }
- SimpleAuthenticationInfoinfo=null;
- if(user.getName().equals(token.getUsername())){
- info=newSimpleAuthenticationInfo(user.getName(),user.getPassword(),getName());
- }
- returninfo;
- }
- }
7、配置对应的Controller文件
LoginController.java
- /**
- *
- */
- packagecom.cat.spring.controller;
- importorg.apache.shiro.SecurityUtils;
- importorg.apache.shiro.authc.UsernamePasswordToken;
- importorg.apache.shiro.subject.Subject;
- importorg.springframework.stereotype.Controller;
- importorg.springframework.web.bind.annotation.RequestMapping;
- importorg.springframework.web.bind.annotation.RequestMethod;
- importorg.springframework.web.servlet.ModelAndView;
- importcom.cat.spring.entity.Role;
- importcom.cat.spring.entity.User;
- /**
- *@authorchenlf
- *
- *2014-3-24
- */
- @Controller
- publicclassLoginController{
- @RequestMapping(value="/login",method=RequestMethod.GET)
- publicModelAndViewlogin(){
- returnnewModelAndView("/login");
- }
- @RequestMapping(value="/submit",method=RequestMethod.POST)
- publicModelAndViewsubmit(Stringusername,Stringpassword){
- Useruser=newUser("shiro","123456");
- user.setRole(newRole("member"));
- try{
- //如果登陆成功
- if(user.getName().equals(username)&&user.getPassword().equals(password)){
- UsernamePasswordTokentoken=newUsernamePasswordToken(user.getName(),user
- .getPassword().toString());
- Subjectsubject=SecurityUtils.getSubject();
- subject.login(token);
- }
- }catch(Exceptione){
- e.printStackTrace();
- }
- returnnewModelAndView("redirect:/member/index.htm");
- }
- }
- /**
- *
- */
- packagecom.cat.spring.controller.member;
- importorg.springframework.stereotype.Controller;
- importorg.springframework.web.bind.annotation.RequestMapping;
- importorg.springframework.web.bind.annotation.RequestMethod;
- importorg.springframework.web.servlet.ModelAndView;
- /**
- *@authorchenlf
- *
- *2014-3-24
- */
- @Controller
- @RequestMapping(value="/member")
- //会员中心要被拦截
- publicclassIndexController{
- //拦截/index.htm方法为GET的请求
- @RequestMapping(value="/index",method=RequestMethod.GET)
- publicModelAndViewindex(){
- ModelAndViewview=newModelAndView();
- view.setViewName("/member/index");
- returnview;
- }
- }
8、对应的jsp 就不写了
9、来看看效果图吧
没有登陆状态的访问/member/**被shiro拦截到登入界面
当用户(角色为member)为shiro 密码为123456时 再次登入/member/index.htm时就不会跳转到login界面了