【Shiro + Spring MVC整合】教程——权限控制

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

2、项目的架构


3、配置web.xml

[java] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <web-appversion="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. <display-name>simpleSpringMCV</display-name>
  7. <!--加载文件-->
  8. <context-param>
  9. <param-name>contextConfigLocation</param-name>
  10. <param-value>
  11. classpath:applicationContext-shiro.xml
  12. </param-value>
  13. </context-param>
  14. <!--shiro-->
  15. <filter>
  16. <filter-name>shiroFilter</filter-name>
  17. <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  18. <init-param>
  19. <param-name>targetFilterLifecycle</param-name>
  20. <param-value>true</param-value>
  21. </init-param>
  22. </filter>
  23. <filter-mapping>
  24. <filter-name>shiroFilter</filter-name>
  25. <url-pattern>/*</url-pattern>
  26. </filter-mapping>
  27. <!--加载springmvc-->
  28. <servlet>
  29. <servlet-name>SpringMVC</servlet-name>
  30. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  31. <init-param>
  32. <param-name>contextConfigLocation</param-name>
  33. <param-value>classpath:mvc.xml</param-value>
  34. </init-param>
  35. <load-on-startup>1</load-on-startup>
  36. </servlet>
  37. <!--以.htm结尾的都被mvc拦截-->
  38. <servlet-mapping>
  39. <servlet-name>SpringMVC</servlet-name>
  40. <url-pattern>*.htm</url-pattern>
  41. </servlet-mapping>
  42. <!--启动spring加载-->
  43. <listener>
  44. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  45. </listener>
  46. </web-app>

4、配置applicationContext-shiro.xml

[java] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <beansxmlns="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/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">
  6. <beanid="shiroFilter"class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
  7. <propertyname="securityManager"ref="securityManager"/>
  8. <propertyname="successUrl"value="/member/index.htm"/>
  9. <propertyname="loginUrl"value="/login.htm"/>
  10. <propertyname="unauthorizedUrl"value="/error.htm"/>
  11. <propertyname="filters">
  12. <map>
  13. <entrykey="authc"value-ref="shiro"></entry>
  14. </map>
  15. </property>
  16. <propertyname="filterChainDefinitions">
  17. <value>
  18. /login.htm=anon
  19. /submit.htm=anon
  20. /error.htm=anon
  21. /member/**=authc,roles["member"]
  22. </value>
  23. </property>
  24. </bean>
  25. <beanid="shiro"class="com.cat.shiro.ShiroFilter">
  26. </bean>
  27. <beanid="shiroRealm"class="com.cat.shiro.ShiroRealm"/>
  28. <beanid="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
  29. <propertyname="realm"ref="shiroRealm"/>
  30. <!--需要使用cache的话加上这句
  31. <propertyname="cacheManager"ref="shiroEhcacheManager"/>
  32. -->
  33. </bean>
  34. <!--用户授权信息Cache,采用EhCache,需要的话就配置上此信息
  35. <beanid="shiroEhcacheManager"class="org.apache.shiro.cache.ehcache.EhCacheManager">
  36. <propertyname="cacheManagerConfigFile"value="classpath:ehcache-shiro.xml"/>
  37. </bean>
  38. -->
  39. <beanid="lifecycleBeanPostProcessor"class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
  40. <bean
  41. class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
  42. depends-on="lifecycleBeanPostProcessor">
  43. <propertyname="proxyTargetClass"value="true"/>
  44. </bean>
  45. <bean
  46. class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
  47. <propertyname="securityManager"ref="securityManager"/>
  48. </bean>
  49. </beans>

5、配置mvc.xml

[java] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <beansxmlns="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-scanbase-package="com.cat.spring.controller"/>
  15. <!--mvc返回页面的配置-->
  16. <beanid="viewResolver"
  17. class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  18. <!--模板路径为WEB-INF/pages/-->
  19. <propertyname="prefix">
  20. <value>/WEB-INF/pages/</value>
  21. </property>
  22. <!--视图模板后缀为.JSP-->
  23. <propertyname="suffix">
  24. <value>.jsp</value>
  25. </property>
  26. </bean>
  27. </beans>

6、创建ShiroFilter和ShiroRealm

ShiroFilter.java

[java] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /**
  2. *
  3. */
  4. packagecom.cat.shiro;
  5. importjava.io.IOException;
  6. importjava.security.Principal;
  7. importjavax.servlet.Filter;
  8. importjavax.servlet.FilterChain;
  9. importjavax.servlet.FilterConfig;
  10. importjavax.servlet.ServletException;
  11. importjavax.servlet.ServletRequest;
  12. importjavax.servlet.ServletResponse;
  13. importjavax.servlet.http.HttpServletRequest;
  14. importjavax.servlet.http.HttpServletResponse;
  15. importorg.apache.shiro.SecurityUtils;
  16. importorg.apache.shiro.authc.UsernamePasswordToken;
  17. importorg.apache.shiro.subject.Subject;
  18. importcom.cat.spring.entity.Role;
  19. importcom.cat.spring.entity.User;
  20. /**
  21. *@authorchenlf
  22. *
  23. *2014-3-24
  24. */
  25. publicclassShiroFilterimplementsFilter{
  26. /*
  27. *(non-Javadoc)
  28. *
  29. *@seejavax.servlet.Filter#destroy()
  30. */
  31. @Override
  32. publicvoiddestroy(){
  33. //TODOAuto-generatedmethodstub
  34. }
  35. /*
  36. *(non-Javadoc)
  37. *
  38. *@seejavax.servlet.Filter#doFilter(javax.servlet.ServletRequest,javax.servlet.ServletResponse,javax.servlet.FilterChain)
  39. */
  40. @Override
  41. publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)
  42. throwsIOException,ServletException{
  43. HttpServletRequesthttpRequest=(HttpServletRequest)request;
  44. HttpServletResponsehttpResponse=(HttpServletResponse)response;
  45. Principalprincipal=httpRequest.getUserPrincipal();
  46. if(principal!=null){
  47. Subjectsubjects=SecurityUtils.getSubject();
  48. //为了简单,这里初始化一个用户。实际项目项目中应该去数据库里通过名字取用户:
  49. //例如:Useruser=userService.getByAccount(principal.getName());
  50. Useruser=newUser();
  51. user.setName("shiro");
  52. user.setPassword("123456");
  53. user.setRole(newRole("member"));
  54. if(user.getName().equals(principal.getName())){
  55. UsernamePasswordTokentoken=newUsernamePasswordToken(user.getName(),user
  56. .getPassword());
  57. subjects=SecurityUtils.getSubject();
  58. subjects.login(token);
  59. subjects.getSession();
  60. }else{
  61. //如果用户为空,则subjects信息登出
  62. if(subjects!=null){
  63. subjects.logout();
  64. }
  65. }
  66. }
  67. chain.doFilter(httpRequest,httpResponse);
  68. }
  69. /*
  70. *(non-Javadoc)
  71. *
  72. *@seejavax.servlet.Filter#init(javax.servlet.FilterConfig)
  73. */
  74. @Override
  75. publicvoidinit(FilterConfigarg0)throwsServletException{
  76. //TODOAuto-generatedmethodstub
  77. }
  78. }

ShiroRealm.java

[java] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /**
  2. *
  3. */
  4. packagecom.cat.shiro;
  5. importjava.util.ArrayList;
  6. importjava.util.List;
  7. importorg.apache.shiro.authc.AuthenticationException;
  8. importorg.apache.shiro.authc.AuthenticationInfo;
  9. importorg.apache.shiro.authc.AuthenticationToken;
  10. importorg.apache.shiro.authc.SimpleAuthenticationInfo;
  11. importorg.apache.shiro.authc.UsernamePasswordToken;
  12. importorg.apache.shiro.authz.AuthorizationException;
  13. importorg.apache.shiro.authz.AuthorizationInfo;
  14. importorg.apache.shiro.authz.SimpleAuthorizationInfo;
  15. importorg.apache.shiro.realm.AuthorizingRealm;
  16. importorg.apache.shiro.subject.PrincipalCollection;
  17. importcom.cat.spring.entity.Role;
  18. importcom.cat.spring.entity.User;
  19. /**
  20. *@authorchenlf
  21. *
  22. *2014-3-24
  23. */
  24. publicclassShiroRealmextendsAuthorizingRealm{
  25. /*
  26. *(non-Javadoc)
  27. *
  28. *@seeorg.apache.shiro.realm.AuthorizingRealm#doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)
  29. */
  30. @Override
  31. protectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipals){
  32. //根据用户配置用户与权限
  33. if(principals==null){
  34. thrownewAuthorizationException("PrincipalCollectionmethodargumentcannotbenull.");
  35. }
  36. Stringname=(String)getAvailablePrincipal(principals);
  37. List<String>roles=newArrayList<String>();
  38. //简单默认一个用户与角色,实际项目应Useruser=userService.getByAccount(name);
  39. Useruser=newUser("shiro","123456");
  40. Rolerole=newRole("member");
  41. user.setRole(role);
  42. if(user.getName().equals(name)){
  43. if(user.getRole()!=null){
  44. roles.add(user.getRole().getName());
  45. }
  46. }else{
  47. thrownewAuthorizationException();
  48. }
  49. SimpleAuthorizationInfoinfo=newSimpleAuthorizationInfo();
  50. //增加角色
  51. info.addRoles(roles);
  52. returninfo;
  53. }
  54. /*
  55. *(non-Javadoc)
  56. *
  57. *@seeorg.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)
  58. */
  59. @Override
  60. protectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokenauthcToken)
  61. throwsAuthenticationException{
  62. UsernamePasswordTokentoken=(UsernamePasswordToken)authcToken;
  63. //简单默认一个用户,实际项目应Useruser=userService.getByAccount(token.getUsername());
  64. Useruser=newUser("shiro","123456");
  65. if(user==null){
  66. thrownewAuthorizationException();
  67. }
  68. SimpleAuthenticationInfoinfo=null;
  69. if(user.getName().equals(token.getUsername())){
  70. info=newSimpleAuthenticationInfo(user.getName(),user.getPassword(),getName());
  71. }
  72. returninfo;
  73. }
  74. }

7、配置对应的Controller文件

LoginController.java

[java] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /**
  2. *
  3. */
  4. packagecom.cat.spring.controller;
  5. importorg.apache.shiro.SecurityUtils;
  6. importorg.apache.shiro.authc.UsernamePasswordToken;
  7. importorg.apache.shiro.subject.Subject;
  8. importorg.springframework.stereotype.Controller;
  9. importorg.springframework.web.bind.annotation.RequestMapping;
  10. importorg.springframework.web.bind.annotation.RequestMethod;
  11. importorg.springframework.web.servlet.ModelAndView;
  12. importcom.cat.spring.entity.Role;
  13. importcom.cat.spring.entity.User;
  14. /**
  15. *@authorchenlf
  16. *
  17. *2014-3-24
  18. */
  19. @Controller
  20. publicclassLoginController{
  21. @RequestMapping(value="/login",method=RequestMethod.GET)
  22. publicModelAndViewlogin(){
  23. returnnewModelAndView("/login");
  24. }
  25. @RequestMapping(value="/submit",method=RequestMethod.POST)
  26. publicModelAndViewsubmit(Stringusername,Stringpassword){
  27. Useruser=newUser("shiro","123456");
  28. user.setRole(newRole("member"));
  29. try{
  30. //如果登陆成功
  31. if(user.getName().equals(username)&&user.getPassword().equals(password)){
  32. UsernamePasswordTokentoken=newUsernamePasswordToken(user.getName(),user
  33. .getPassword().toString());
  34. Subjectsubject=SecurityUtils.getSubject();
  35. subject.login(token);
  36. }
  37. }catch(Exceptione){
  38. e.printStackTrace();
  39. }
  40. returnnewModelAndView("redirect:/member/index.htm");
  41. }
  42. }
IndexController.java

[java] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /**
  2. *
  3. */
  4. packagecom.cat.spring.controller.member;
  5. importorg.springframework.stereotype.Controller;
  6. importorg.springframework.web.bind.annotation.RequestMapping;
  7. importorg.springframework.web.bind.annotation.RequestMethod;
  8. importorg.springframework.web.servlet.ModelAndView;
  9. /**
  10. *@authorchenlf
  11. *
  12. *2014-3-24
  13. */
  14. @Controller
  15. @RequestMapping(value="/member")
  16. //会员中心要被拦截
  17. publicclassIndexController{
  18. //拦截/index.htm方法为GET的请求
  19. @RequestMapping(value="/index",method=RequestMethod.GET)
  20. publicModelAndViewindex(){
  21. ModelAndViewview=newModelAndView();
  22. view.setViewName("/member/index");
  23. returnview;
  24. }
  25. }

8、对应的jsp 就不写了


9、来看看效果图吧

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

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值