http://blog.csdn.net/facekbook/article/details/54947730

shiro和web项目整合,实现类似真实项目的应用

本文中使用的项目架构是springMVC+mybatis,所以我们是基于搭建好的项目进行改造的。

  • 将shiro整合到web应用中
  • 登录
  • 退出
  • 认证信息在页面展现,也就是显示菜单
  • shiro的过滤器

将shiro整合到web应用中

数据库脚步

sql脚步放到项目中,项目上传到共享的资源中,文章最后给出共享url。

去除项目中不使用shiro实现认证的拦截器

    <!--拦截器 --><!-- <mvc:interceptors> <mvc:interceptor> --><!-- 用户认证拦截 --><!-- <mvc:mapping path="/**" /> <bean class="cn.itcast.ssm.controller.interceptor.LoginInterceptor"></bean> </mvc:interceptor> <mvc:interceptor> --><!-- 授权拦截 --> <!-- <mvc:mapping path="/**" /> <bean class="cn.itcast.ssm.controller.interceptor.PermissionInterceptor"></bean> </mvc:interceptor> </mvc:interceptors> --> 

添加shiro的jar包

除了前面文章提到的shiro-core相关的jar包,还需要如下:

  • 与web整合的 shiro-web-1.2.3.jar
  • 与spring整合的 shiro-spring-1.2.3.jar
  • 与ehcache整合的 shiro-ehcache-1.2.3.jar

在web.xml中配置shiro的filter

在web系统中,shiro 也是通过filter进行拦截的。filter拦截后将操作交给filterChain(过滤器炼)。shiro中提供了多个filter,在栏目 shiro的过滤器 会全部介绍 
在web中配置filter,如下:

    <!--shirofilter--><!-- shiro过滤器,DelegatingFilterProxy通过代理模式将spring容器的bean和filter关联起来 --><filter><filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <!--设置true由servlet容器控制filter的生命周期--> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> <!--设置spring容器filter的bean id,如果不设置则找与filter-name一致的bean --> <init-param> <param-name>targetBeanName</param-name> <param-value>shiroFilter</param-value> </init-param> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

新建applicationContext-shiro.xml文件

内容下图:

    <!-- web.xml中shiro的filter对应的bean --><!-- shiro的web过滤器 --><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <!-- logiUrl认证提交地址,如果没有认证通过将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 --> <property name="loginUrl" value="/login.action" /> <!-- 认证成功后统一跳转到first.action,建议不配置,shiro认证成功自动到上一个链接 --> <property name="successUrl" value="/first.action" /> <!-- 通过unauthorizedUrl指定没有权限时跳转页面 --> <property name="unauthorizedUrl" value="/refuse.jsp" /> <!-- 过滤器链定义,从上向下顺序执行,一般将/**放在最后面 --> <property name="filterChainDefinitions"> <value> <!--静态资源可以匿名访问 --> /images/** = anon /js/** = anon /styles/** = anon <!--登录验证码匿名访问--> /validatecode.jsp = anon <!--任何链接都可以不认证访问--> /** = anon </value> </property> </bean> <!--securityManager安全管理器 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="customRealm" /> </bean> <!-- 自定义的realm --> <bean id="customRealm" class="cn.itcast.ssm.shiro.CustomRealm"/>
  • 1

上面配置的CustomRealm 的内容和文章shiro权限框架详解05-shiro授权的CustomRealm一样。

测试是否整合成功

在界面输入CustomRealm 代码中的账号为 zhangsan 密码为 123 可以进入欢迎页面。 

但是并没有菜单和相关用户信息

登录功能

原理

由于登录使用的是 org.apache.shiro.web.filter.authc.FormAuthenticationFilter filter实现的,具体流程如下: 
如果用户没有认证时,请求上面配置的loginUrl进行认证,用户的身份信息和密码提交到loginUrl,FormAuthenticationFilter拦截取出request中的username和password(参数的key是可以进行配置的,下一篇blog介绍)参数值。FormAuthenticationFilter调用realm传入一个token(包含username和password),realm根据username查询用户信息,如果查询不到,返回null,FormAuthenticationFilter向request域中填充一个参数,key为shiroLoginFailure 记录异常信息。如果不为空的话,返回AuthenticationInfo 类。

修改登录页面

由于FormAuthenticationFilter的身份信息和密码的请求参数的key默认是(username和password),修改login.jsp页面的账号和密码输入框name属性值,并注释掉验证码的代码。

修改controller类

修改LoginController 的 login 方法如下:

    @RequestMapping("/login")public String login(HttpServletRequest request)throws Exception{ //如果登录失败从request中获取认证异常信息,shiroLoginFailure就是shiro异常类的全限定名 String exceptionClassName = (String) request.getAttribute("shiroLoginFailure"); if(exceptionClassName!=null){ if(UnknownAccountException.class.getName().equals(exceptionClassName)){ throw new CustomException("账号不存在"); }else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)){ throw new CustomException("用户名或密码错误"); }else { throw new Exception();//最终在异常处理器生成未知错误 } } //此方法不处理登录成功(认证成功),shiro认证成功会自动跳转到上一个请求路径。 //登录失败还到login页面 return "login"; }

这个方法只有校验不通过的时候才会执行。真正的校验方法是在自定义的realm中,校验身份是否正确。

修改认证拦截器

将所有请求都改为需要认证才能访问的。

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <!-- logiUrl认证提交地址,如果没有认证通过将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 --> <property name="loginUrl" value="/login.action" /> <!-- 认证成功后统一跳转到first.action,建议不配置,shiro认证成功自动到上一个链接 --> <property name="successUrl" value="/first.action" /> <!-- 通过unauthorizedUrl指定没有权限时跳转页面 --> <property name="unauthorizedUrl" value="/refuse.jsp" /> <!-- 自定义filter配置 --> <property name="filters"> <map> <entry key="authc" value-ref="formAuthenticationFilter"/> </map> </property> <!-- 过滤器链定义,从上向下顺序执行,一般将/**放在最后面 --> <property name="filterChainDefinitions"> <value> <!--静态资源可以匿名访问 --> /images/** = anon /js/** = anon /styles/** = anon /validatecode.jsp = anon <!-- /**=authc 表示所有的url都需要认证才能访问 --> /** = authc </value> </property> </bean>

验证登录功能

在登录界面输入账号为 zhangsan 密码为 123 验证是否登录成功,然后输入错误的账号,控制台出现下面的异常信息: 
 
如果输入密码错误: 
 
异常信息和前面Java项目演示的一样。

退出

退出不需要我们自己实现,只要去访问一个退出的url(该url是可以不存在的)即可,由LogoutFilter filter处理,清除session。在applicationContext.xml配置logoutFilter

    <!-- web.xml中shiro的filter对应的bean --><!-- shiro的web过滤器 --><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <!-- logiUrl认证提交地址,如果没有认证通过将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 --> <property name="loginUrl" value="/login.action" /> <!-- 认证成功后统一跳转到first.action,建议不配置,shiro认证成功自动到上一个链接 --> <property name="successUrl" value="/first.action" /> <!-- 通过unauthorizedUrl指定没有权限时跳转页面 --> <property name="unauthorizedUrl" value="/refuse.jsp" /> <!-- 自定义filter配置 --> <property name="filters"> <map> <entry key="authc" value-ref="formAuthenticationFilter"/> </map> </property> <!-- 过滤器链定义,从上向下顺序执行,一般将/**放在最后面 --> <property name="filterChainDefinitions"> <value> <!--静态资源可以匿名访问 --> /images/** = anon /js/** = anon /styles/** = anon /validatecode.jsp = anon <!-- 请求logout.action地址,shiro去清除session --> /logout.action = logout <!-- /**=authc 表示所有的url都需要认证才能访问 --> /** = authc </value> </property> </bean>

删除原来的退出方法。

菜单显示

修改realm从数据库查询用户信息及用户拥有的菜单设置在AuthenticatorInfo中。具体代码如下:

    /*** 用于认证*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //第一步:通过token获取身份信息 String userCode = (String) token.getPrincipal(); if (!"zhangsan".equals(userCode)) {// 这里模仿查询不到 return null; } String password = "123"; //模拟数据activeUser就是用户身份信息 ActiveUser activeUser = new ActiveUser(); activeUser.setUserid("zhangsan"); activeUser.setUsercode("zhangsan"); activeUser.setUsername("张三"); //查询菜单信息 List<SysPermission> menus = null; try { menus = sysService.findMenuListByUserId(activeUser .getUsercode()); } catch (Exception e) { e.printStackTrace(); } activeUser.setMenus(menus); //如果查询到结果返回AuthenticationInfo AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(activeUser, password, ""); return authenticationInfo; }
  • 1

上面的代码通过模拟从数据库获取数据设置到ActiveUser中。

修改FirstAction中的first方法

修改代码将获取身份信息,并放入request域中用于页面显示。

    //系统首页@RequestMapping("/first")public String first(Model model)throws Exception{ Subject subject =SecurityUtils.getSubject(); ActiveUser activeUser = (ActiveUser)subject.getPrincipal(); model.addAttribute("activeUser", activeUser); return "/first"; }

测试

在登录界面,账号输入 zhangsan , 密码输入 123 
如果成功的话,将会看到如下页面。 

shiro过滤器总结

过滤器简称 对应的Java类
anon org.apache.shiro.web.filter.authc.AnonymousFilter
authc org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authcBasic org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
perms org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
port org.apache.shiro.web.filter.authz.PortFilter
rest org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
roles org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
ssl org.apache.shiro.web.filter.authz.SslFilter
user org.apache.shiro.web.filter.authc.UserFilter
logout org.apache.shiro.web.filter.authc.LogoutFilter

各个过滤器的介绍和作用:


anon:例子/admins/**=anon 没有参数,表示可以匿名使用。


authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,FormAuthenticationFilter是表单认证,没有参数 。


roles:例子 /admins/user/** =roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/** =roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。


perms:例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。


rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method],其中method为post,get,delete等。


port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString 
是你访问的url里的?后面的参数。


authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证


ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https


user:例如/admins/user/**=user没有参数表示必须存在用户, 身份认证通过或通过记住我认证通过的可以访问,当登入操作时不做检查


注: 
anon,authcBasic,auchc,user是认证过滤器, 
perms,roles,ssl,rest,port是授权过滤器

blog的项目地址

点击进入下载页面

转载于:https://www.cnblogs.com/telwanggs/p/7118151.html

(转) shiro权限框架详解06-shiro与web项目整合(上)相关推荐

  1. (转)shiro权限框架详解06-shiro与web项目整合(下)

    http://blog.csdn.net/facekbook/article/details/54962975 shiro和web项目整合,实现类似真实项目的应用 web项目中认证 web项目中授权 ...

  2. (转)shiro权限框架详解03-shiro介绍

    http://blog.csdn.net/facekbook/article/details/54893740 shiro介绍 本文正式进入主题.本文将介绍如下内容: 什么是shiro 为什么需要学习 ...

  3. (转)shiro权限框架详解02-权限理论介绍

    http://blog.csdn.net/facekbook/article/details/54893042 权限管理解决方案 本文主要介绍权限管理的解决方法: 粗颗粒度和细颗粒度 基于url拦截 ...

  4. (转)shiro权限框架详解05-shiro授权

    http://blog.csdn.net/facekbook/article/details/54910606 本文介绍 授权流程 授权方式 授权测试 自定义授权realm 授权流程 开始构造Secu ...

  5. shiro权限框架详解02-权限理论介绍

    权限管理解决方案 本文主要介绍权限管理的解决方法: 粗颗粒度和细颗粒度 基于url拦截 使用权限管理框架 粗颗粒度和细颗粒度 什么是粗颗粒度和细颗粒度 在上一文中提到粗颗粒度和细颗粒度,但是没有细讲. ...

  6. (转) shiro权限框架详解04-shiro认证

    http://blog.csdn.net/facekbook/article/details/54906635 shiro认证 本文介绍shiro的认证功能 认证流程 入门程序(用户登录和退出) 自定 ...

  7. (转)shiro权限框架详解01-权限理论介绍

    http://blog.csdn.net/facekbook/article/details/54890365 权限管理 本文介绍权限管理的理论和权限管理的一些名词. 介绍权限管理 理解身份认证和授权 ...

  8. Shiro权限管理详解(授权和注解开发)【面试点】

    Shiro权限管理详解 1. 权限管理 1.1什么是权限管理 1.2用户身份认证 1.2.1 概念 1.2.2 用户名密码身份认证流程 1.2.3 关键对象 1.3 授权 1.3.1 概念 1.3.2 ...

  9. Shiro权限管理框架详解

    1权限管理1.1什么是权限管理 基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权 ...

最新文章

  1. The application could not be installed: INSTALL_FAILED_NO_MATCHING_ABIS
  2. 利用System.Uri转URL为绝对地址
  3. 组合查询——怎样使用窗口的继承达到事半功倍?
  4. [云炬python3玩转机器学习笔记] 2-6关于回归和分类
  5. 堆排序python代码实现_python实现堆排序
  6. python语言print函数_Python 的 print 函数
  7. idea报错Module Project1 must not contain source root ...\Project1\src. The root already belongs to m
  8. 使用Affinity Designer导出Android资产
  9. 计算机辅助设计利用计算机的,计算机基础知识:计算机辅助设计
  10. T-SQL Parser
  11. 河北工业大学 高等数学学习资料分享(课件,录屏,教材,答案)
  12. SAP 各模块常用T-Code
  13. FineReport制作报表讲解(基本操作以及网络报表)
  14. Golang interface 接口详解
  15. Linux 云服务器aircrack-ng后台跑包并用邮件发送结果
  16. @Valid注解的使用---SpringMvc中的校验框架@valid和@validation的概念及相关使用
  17. TI-Davinci开发系列之七DVSDK-4.03目录介绍
  18. 块加密 工作模式 ECB、CBC、PCBC、CFB、OFB、CTR
  19. 深度解析FUTABA的SBUS协议(/天地飞遥控器的WBUS协议/Robomaster接收机的DBUS协议)到底是啥?
  20. SVG——入门,路径变形动画

热门文章

  1. 深入理解密码学基本概念和应用
  2. (80)ADC采集方法(基于LVDS采集方法)
  3. (79)FPGA版本如何管理?
  4. (27)FPGA面试技能提升篇(UVM、VMM)
  5. sqlite3学习笔记-方法介绍和测试代码
  6. STM32 中断详解
  7. Keil(MDK-ARM-STM32)系列教程(一)_新建软件工程详细过程
  8. server sql 分组 去重 字符串拼接_SQL必知必会
  9. dubbo 配置及分析
  10. [Winform] DataGridView辅助类