如果你看到这篇文章,你一定知道shiro是干嘛用的,如果真的真的不知道。。。
那么请先移步:shiro



好了,聪明的你现在一定知道shiro是干嘛用的了,你应该知道,shiro不是web框架,所有你要先搭建好一个web项目,我这里用的是ssm,你也可以用比好好玩的jFianl或者nutz。那么怎么去用呢。

本章目录

  • maven示例
  • springMVC配置文件
  • web.xml
  • 简单的Realm
  • 简单的shiro配置文件
  • MyController.java
  • 部分jsp页面
  • 开启shiro注解

工欲善其事必先利其器,要用到的shiro包与spring包

maven示例

    <!-- SpringMVC核心jar --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>3.2.4.RELEASE</version></dependency><!--shiro配置--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.4.0</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>1.4.0</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.4.0</version></dependency>

喜欢直接用jar包的同学也可以直接到maven仓库下载,别忘记spring相关jar包哦。
ok,开始coding…项目的构建与目录结构我相信你会操作的
因为使用springMVC框架,就简单的配置一下它的配置文件吧,我就假装你很懒,就直接贴出来了

springMVC配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.2.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.2.xsd"><!--配置的注解所使用的处理器--><context:component-scan base-package="com.yk"/><!-- 启用SpringMVC的注解功能,它会自动注册HandlerMapping、HandlerAdapter、ExceptionResolver的相关实例 --><mvc:annotation-driven/><!-- 配置SpringMVC的视图解析器 --><!-- 其viewClass属性的默认值就是org.springframework.web.servlet.view.JstlView --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/"/><property name="suffix" value=".jsp"/></bean><!-- 由于web.xml中设置是:由SpringMVC拦截所有请求,于是在读取静态资源文件的时候就会受到影响(说白了就是读不到) --><!-- 经过下面的配置,该标签的作用就是:所有页面中引用"/js/**"的资源,都会从"/resources/js/"里面进行查找 --><!-- 我们可以访问http://IP:8080/xxx/js/my.css和http://IP:8080/xxx/resources/js/my.css对比出来 --><mvc:resources mapping="/js/**" location="/WEB-INF/resources/js/"/><mvc:resources mapping="/css/**" location="/WEB-INF/resources/css/"/><!-- 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证 --><bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"><property name="proxyTargetClass" value="true" /></bean><bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"><property name="securityManager" ref="securityManager"/></bean>
</beans>

好了,我们再去配置一下web.xml,也全部贴出来了哦

web.xml

<?xml version="1.0" encoding="UTF-8" ?>
<web-app version="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/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><display-name>Archetype Created Web Application</display-name><!-- spring的监听器 --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/applicationContext*.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- Shiro --><filter><filter-name>shiroFilter</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter-mapping><filter-name>shiroFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- 配置springmvc servlet --><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:dispatcher-servlet.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><!-- / 表示所有的请求都要经过此serlvet --><url-pattern>/</url-pattern></servlet-mapping><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list></web-app>

这里有两点要注意:
1.shiro过滤器一定要在springmvc配置前面。为什么呢,因为有些访问地址是要进行权限鉴定的,如果直接走springmvc配置,不管有没有权限就直接跳转成功了,而不会经过shiro判断。
2.shiro过滤器的url-pattern必须是/* ,我之前跟springMVC配置一样写的/,启动是没问题,但是一登陆就报错 ,下面会解释到。

这时候就可以启动项目,看会不会访问到index.jsp。

访问成功,继续往下。

Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。

百度百科解释的很清楚了,我们执行登陆时会把用户相关信息放到‘realm’中进行登陆校验,然后在访问其他路径时可以拿到该配置进行访问权限鉴定。
好了,我们来写一个试试。

简单的Realm

public class MyRealm extends AuthorizingRealm {/*** 权限认证* @param principals* @return*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 获取登录用户名String username = (String)principals.getPrimaryPrincipal();System.out.println("username==="+username);/*** 根据用户名取数据库用户信息,此处用数据表示* UserInfo info = userService.findByName(loginName);*/UserInfo user = new UserInfo(username,"123456","admin");if(user != null) {//权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission)SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();//用户的角色集合Set roles = new HashSet();roles.add(user.getRole());info.setRoles(roles);//用户的角色对应的所有权限List<String> permissions = new ArrayList<String>();permissions.add("user:query");permissions.add("user:update");info.addStringPermissions(permissions);return info;}// 直接返回null,shiro管理器会处抛出异常return null;}/*** 登录认证* @param token* @return* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {//UsernamePasswordToken对象用来存放提交的登录信息UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;/*** 根据用户名取数据库用户信息,此处用数据表示* UserInfo info = userService.findByName(loginName);*/UserInfo user = new UserInfo(token.getUsername(),"123456","admin");if(user!=null){//若存在,将此用户存放到登录认证info中return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());}return null;}
}

继承AuthorizingRealm类,实现方法doGetAuthorizationInfodoGetAuthenticationInfo,分别是权限认证与登陆认证,具体逻辑后面介绍。

接着编写shiro的配置文件

简单的shiro配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- 配置权限管理器 --><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><!-- ref对应我们写的realm  MyShiro --><property name="realm" ref="myRealm"/><!-- 使用下面配置的缓存管理器 --><property name="cacheManager" ref="cacheManager"/></bean><bean id="myRealm" class="com.yk.MyRealm"/><bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" /><!-- 配置shiro的过滤器工厂类,id- shiroFilter要和我们在web.xml中配置的过滤器一致 --><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><!-- 调用我们配置的权限管理器 --><property name="securityManager" ref="securityManager"/><!-- 配置我们的登录请求地址 --><property name="loginUrl" value="/login"/><!-- 配置我们在登录页登录成功后的跳转地址,如果你访问的是非/login地址,则跳到您访问的地址 --><property name="successUrl" value="/home"/><!-- 如果您请求的资源不再您的权限范围,则跳转到/403请求地址 --><property name="unauthorizedUrl" value="/unauthorized"/><!-- 权限配置 --><property name="filterChainDefinitions"><value><!-- anon表示此地址不需要任何权限即可访问 -->/login = anon/home = anon/static/**= anon<!-- authc表示此地址需要登陆才可访问 -->/query = authc</value></property></bean><bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /></beans>

这是一个非常简单的shiro配置文件,复杂的可以集成cacher,自定义session等等

接着写一个登陆

MyController.java

@Controller
public class MyController {@InitBinder("userInfo")public void initBinder1(WebDataBinder binder) {binder.setFieldDefaultPrefix("userInfo.");}@RequestMapping("/home")public String home(){return "home";}@RequestMapping("/login")public String login(){return "login";}@RequestMapping(value = "/doLogin",method = RequestMethod.POST)public String doLogin(UserInfo userInfo, RedirectAttributes redirectAttributes){System.out.println(userInfo.toString());try {//使用权限工具进行用户登录,登录成功后跳到shiro配置的successUrl中,与下面的return没什么关系!SecurityUtils.getSubject().login(new UsernamePasswordToken(userInfo.getUsername(), userInfo.getPassword()));}catch (AuthenticationException e) {redirectAttributes.addFlashAttribute("message", "用户名或密码错误");return "redirect:/login";}return "redirect:/home";}@RequestMapping("/loginOut")public String loginOut(){SecurityUtils.getSubject().logout();return "redirect:/home";}@RequiresRoles("admin1")@RequestMapping("/query")public String query(){return "query";}@RequestMapping("/unauthorized")public String unauthorized(){return "redirect:/unauthorized";}}

Subject:即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。但考虑到大多数目的和用途,你可以把它认为是Shiro的“用户”概念。
SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。

login–>SecurityManager –>doGetAuthenticationInfo(登陆认证)
所以在MyRealm中的doGetAuthenticationInfo 可以直接获取UsernamePasswordToken 对象(登陆用户),拿到用户名去数据库查询用户信息,最后new SimpleAuthenticationInfo 中的第二个参数放的是从数据库查出来的密码,shiro会自己去校验登陆密码是否正确。
我们再来看看doGetAuthorizationInfo方法中principals.getPrimaryPrincipal()获取的是一个Object,它的内容取决于new SimpleAuthenticationInfo 中的第一个参数。所以我这里放的是username,所以取到的只能是String类型,如果放的是UserInfo,则可以这样写UserInfo user = (UserInfo)principals.getPrimaryPrincipal();

部分jsp页面

index.jsp

<html>
<body>
<h2>Hello World!</h2>
</body>
<script>window.location.href="/home";
</script>
</html>

home.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<html>
<head><title>home</title>
</head>
<body>this is home page.<br><shiro:notAuthenticated><%--未登录--%>please <a href="/login">login</a> now!</shiro:notAuthenticated><shiro:authenticated><%--已登陆-%>hello <shiro:principal/><%--用户名--%>,you can<ol><li><a href="/loginOut">loginOut</a></li><li><a href="/query">query</a></li></ol></shiro:authenticated>
</body>
</html>

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>login</title>
</head>
<body><form action="/doLogin" method="post">用户:<input type="text" name="userInfo.username">密码:<input type="text" name="userInfo.password"><input type="submit" value="登录"></form></body>
</html>

注意:前面说过shiro过滤器配置的url-pattern/* ,如果为/ 的话,在SecurityUtils.getSubject().login时会报500错误,无法解析shiro注解

那么去掉页面的shiro注解后,登录正常,但是访问/query进行权限认证时,依然报500异常:org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton. This is an invalid application configuration.

后来我在/query时打印SecurityUtils.getSubject(),显示为null
我的猜测是url-pattern/时拦截了shiro必要的文件,导致页面无法解析shiro注解,管理器也无法记住登录的用户。

注意:
页面作权限判断时,引入shiro标签库<%@ taglib prefix=”shiro” uri=”http://shiro.apache.org/tags” %>

启动项目访问

可以把home看作首页,可以浏览一些有权限的东西,点击跳到登陆页面

点击登陆,再次跳到home页面

我们发现显示的内容不一样了,可以查询,可以登出了
点击loginOut会跳到home再次显示please login now!因为SecurityUtils.getSubject().logout();会把用户信息清除。

query.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><h1>this is query page.</h1>
</head>
<body></body>
</html>

unauthorized.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><h1>unauthorized!!!</h1>
</head>
<body></body>
</html>

点击query

这是为啥呢?怎么显示的是unauthorized!!!呢
这时候要先在springMVC配置文件加入有关shiro的配置

开启shiro注解

 <!-- 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证 --><bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"><property name="proxyTargetClass" value="true" /></bean><bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"><property name="securityManager" ref="securityManager"/></bean><!-- shiro无权限异常处理 --><bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"><property name="exceptionMappings"><props><prop key="org.apache.shiro.authz.UnauthorizedException">unauthorized</prop><!--<prop key="org.apache.shiro.authz.UnauthenticatedException">jsp/unauthorized</prop><prop key="org.apache.shiro.authz.AuthorizationException">jsp/unauthorized</prop><prop key="java.lang.Throwable">jsp/unauthorized</prop>--></props></property></bean>

注意:这个配置如果在shiro配置文件中是不生效的,必须放在springMVC配置文件中

注意看清楚,访问/query时加了一个注解@RequiresRoles(“admin1”)

@RequiresRoles:角色鉴定
@RequiresPermissions:权限鉴定

而我在doGetAuthorizationInfo 中加入角色是admin,所以在鉴定角色时出错,没有admin1的角色权限,就会报UnauthorizedException(无权限) 异常,通过配置会跳到/unauthorized页面。

注意: shiro配置文件中的<property name="unauthorizedUrl" value="/unauthorized"/> 是不生效的

把admin1改成admin

有权限,显示正常页面。

后续更新一些其他的集成
好累,休息一下。。。

shiro权限鉴定框架相关推荐

  1. Apache Shiro权限控制框架简介

    Apache Shiro权限控制框架简介 要想实现权限控制,可以自己写代码实现,蓄力都的权限控制可以通过过滤器Filter实现,细粒度的权限控制是基于代理对象结合自定义的注解和反射技术来实现,反射技术 ...

  2. shiro放行_Shiro框架详解 tagline

    部分面试资料链接:https://pan.baidu.com/s/1qDb2YoCopCHoQXH15jiLhA 密码:jsam 想获得全部面试必看资料,关注公众号,大家可以在公众号后台回复" ...

  3. springboot shiro权限管理

    集成shiro大概分这么一个步骤: (一) pom.xml中添加Shiro依赖: (二) 注入Shiro Factory和SecurityManager. (三) 身份认证 (四) 权限控制 一:po ...

  4. activiti 工作流 springboot 后台框架平台 集成代码生成器 shiro 权限

    QQ 313596790 官网:www.fhadmin.org 下载地址 工作流模块---------------------------------------------------------- ...

  5. 权限控制框架Shiro简单介绍及配置实例

    Shiro是什么 Apache Shiro是一个非常易用的Java安全框架它能提供验证.授权.加密和Session控制.Shiro非常轻量级而且API也非常易于理解可以使用Shiro完成从APP到企业 ...

  6. java权限框架_Java高级工程师必备技术栈-由浅入深掌握Shiro权限框架

    权限系统在任何一个系统中都存在,随着分布式系统的大行其道,权限系统也趋向服务化,对于一个高级工程师来说,权限系统的设计是必不可少需要掌握的技术栈 Apache Shiro™是一个功能强大且易于使用的J ...

  7. 权限验证框架Shiro

    权限验证框架Shiro: Shiro简介 什么是Shiro: shiro是一个强大易用的Java安全框架,提供了认证,授权,加密,回话管理等功能: 认证(Authentication):用户身份识别, ...

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

    http://blog.csdn.net/facekbook/article/details/54947730 shiro和web项目整合,实现类似真实项目的应用 本文中使用的项目架构是springM ...

  9. 视频教程-Apache Shiro权限框架实战+项目案例视频课程-Java

    Apache Shiro权限框架实战+项目案例视频课程 拥有10余年项目实战经验. 2006-2011在nttdata从事对日软件开发类工作. 2011-2015在HP从事技术服务工作. 擅长于j2e ...

最新文章

  1. Why HashMap Extends AbstractMap and Implement Map
  2. [LeetCode] 93. Restore IP Addresses_Medium tag: backtracking
  3. python3.7下载包的命令_python3.7中安装paddleocr及paddlepaddle包的多种方法
  4. 从R-CNN到Mask R-CNN
  5. 参观北京移动信息港森华易腾机房
  6. 解决Redmi 6 pro底部出现黑边问题
  7. coolite TreeNode NodeClick传id到后台的方法
  8. linux删除磁盘后刷新,linux – 短暂的文件是否刷新到磁盘?
  9. lamp怎么使用mysql_lamp(四)mysql操作
  10. R语言系列:自定义function
  11. bzoj 1670: [Usaco2006 Oct]Building the Moat护城河的挖掘(凸包)
  12. sqlserver自动备份脚本
  13. 基于ARM-LINUX的温度传感器驱动-DS18B20
  14. [C++]##(两个井号)和#(一个井号)都是什么意思
  15. JAVASE复习计划
  16. 服务器远程开多个桌面,远程桌面多开,远程桌面多开的工具介绍,操作方法
  17. esxi虚拟化服务器端口聚合,配置链路聚合组处理分布式端口组的流量
  18. Mybatis plus 修改密码
  19. 计算机技能测试题五,计算机基本技能测试题(第五套
  20. 私域流量sop社群运营规划工作计划表格方案模板2022

热门文章

  1. 【科普】气垫船是如何浮在水面上行驶的
  2. c#的decode用法
  3. LiveQing流媒体RTMP推流服务-如何获直播流地址 HLS/HTTP-FLV/WS-FLV/WebRTC/RTMP视频流地址
  4. 面试中怎样谈自己的缺点?
  5. iOS9.0 canOpenURL: failed for URL: xx - error:This app is not allowed to query for scheme xx
  6. ld: library not found for -l.... 问题的解决
  7. 编写python代码实现打开并登录网页、对网页进行点击、输入信息等操作
  8. vue:tabel和form 分别动态生成 列 与 文本框
  9. 晶品特装科创板上市:市值68亿 主打地面无人装备研发与产销
  10. 怎么在电脑的右键新建菜单添加.py或者其他格式的文件