shiro登录验证 怎么配置验证失

shiro在应用程序中的使用是用Subject为入口的, 最终subject委托给真正的管理者ShiroSecurityMannager
Realm是Shiro获得身份认证信息和来源信息的地方(所以这里是我们实现的)我们只要继承他的实现类重写方法就好了,AuthorizingRealm&
身份认证过程
自定义realm代码
public class myRealm
extends AuthorizingRealm
//realm的名称
public String getName() {
// TODO Auto-generated method stub
return "myRealm";
//验证token是否是有效的token
public boolean supports(AuthenticationToken arg0) {
// TODO Auto-generated method stub
return arg0 instanceof UsernamePasswordT
//授权获得用户权限信息的方法
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
info.addRole("321");
info.addRole("3332");
info.addStringPermission("333");
info.addStringPermission("555");
info.addObjectPermission(new WildcardPermission("44"));
// TODO Auto-generated method stub
//认证获取用户身份信息的方法
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken loginToken=(UsernamePasswordToken)
String password=new String(loginToken.getPassword());
System.out.println(password);
System.out.println(loginToken.getUsername());
if(loginToken.getUsername()=="zhang"&&password.equals("123")){
throw new IncorrectCredentialsException();
// TODO Auto-generated method stub
SimpleAuthenticationInfo info= new SimpleAuthenticationInfo(loginToken.getUsername(),password,getName());
doGetAuthorizationInfo方法是进行用户授权的时候调用的方法 用户获得当前用户的授权信息 先不管他doGetAuthenticationInfo是当我们调用subject.login进行认证的方法
这个方法的参数token就是我们subject.login调用的这里面我们就可以查询数据库对用户名和密码进行认证 如果认证成功将用户信息封装成SimpleAuthenticationInfo 认证失败根据几种情况抛出异常,常见的如:DisabledAccountException(禁用的帐号)、LockedAccountException(锁定的帐号)UnknownAccountException(错误的帐号)ExcessiveAttemptsException(登录失败次数过多)、IncorrectCredentialsException (错误的凭证)ExpiredCredentialsException(过期的凭证)等
shiro.ini配置
#声明一个realm
myRealm1=com.liqiang.realm.myRealm
#这里就是我们注入realm的地方
securityManager.realms=$myRealm1
实现身份认证的代码
public void testHelloworld() {
//1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
Factory&org.apache.shiro.mgt.SecurityManager& factory =
new IniSecurityManagerFactory("classpath:shiro.ini");
//2、得到SecurityManager实例 并绑定给SecurityUtils
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
//3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
//4、登录,即身份验证
subject.login(token);
} catch (AuthenticationException e) {
//5、身份验证失败
subject.logout();
上面我们调用sbuject.login(token) 这个token封装了前端用户输入的用户名和密码
&当我们通过subject.isPermitted("user:update") 当我们判断当前用户是否拥有user:update这个权限代码的时候
会调用我们ream的&doGetAuthorizationInfo 方法获得授权信息。我们在这里面就是根据用户信息查询数据将认证信息封装
SimpleAuthorizationInfo 返回回去
//授权获得用户权限信息的方法
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
info.addRole("321");
info.addRole("3332");
info.addStringPermission("333");
info.addStringPermission("555");
info.addObjectPermission(new WildcardPermission("44"));
// TODO Auto-generated method stub
这里通过查询数据库知道用户有321 &332 &这2个角色 和&333 &&555 &&44 &这几个权限
WildcardPermission 这个又是什么意思呢。。通过addStringPermission
默认是用Permission的实现类封装的 如果我们又定义就用我们的封装 没有定义就用默认的WildcardPermission最终将他们保存到一个集合里面如:
public class MyPermission implements Permission {
String permissionC
public MyPermission(String name) {
permissionCode=
public boolean implies(Permission permission) {
//自定义比较
// TODO Auto-generated method stub
return false;
当我们调用subject.isPermitted("user:update")会调用将指令传达给
SecurityManager
SecurityManager 再将指令传达给授权管理类Authorizer
Authorizer会通过reaml获得授权信息SimpleAuthorizationInfo如果我们返回的授权信息拥有角色 会调用RolePermissionResolver实现类的方法 将角色的权限追加到SimpleAuthorizationInfo(默认是没有实现的)如:
public class MyRolePermissionResolver
implements RolePermissionResolver{
public Collection&Permission& resolvePermissionsInRole(String roleString) {
// TODO Auto-generated method stub
return Arrays.asList((Permission)new MyPermission("menu:*"));
这里面应该是根据角色查询权限&
最终 遍历SimpleAuthorizationInfo的权限信息 (我们的权限信息都封装Permission接口实现类 调用implies方法进行比较 如果比较成功返回true 表示授权通过)自定义Permission的好处就是我们可以自定义匹配规则
注入自定义Permission和RolePerminssion的配置
authorizer=org.apache.shiro.authz.ModularRealmAuthorizer
securityManager.authorizer=$authorizer
#自定义rolePermissionResolver
rolePermissionResolver=com.liqiang.permissionResolver.MyRolePermissionResolver
authorizer.rolePermissionResolver=$rolePermissionResolver
securityManager.authorizer=$authorizer
permissionResolver=com.liqiang.permissionResolver.MyPermissionResolver
authorizer.permissionResolver=$permissionResolver
#声明一个realm
myRealm1=com.liqiang.realm.myRealm
#指定securityManager的realms实现
securityManager.realms=$myRealm1
&PS:好记性不如烂笔头 &希望自己回头来看一下就能回忆起来
& & & & 学习文章:http://jinnianshilongnian.iteye.com/blog/2018398
阅读(...) 评论()在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
shiro 验证失败后,shiroLoginFailure中保存的一直是AuthenticationException类的名称,得不到AuthenticationException子类的名称
比如我在doGetAuthenticationInfo中抛出UnknownAccountException异常,但是shiroLoginFailure中不会是UnknownAccountException的类名,而是AuthenticationException的。
有人碰到这种情况吗?
shiro版本1.3.2无论使用FormAuthenticationFilter,还是 SecurityUtils.getSubject().login方法,抛出任何AuthenticationException的子类异常,shiroLoginFailure中保存的一直是AuthenticationException类的名称
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
知道原因了。使用了ModularRealmAuthenticator的原因。无解。
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。发布于 08/10 18:27
由于公司前端引进新的技术react,改变了传统的jsp模式,逐渐走上前后端分离的,并且随着小程序,手机端业务的发展,越来越多的项目在开始往上面迁移,这就导致了权限问题。于是也就开启了sso项目,一个人挖坑一个人填,终于是上线了。
没人指引,没人会,导致了我现在百度里面搜索了sso单点登录,当时发现的是有个鉴权验证的,需要第三方服务,cas实现,搞了一天,门都没摸到,淘汰。后来在网上看到有人用shiro来做sso系统,然后开启了shiro的了解之路。
我介绍更多的是我机遇shiro做的sso项目,对于shiro是啥,网上很多都有介绍,源码我没看,只知道他大概的实现原理,所以本人是小白一名,深入理解不了,见谅。
#sso系统设想
当用户登录的时候,登录验证后,把userInfo信息和一个token对应(UUID生成),放入redis中token为key,userInfo为value,并且把token返回给前端,要求前端每次访问数据必须请求头中放token
提供一个HTTP接口,让各个系统都放入到filter里面,每次数据接口请求,需要传递我token以及当前数据请求路径,sso判断是否有权限请求该接口,
sso需要验证登录,需要验证数据请求权限,需要支持分布式部署
自定义Realm
&bean id=&upmsRealm& class=&com.xxx.controller.shiro.UpmsRealm&&
&property name=&credentialsMatcher& ref=&credentialsMatcher&/&
当调用 SecurityUtils.getSubject().login(ssoUserNameToken)的时候,会调用重写的方法
自定义PermissionResolver
&!-- 自定义Realm --&
&bean id=&upmsRealm& class=&com.ruhnn.controller.shiro.UpmsRealm&&
&property name=&credentialsMatcher& ref=&credentialsMatcher&/&
&property name=&PermissionResolver& ref=&urlPermissionResolver&/&
* @param principalCollection
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//该处为伪代码
UserInfo userInfo = (UserInfo) SecurityUtils.getSubject().getPrincipal();
byte[] value = redisClient.get(userInfo.getToken());
if (value != null) {
userInfo = SerializeUtil.deserialize(value, UserInfo.class);
String key = SsoConstants.REDIS_ROLE_KEY + userInfo.getToken() + &-& + userInfo.getWebId();
Set&String& allPermissions = new HashSet&&();
byte[] bytes = redisClient.get(key);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setStringPermissions(allPermissions);
#####分布式部署
必须重写shiro的sessionDAO的管理,我这个是在github上面,有个大哥写的案例,现在找不到了,很感谢大哥给我的启发
&!-- session管理器 --&
&bean id=&sessionManager& class=&com.ruhnn.controller.shiro.SsoSessionManager&&
&!-- 设置全局会话超时时间,默认30分钟(1800000) --&
&property name=&globalSessionTimeout& value=&&/&
&!-- 是否在会话过期后会调用SessionDAO的delete方法删除会话 默认true --&
&property name=&deleteInvalidSessions& value=&true&/&
&!-- 会话验证器调度时间 --&
&property name=&sessionValidationInterval& value=&1800000&/&
&!-- session存储的实现 --&
&property name=&sessionDAO& ref=&redisCacheSessionDAO&/&
&property name=&sessionIdCookie.name& value=&SSO-SESSIONID&/&
&!--&/bean&--&
&!-- 会话Session ID生成器 --&
&bean id=&sessionIdGenerator& class=&com.ruhnn.controller.shiro.JavaUuidSessionIdGenerator&/&
&bean id=&redisCacheSessionDAO& class=&com.ruhnn.controller.shiro.RedisCacheSessionDAO&&
&property name=&sessionIdGenerator& ref=&sessionIdGenerator&/&
public class RedisCacheSessionDAO extends AbstractSessionDAO {
//该处需要重写抽象方法
运用shiro的请求拦截,自定义了一些拦截方法
&!-- Shiro过滤器 --&
&bean id=&shiroFilter& class=&org.apache.shiro.spring.web.ShiroFilterFactoryBean&&
&!-- Shiro的核心安全接口,这个属性是必须的 --&
&property name=&securityManager& ref=&securityManager&/&
&!-- 身份认证失败,则跳转到登录页面的配置 --&
&property name=&loginUrl& value=&/index&/&
&!-- 权限认证失败,则跳转到指定页面 --&
&property name=&unauthorizedUrl& value=&/index&/&
&!--登陆成功--&
&property name=&successUrl& value=&/index&/&
&property name=&filters&&
&util:map&
&entry key=&token& value-ref=&tokenUserFilter&/&
&entry key=&validate& value-ref=&validateUserFilter&/&
&entry key=&expire& value-ref=&expireTokenUserFilter&/&
&/util:map&
&/property&
&!-- Shiro连接约束配置,即过滤链的定义 --&
&property name=&filterChainDefinitions&&
/login/** = anon
/logout/** = logout
/static/**= anon
/** = token,validate,expire
&/property&
token:验证只能请求token的鉴权路径,其他路径一律拦截返回错误
validate:验证是否有token,token是否有效
expire:延长用户token过期时间
以上是我花费1个月研究出来的sso系统,没人做技术指导,有的只是需求,有的只是对技术的执着,我不知道我这种实现方式有什么不妥,目前系统已经上线允许,也许是没人搞我们系统,也许是走了狗屎运,目前运行一切正常。记录一下 自己这次的成就,感觉又要逆天了 哈哈哈哈
& 著作权归作者所有
人打赏支持
码字总数 1123
分布式单点登录框架 XXL-SSO XXL-SSO 是一个分布式单点登录框架。只需要登录一次就可以访问所有相互信任的应用系统。 其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码,...
Smart QQ交流群:(提供开发工具和文档下载) 简述 Smart定位用当下最流行的SSM(SpringMVC + Spring + Mybatis)技术,为您构建一个易理解、高可用、高扩展性的单点登录权限管理应用...
转载地址: http://www.aboutyun.com/thread-.html 问题导读: 1、电商网站考虑的客户需求有哪些? 2、网站架构如何演变的? 3、电商架构优化需考虑哪些内容? 大型网站架构是一个系...
jbaowei2000
本文大纲: 1. 使用电商案例的原因 2. 电商网站需求 3. 网站初级架构 4. 系统容量估算 5. 网站架构分析 6. 网站架构优化 本文主题为电商网站架构案例,将介绍如何从电商网站的需求,到单机架...
Reliable 是分布式架构的持续集成系统,由 Macaca 团队的成员开发。适用于集成构建、集成构建等场景。她是典型的主从结构,分为 reliable-master 与 reliable-slave 两部分。 特点: 集群负载...
没有更多内容
加载失败,请刷新页面
1.背景 说起应用分层,大部分人都会认为这个不是很简单嘛 就controller,service, mapper三层。看起来简单,很多人其实并没有把他们职责划分开,在很多代码中,controller做的逻辑比service还...
一、MultipartEntityBuilder 实现文件上传步骤 在HttpCient4.3之后上传文件主要使用的类是位于org.apache.http.entity.mime下的MultipartEntityBuilder(原先的MultipartEntity已经基本弃用了...
xiaomin0322
源码在这里https://github.com/zdy1988/vue-jstree 我是vue-cli建的项目 npm install vue-jstree --save 组件里这样写 import VJstree from 'vue-jstree';import axios from "axios";exp......
iOS精选源码 JPLiquidLayout 简单易用的流式布局 labelGroupAndStreamSwift---标签分组,单选,多选 iOS采用UITableView和UIScrollView来实现Excel、课程表的上下左右... 3D Touch打开控制器...
1.到https://www.kernel.org/ 下载需要的内核版本 2.上传到操作系统 3.解压到/usr/src目录下 比如3.19内核 tar -xvf linux-3.19.tar.xz -C /usr/src 4.创建连接 cd /usr/src ln -sv /usr/sr...
tututu_jiang
没有更多内容
加载失败,请刷新页面
文章删除后无法恢复,确定取消删除此文章吗?
亲,自荐的博客将通过私信方式通知管理员,优秀的博客文章审核通过后将在博客推荐列表中显示
确定推荐此文章吗?
确定推荐此博主吗?
聚合全网技术文章,根据你的阅读喜好进行个性推荐
指定官方社区
深圳市奥思网络科技有限公司版权所有javaEE开发必用的技术 ssm框架+shiro框架实现权限控制及认证javaEE开发必用的技术 ssm框架+shiro框架实现权限控制及认证从小白到架构师百家号本文将使用spring,springmvc,mybatis,shiro都是最新版本的框架+JDK1.8完成用户登录模块的DEMO,该DEMO具备较完善的功能,大部分项目都要做权限控制,大部分项目的思路都可以用来参照。本文使用shiro框架来完成认证和授权,同功能的框架还有一种叫做spring security,spring保安的框架,他俩的区别就是一个是Apache旗下的一个是Spring旗下的,具体哪个好你们可以自己去体验体验。shiro是基于过滤器完成权限控制的,所以我们要在web.xml中给shiro配置一个专属过滤器。但是这个过滤器是spring提供的,spring通过代理调用 shiro的过滤器,使用spring security框架时,也得这样配置。url-pattern为/*匹配所有请求,都走这个过滤器。下面我们看一下shiro在spring的配置文件中applicationContext.xml的配置。这里需要配置一个bean,此bean的名字必须与web.xml的filter-name相同,spring代理时就是通过&filter-name&shiroFilter&/filter-name&找到代理对象的,如果不配置就会抛出error,create bean shiroFilter Class not found 的异常,所以我们需要将shiro的过滤器注册到spring容器中给spring代理。这里注册的是org.apache.shiro.spring.web.ShiroFilterFactoryBean工厂类bean,shiro用的过滤器都是由这个工厂创建,其中有shiro自带的过滤器,也可以加入自定义的过滤器。我们使用shiro的登录校验时就用到了shiro的authc过滤器。该过滤器功能就是检查session中是否拥有shiro的授权,如果没有的话就要跳转到我们上访在property配置的unauthorizedUrl路径。我们注册完shiroFilter bean之后还需要为其中属性进行注入,有三个url,一个是登录用的url,校验成功url和校验失败url。另一个就是securityManager,不要在创建一个SecurityManager bean注入到spring容器中,由于这是一个接口,在启动spring时会抛出异常,我们需要在class位置填写他的实现类DefaultWebSecurityManager。那么他的作用是什么呢,有点类似dispatcherServlet它是核心方法的调用者,在shiro中处于一种指挥中心似的地位。所以我们需要使用的一些功能都是经由SecurityManager一手操办的,也是ShiroFilterFactoryBean依赖它的一个原因。然后我们需要配置一个filterChainDefinitions对过滤器链的定义。shiro底层是将所有的过滤器封装到一个linkedHashMap里面的,我们的url在访问服务器时,先经过这个过滤器链再到拦截器,最后才到servlet,filterChainDefinitions其实也是一个map,他会根据我们写的url 来取到过滤器链中的相应过滤器来执行。就是说如果写不同的url-pattern那么经过的shiro内部过滤器时不同的。shiro的过滤器有以下几种anon 这种字母是过滤器的名字缩写,shiro可以识别,以下就用字母来指代过滤器。anon的功能是一个空的过滤器,它的作用是对静态资源文件进行放行,比如图片文件,js,css等都需要使用anon过滤器,也包括登录页面,等一些特殊的url,都是可以直接进行访问。authc 该过滤器会检查访问url的session中是否拥有shiro的授权,如果没有则跳转至上面配置的校验失败页面。几乎除了几个特殊页面外,所有的url都需要经过这个过滤器,shiro会在用户登录成功之后进行授权,所以需要登录之后才能访问的url都要经过这个过滤器。roles 是一种角色管理过滤器,它能够对用户登录的账号的种类进行过滤。被roles匹配的url需要特定的用户账号才可以访问,比如管理员的账号和普通用户的账号是不一样的。perms 是一种权限过滤器,它对用户权限进行过滤,它属于进一步的划分,并不是所有roles级别都有某个权限。等等。没有使用shiro的时候我们都是在login方法中查询数据库,那么看看在使用shiro之后login方法该怎么写。一个成熟的项目的登录页面现在已经有短信登录,验证码登录以及人脸识别登录了。这里使用一种古老的技术用户名密码+字母数字组合验证码登录。先看登录页面背景图片很精美,是我从1688登录页下载下来的,看关键信息。需要用input提交的有三条数据,用户名密码验证码和一个登录submit按钮。这里的验证码是一个jsp页面,并不是ajax每隔一段时间刷新那种,也是个非常low的验证码。也就是说每次登录按钮按下是我们实际提交四条数据,除了页面上的图形验证还有jsp页面的验证码,jsp页面验证码存在session里。下面看java代码该代码中我们需要做几件事情:参数接收 用户名和密码使用实体类TUser接收参数接收 手写验证码从Session中拿出jsp页面的验证码接下来需要对验证码做几个判断,非空,不是null和不等于空串。如果if为false则重定向至登录页面并提示原因。下一步验证验证码输入是否正确,如果为false重定向并提示。接下来通过SecurityUtils.getSubject()获取一个单例的Subject对象,该对象用于绑定本地线程,每个用户访问时起一条线程,绑定的就是这个线程,它是一个自己写的Thread域,那我们拿到的subject对象就是该域的引用。下面实例化UsernamePasswordToken对象,Subject和UsernamePasswordToken都是由shiro提供的。该token需要传入用户提交过来的用户名和密码,按上图参数传入即可。到这里就结束了,写shiro的人还是非常骚气的.之前的文章里面我们不是配置了全局异常处理器吗s.login(token);方法验证成功与否需要根据异常判断,你可以自己trycatch也可以使用springmvc提供的异常处理器来处理。下面我们看看它是怎么进行用户名密码进行校验的。首先需要在spring的主配置文件中添加如下配置红框圈出来的bean是shiro提供的securityManager,他需要注入一个realm。realm是什么呢,realm就是我们自己编写的实现用户名密码验证方法的类,他还包含了授权功能。粉色箭头指向的就是realm的bean,该类由我们自己编写,稍后见下图。红色箭头是spring提供的通过注解进行代理的类,他需要注入一条属性,proxyTargetClass是选择目标代理,如果为true则底层使用cglib代理,如果不配置或者为false,默认为false时,使用JDK代理。JDK除了需要实现接口外,接口中必须封装子类所有方法,否则会出现异常。因为JDK代理使用的接口中的方法,JAVA8的default关键字已经弥补了JDK代理部分缺陷,所有这里推荐配置为true,使用false也不是不行!最后一个黑色箭头是shiro提供的切面类,通知由shiro已经编写完毕,切入点需要我们自行配置。继续上面添加完realm后我们需要编写realm中的代码,realm类必须继承shiro提供的AuthorizingRealm抽象类,这个类实现了很多接口,留给我们自己编写的就两个方法doGetAuthorizationInfodoGetAuthenticationInfo他们两个长得很像,但是可以看到中间为za的授权方法,为ca的是认证方法。下面我们就先来编写认证方法认证方法提供我们一个参数,token就是我们刚才传入用户提交的用户名和密码的token,需要将其转型成子类UsernamePasswordToken,然后获取用户名。下面要做的就是简单了,因为我使用的是mybatis,所以直接查数据库,通过token中的用户名查询密码。select * from user where username = ? 发送一个这样语句拿到数据库中的密码,如果查询不到对应密码就会抛出异常AuthenticationException,这里使用的是shiro1.4版本,如果是1.2或以下版本异常名可能不同。然后我们创建一个SimpleAuthenticationInfo对象,它相当于一个密码校验器,需要传入三个参数,第一个刚才通过username查询到得实体类对象,查询到得密码,如果你的密码在数据库中使用加密算法过的话需要将用户提交进来的密码也进行加密。第三个参数就是对象名。最后返回SimpleAuthenticationInfo对象,它里面装的是几个boolean类型的值,用来表示密码验证是否与用户提交进来的密码一致,如果不一致会抛出IncorrectCredentialsException异常。我们通过对异常进行捕获就能得出是否存在用户名和密码是否正确。到此认证方法就结束了,认证通过后将不受到authc过滤器的限制。下面是shiro的授权方法为了便于演示做了部分改动,perms过滤器是一种权限过滤器,要求访问该url时必须携带后面[]中的权限,它是一个元素为字符串的数组,所以一个url可以配置多种权限。要想使用权限我们需要在数据库中使用三张表。用户表、权限表、角色表。我们需要在realm中将这三张表连接起来,可以在数据库中创建两个中间表也可以在sql中添加创建临时表。下图为权限表。下图角色表最后是用户表他们的关系就是从用户表开始,用户表对角色表一对多。角色表对权限表是多对多的关系。下面我们为代码添加权限.添加权限有四种方式第一种就是之前图中的
/editItem = perms[&editItem&] 对url访问权限进行控制,如果没有该权限则不能访问url。第二种如图所示通过注解实现的,在方法上添加注解,没有itemList权限的用户将无法访问itemList页面。第三种为shiro标签,被标签包裹住的html代码将不会显示第四种几乎不会使用所以不需要了解。添加完权限后我们直接在realm类中完成对用户授权。记住授权方法就是中间是za的,我们先实例化SimpleAuthorizationInfo对象,它是用户权限的容器。然后通过本地线程栈绑定对象SecurityUtils.getSubject().getPrincipal()可以拿到我们刚才从数据库用过用户名查询到得Tuser对象。存到shiro自己写的ThreadContext域里去了,现在把它拿出来。接下来通过u.id查询该用户拥有的权限。通过SELECT * FROM
auth_function afLEFT JOIN role_function rf ON rf.function_id = af.idLEFT JOIN auth_role ar ON ar.id = rf.role_idLEFT JOIN user_role ur ON rf.role_id = ur.role_idLEFT JOIN t_user t ON ur.user_id = t.idWHERE
t.id = #{id};查询到用户对应的权限对象集合。然后对集合进行遍历,没一个遍历调用SimpleAuthorizationInfo对象info的add方法将权限对象中的权限添加进去,这里所谓的权限可以是字母也可以是数字,它是一种标识。添加完成后结束。认证和授权方法都结束以后这个位置才结束。下一步就是进行跳转。那么我们到页面中看看shiro到底做了什么这是没输入验证码返回该信息,该信息是应该显示在登录框内的,我没写那个。密码不正确时,返回的异常。用户名不正确的异常。没有登录权限时返回的信息。以上就是shiro权限和认证的演示了,它支持的功能比较多,还支持缓存用户权限角色信息等,它的realm也有自己专属的JDBC,从框架的源码风格来看spring属于偏官方的比较通俗易懂的,shiro则是怎么让你看不懂怎么写。感兴趣的小伙伴们可以去看一看我前面的文章.不懂得地方在下面留言回复即可,框架基础在前面文章都讲过了。最后补充一下,本文编译为spring系列是5.系的版本,shiro系列必须用1.4系版本,其他会造成jar冲突。本文由百家号作者上传并发布,百家号仅提供信息发布平台。文章仅代表作者个人观点,不代表百度立场。未经作者许可,不得转载。从小白到架构师百家号最近更新:简介:从前端到后台数据库到Linux,从开发到部署作者最新文章相关文章

我要回帖

更多关于 shiro框架面试 的文章

 

随机推荐