【Shiro + Spring MVC整合】教程

来源:互联网 发布:动画生成软件 编辑:程序博客网 时间:2024/06/05 14:23

1、准备Shiro的架包和spring 的架包

2、项目的架构


3、配置web.xml

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
  5.     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
  6.   
  7.     <display-name>simpleSpringMCV</display-name>  
  8.   
  9.     <!-- 加载文件 -->  
  10.     <context-param>  
  11.         <param-name>contextConfigLocation</param-name>  
  12.         <param-value>  
  13.             classpath:applicationContext-shiro.xml  
  14.         </param-value>  
  15.     </context-param>  
  16.   
  17.     <!-- shiro -->  
  18.     <filter>  
  19.         <filter-name>shiroFilter</filter-name>  
  20.         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  21.         <init-param>  
  22.             <param-name>targetFilterLifecycle</param-name>  
  23.             <param-value>true</param-value>  
  24.         </init-param>  
  25.     </filter>  
  26.     <filter-mapping>  
  27.         <filter-name>shiroFilter</filter-name>  
  28.         <url-pattern>/*</url-pattern>  
  29.     </filter-mapping>  
  30.   
  31.   
  32.     <!-- 加载springmvc -->  
  33.     <servlet>  
  34.         <servlet-name>SpringMVC</servlet-name>  
  35.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  36.         <init-param>  
  37.             <param-name>contextConfigLocation</param-name>  
  38.             <param-value>classpath:mvc.xml</param-value>  
  39.         </init-param>  
  40.         <load-on-startup>1</load-on-startup>  
  41.     </servlet>  
  42.   
  43.     <!-- 以.htm结尾的都被mvc拦截 -->  
  44.     <servlet-mapping>  
  45.         <servlet-name>SpringMVC</servlet-name>  
  46.         <url-pattern>*.htm</url-pattern>  
  47.     </servlet-mapping>  
  48.     <!-- 启动spring 加载 -->  
  49.   
  50.     <listener>  
  51.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  52.     </listener>  
  53. </web-app>  

4、配置applicationContext-shiro.xml
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd">  
  6.       
  7.     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  8.         <property name="securityManager" ref="securityManager" />  
  9.         <property name="successUrl" value="/member/index.htm" />  
  10.         <property name="loginUrl" value="/login.htm" />  
  11.         <property name="unauthorizedUrl" value="/error.htm" />  
  12.         <property name="filters">  
  13.             <map>  
  14.                 <entry key="authc" value-ref="shiro"></entry>  
  15.             </map>  
  16.         </property>  
  17.         <property name="filterChainDefinitions">  
  18.             <value>  
  19.                 /login.htm=anon  
  20.                 /submit.htm=anon  
  21.                 /error.htm=anon  
  22.                 /member/**=authc,roles["member"]  
  23.             </value>  
  24.         </property>  
  25.     </bean>  
  26.     <bean id="shiro" class="com.cat.shiro.ShiroFilter">  
  27.   
  28.     </bean>  
  29.     <bean id="shiroRealm" class="com.cat.shiro.ShiroRealm" />  
  30.   
  31.     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  32.         <property name="realm" ref="shiroRealm" />  
  33.         <!-- 需要使用cache的话加上这句  
  34.         <property name="cacheManager" ref="shiroEhcacheManager" />  
  35.          -->  
  36.     </bean>  
  37.   
  38.     <!-- 用户授权信息Cache, 采用EhCache,需要的话就配置上此信息   
  39.     <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">  
  40.         <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml" />  
  41.     </bean>  
  42.     -->  
  43.   
  44.     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />  
  45.     <bean  
  46.         class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"  
  47.         depends-on="lifecycleBeanPostProcessor">  
  48.         <property name="proxyTargetClass" value="true" />  
  49.     </bean>  
  50.     <bean  
  51.         class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
  52.         <property name="securityManager" ref="securityManager" />  
  53.     </bean>  
  54. </beans>  

5、配置mvc.xml

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xmlns:mvc="http://www.springframework.org/schema/mvc"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  7.         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  8.         http://www.springframework.org/schema/context  
  9.         http://www.springframework.org/schema/context/spring-context-3.0.xsd   
  10.         http://www.springframework.org/schema/mvc  
  11.         http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">  
  12.     <mvc:annotation-driven/>  
  13.     <!-- 自动扫描包 -->  
  14.     <context:component-scan base-package="com.cat.spring.controller" />  
  15.   
  16.     <!-- mvc返回页面的配置 -->  
  17.     <bean id="viewResolver"  
  18.         class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  19.         <!-- 模板路径为WEB-INF/pages/ -->  
  20.         <property name="prefix">  
  21.             <value>/WEB-INF/pages/</value>  
  22.         </property>  
  23.         <!-- 视图模板后缀为.JSP -->  
  24.         <property name="suffix">  
  25.             <value>.jsp</value>  
  26.         </property>  
  27.     </bean>  
  28.   
  29. </beans>  

6、创建ShiroFilter和ShiroRealm

ShiroFilter.java

  1. package com.cat.shiro;  
  2.   
  3. import java.io.IOException;  
  4. import java.security.Principal;  
  5.   
  6. import javax.servlet.Filter;  
  7. import javax.servlet.FilterChain;  
  8. import javax.servlet.FilterConfig;  
  9. import javax.servlet.ServletException;  
  10. import javax.servlet.ServletRequest;  
  11. import javax.servlet.ServletResponse;  
  12. import javax.servlet.http.HttpServletRequest;  
  13. import javax.servlet.http.HttpServletResponse;  
  14.   
  15. import org.apache.shiro.SecurityUtils;  
  16. import org.apache.shiro.authc.UsernamePasswordToken;  
  17. import org.apache.shiro.subject.Subject;  
  18.   
  19. import com.cat.spring.entity.Role;  
  20. import com.cat.spring.entity.User;  
  21.   
  22. /** 
  23.  * @author chenlf 
  24.  *         2014-3-24 
  25.  */  
  26. public class ShiroFilter implements Filter {  
  27.   
  28.     /* 
  29.      * (non-Javadoc) 
  30.      *  
  31.      * @see javax.servlet.Filter#destroy() 
  32.      */  
  33.     @Override  
  34.     public void destroy() {  
  35.   
  36.     }  
  37.   
  38.     /* 
  39.      * (non-Javadoc) 
  40.      *  
  41.      * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) 
  42.      */  
  43.     @Override  
  44.     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  
  45.             throws IOException, ServletException {  
  46.          
  47.         HttpServletRequest httpRequest = (HttpServletRequest) request;  
  48.         HttpServletResponse httpResponse = (HttpServletResponse) response;  
  49.         Principal principal = httpRequest.getUserPrincipal();  
  50.   
  51.         if (principal != null) {  
  52.             Subject subjects = SecurityUtils.getSubject();  
  53.             // 为了简单,这里初始化一个用户。实际项目项目中应该去数据库里通过名字取用户:  
  54.             // 例如:User user = userService.getByAccount(principal.getName());  
  55.             User user = new User();  
  56.             user.setName("shiro");  
  57.             user.setPassword("123456");  
  58.             user.setRole(new Role("member"));  
  59.             if (user.getName().equals(principal.getName())) {  
  60.                 UsernamePasswordToken token = new UsernamePasswordToken(user.getName(), user  
  61.                         .getPassword());  
  62.                 subjects = SecurityUtils.getSubject();  
  63.                 subjects.login(token);  
  64.                 subjects.getSession();  
  65.             } else {  
  66.                 // 如果用户为空,则subjects信息登出  
  67.                 if (subjects != null) {  
  68.                     subjects.logout();  
  69.                 }  
  70.             }  
  71.         }  
  72.         chain.doFilter(httpRequest, httpResponse);  
  73.   
  74.     }  
  75.   
  76.     /* 
  77.      * (non-Javadoc) 
  78.      *  
  79.      * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) 
  80.      */  
  81.     @Override  
  82.     public void init(FilterConfig arg0) throws ServletException {  
  83.         // TODO Auto-generated method stub  
  84.   
  85.     }  
  86.   
  87. }  

ShiroRealm.java

  1. /** 
  2.  *  
  3.  */  
  4. package com.cat.shiro;  
  5.   
  6. import java.util.ArrayList;  
  7. import java.util.List;  
  8.   
  9. import org.apache.shiro.authc.AuthenticationException;  
  10. import org.apache.shiro.authc.AuthenticationInfo;  
  11. import org.apache.shiro.authc.AuthenticationToken;  
  12. import org.apache.shiro.authc.SimpleAuthenticationInfo;  
  13. import org.apache.shiro.authc.UsernamePasswordToken;  
  14. import org.apache.shiro.authz.AuthorizationException;  
  15. import org.apache.shiro.authz.AuthorizationInfo;  
  16. import org.apache.shiro.authz.SimpleAuthorizationInfo;  
  17. import org.apache.shiro.realm.AuthorizingRealm;  
  18. import org.apache.shiro.subject.PrincipalCollection;  
  19.   
  20. import com.cat.spring.entity.Role;  
  21. import com.cat.spring.entity.User;  
  22.   
  23. /** 
  24.  * @author chenlf 
  25.  *  
  26.  *         2014-3-24 
  27.  */  
  28. public class ShiroRealm extends AuthorizingRealm {  
  29.   
  30.     /* 
  31.      * (non-Javadoc) 
  32.      *  
  33.      * @see org.apache.shiro.realm.AuthorizingRealm#doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection) 
  34.      */  
  35.     @Override  
  36.     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  
  37.         // 根据用户配置用户与权限  
  38.         if (principals == null) {  
  39.             throw new AuthorizationException("PrincipalCollection method argument cannot be null.");  
  40.         }  
  41.         String name = (String) getAvailablePrincipal(principals);  
  42.         List<String> roles = new ArrayList<String>();  
  43.         // 简单默认一个用户与角色,实际项目应User user = userService.getByAccount(name);  
  44.         User user = new User("shiro", "123456");  
  45.         Role role = new Role("member");  
  46.         user.setRole(role);  
  47.         if (user.getName().equals(name)) {  
  48.             if (user.getRole() != null) {  
  49.                 roles.add(user.getRole().getName());  
  50.             }  
  51.         } else {  
  52.             throw new AuthorizationException();  
  53.         }  
  54.         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  
  55.         // 增加角色  
  56.         info.addRoles(roles);  
  57.         return info;  
  58.     }  
  59.   
  60.     /* 
  61.      * (non-Javadoc) 
  62.      *  
  63.      * @see org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken) 
  64.      */  
  65.     @Override  
  66.     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)  
  67.             throws AuthenticationException {  
  68.         UsernamePasswordToken token = (UsernamePasswordToken) authcToken;  
  69.         // 简单默认一个用户,实际项目应User user = userService.getByAccount(token.getUsername());  
  70.         User user = new User("shiro", "123456");  
  71.         if (user == null) {  
  72.             throw new AuthorizationException();  
  73.         }  
  74.         SimpleAuthenticationInfo info = null;  
  75.         if (user.getName().equals(token.getUsername())) {  
  76.             info = new SimpleAuthenticationInfo(user.getName(), user.getPassword(), getName());  
  77.         }  
  78.         return info;  
  79.     }  
  80. }  

7、配置对应的Controller文件

LoginController.java

  1. /** 
  2.  *  
  3.  */  
  4. package com.cat.spring.controller;  
  5.   
  6. import org.apache.shiro.SecurityUtils;  
  7. import org.apache.shiro.authc.UsernamePasswordToken;  
  8. import org.apache.shiro.subject.Subject;  
  9. import org.springframework.stereotype.Controller;  
  10. import org.springframework.web.bind.annotation.RequestMapping;  
  11. import org.springframework.web.bind.annotation.RequestMethod;  
  12. import org.springframework.web.servlet.ModelAndView;  
  13.   
  14. import com.cat.spring.entity.Role;  
  15. import com.cat.spring.entity.User;  
  16.   
  17. /** 
  18.  * @author chenlf 
  19.  *  
  20.  *         2014-3-24 
  21.  */  
  22. @Controller  
  23. public class LoginController {  
  24.     @RequestMapping(value = "/login", method = RequestMethod.GET)  
  25.     public ModelAndView login() {  
  26.         return new ModelAndView("/login");  
  27.     }  
  28.   
  29.     @RequestMapping(value = "/submit", method = RequestMethod.POST)  
  30.     public ModelAndView submit(String username, String password) {  
  31.         User user = new User("shiro", "123456");  
  32.         user.setRole(new Role("member"));  
  33.         try {  
  34.             // 如果登陆成功  
  35.             if (user.getName().equals(username) && user.getPassword().equals(password)) {  
  36.                 UsernamePasswordToken token = new UsernamePasswordToken(user.getName(), user  
  37.                         .getPassword().toString());  
  38.                 Subject subject = SecurityUtils.getSubject();  
  39.                 subject.login(token);  
  40.             }  
  41.         } catch (Exception e) {  
  42.             e.printStackTrace();  
  43.         }  
  44.   
  45.         return new ModelAndView("redirect:/member/index.htm");  
  46.     }  
  47. }  
IndexController.java
  1. package com.cat.spring.controller.member;  
  2.   
  3. import org.springframework.stereotype.Controller;  
  4. import org.springframework.web.bind.annotation.RequestMapping;  
  5. import org.springframework.web.bind.annotation.RequestMethod;  
  6. import org.springframework.web.servlet.ModelAndView;  
  7.   
  8. /** 
  9.  * @author chenlf 
  10.  *    2014-3-24 
  11.  */  
  12. @Controller  
  13. @RequestMapping(value = "/member")  
  14. //会员中心要被拦截  
  15. public class IndexController {  
  16.     // 拦截/index.htm 方法为GET的请求  
  17.     @RequestMapping(value = "/index", method = RequestMethod.GET)  
  18.     public ModelAndView index() {  
  19.         ModelAndView view = new ModelAndView();  
  20.         view.setViewName("/member/index");  
  21.         return view;  
  22.     }  
  23.   
  24. }  
8、对应的jsp 就不写了


9、来看看效果图吧

没有登陆状态的访问/member/**被shiro拦截到登入界面

当用户(角色为member)为shiro 密码为123456时 再次登入/member/index.htm时就不会跳转到login界面了


0 0
原创粉丝点击