1. 由于最近自己写的一个项目上用到了多realm的使用,遇到了一个这样的问题:

  1. 自己继承了BasicHttpAuthenticationFilter,实现了获取token,然后直接请求api的方法,但是每次第一次调用的时候都是无效的,第二次请求又是正常的。

以下为配置文件

    @Bean
public ShiroFilterFactoryBean shirFilter(org.apache.shiro.mgt.SecurityManager securityManager) {
logger.debug("ShiroConfiguration.shiroFilter()");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//拦截器.
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
// 配置不会被拦截的链接 顺序判断
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/fonts/**", "anon");
filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/index.html", "anon");
filterChainDefinitionMap.put("/login.html", "anon");
filterChainDefinitionMap.put("/register.html", "anon");
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/auth/logout", "logout");
filterChainDefinitionMap.put("/auth/login", "anon");
filterChainDefinitionMap.put("/wx/app/login/**", "anon");
filterChainDefinitionMap.put("/auth/register", "anon");
//<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
filterChainDefinitionMap.put("/**", "authc,token");
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
//配置shiro默认登录界面地址,前后端分离中登录界面跳转应由前端路由控制,后台仅返回json数据
shiroFilterFactoryBean.setLoginUrl("/unauth");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index");
//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
Map<String,Filter> filterMap=new HashedMap();
filterMap.put("token",headerHttpAuthenticationFilter());
shiroFilterFactoryBean.setFilters(filterMap);
return shiroFilterFactoryBean;
}

  2. 贴出主要的配置文件

2.分析问题:

  1. 由于第一次不正常,第二次正常,又因为shiro的权限认证是根据sessionId+过滤器实现的,每次删除sessionId的cookie后,第一次通过token方式进行请求都会出现没有权限的问题。

  2. 检查HeaderHttpAuthenticationFilter类发现正常,在该类中打断点,发现方法能够正常进入到该方法中,并且是正常的

3. 查询shiro中的Filter调用链,发现ProxiedFilterChain类中是这样进行调用的

   

    public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
if (this.filters != null && this.filters.size() != this.index) {
if (log.isTraceEnabled()) {
log.trace("Invoking wrapped filter at index [" + this.index + "]");
} ((Filter)this.filters.get(this.index++)).doFilter(request, response, this);
} else {
if (log.isTraceEnabled()) {
log.trace("Invoking original filter chain.");
} this.orig.doFilter(request, response);
} }

  获取filters然后进行一个一个调用,查询以及跟踪断点发现,authc该方式中对应的为BasicHttpAuthenticationFilter

在BasicHttpAuthenticationFilter打上断点

发现每次会请求到该方法上,查找原因发现,由于我是token请求,并没有带该参数导致的

问题解决:

  1. 查看ShiroConfig类中发现

        filterChainDefinitionMap.put("/**", "authc,token");

  位置放置权限filter鉴权有问题,由于token的鉴权会比authc的权限高,自定义权限比普通的表单认证的优先级高。所以应该将其放到前面,修改为如下

 

        filterChainDefinitionMap.put("/**", "token,authc");

  2. 重启项目,运行正常了

shiro多Realm第一次调用不生效问题的更多相关文章

  1. Shiro笔记(四)Shiro的realm认证

    认证流程: 1.获取当前Subject.调用SecurityUtils.getSubject(); 2.测试当前用户是否已经被认证,即是否已经登录,调用Subject的isAurhenticated( ...

  2. Shiro中Realm

    6.1 Realm [2.5 Realm]及[3.5 Authorizer]部分都已经详细介绍过Realm了,接下来再来看一下一般真实环境下的Realm如何实现. 1.定义实体及关系   即用户-角色 ...

  3. Shiro自定义Realm时用注解的方式注入父类的credentialsMatcher

    用Shiro做登录权限控制时,密码加密是自定义的. 数据库的密码通过散列获取,如下,算法为:md5,盐为一个随机数字,散列迭代次数为3次,最终将salt与散列后的密码保存到数据库内,第二次登录时将登录 ...

  4. 【转】WCF 服务第一次调用慢的问题

    写了一个WCF Serivces供外部程序通过.NET Businesss Connector调用AX的代码,第一次调用的时候总是很慢,有时候甚至超过1分钟,访问地址改成http://localhos ...

  5. winform客户端程序第一次调用webservice方法很慢的解决方法

    .net2.0的winform客户端最常用的与服务端通信方式是通过webservice,最近在用dottrace对客户端做性能测试的时候发现,客户端程序启动以后,第一次调用某一个webservice的 ...

  6. shiro自定义Realm

    1.1 自定义Realm 上边的程序使用的是shiro自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm. ...

  7. SpringCloud服务消费者第一次调用出现超时问题的解决方案

    在第一次访问服务消费者的时候(消费者去调用服务提供者服务)会出现如下异常: com.netflix.hystrix.exception.HystrixRuntimeException: TestSer ...

  8. 百度编辑器同一id重复调用不能生效的办法

    在使用js 调用表单组件模板的时候,表单内有一个编辑框 第一次调出的时候,百度编辑器正常显示,关闭后,再打开,百度编辑器不能显示 原因:第一次使用的时候, UE.getEditor('node_con ...

  9. shiro开启realm

    使用缓存,可以解决每次访问请求都查数据库的问题.第一次授权后存入缓存. 缓存流程 shiro中提供了对认证信息和授权信息的缓存.shiro默认是关闭认证信息缓存的,对于授权信息的缓存shiro默认开启 ...

随机推荐

  1. Django之随机图形验证码

    实现效果:点击右边图片验证码会变 前端代码: <div class="container"> <div class="row"> < ...

  2. Dynamics 365中显示格式为URL的字段极少部分URL值录入了不显示怎么回事?

    微软动态CRM专家罗勇 ,回复318或者20190315可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 对于如下类型的字段, ...

  3. SAP MM 明明有需求,为啥MRP RUN后没有PR单据产生?

    SAP MM 明明有需求,为啥MRP RUN后没有PR单据产生? 用户报了一个问题说,对于物料号42011222的采购单 4500000156建好了,为啥PR没有自动生成 . 我们检查了物料的MRP ...

  4. 自定义修改Anaconda Jupyterlab Home目录

    自定义修改Anaconda Jupyterlab Home目录 最近在使用Anaconda学习数据分析和机器学习,会使用到Jupyter,但是他默认目录是用户的目录,我并没有习惯将项目和资料放在C盘, ...

  5. pyltp安装踩坑记录

    LTP(Language Technology Platform)由哈工大社会计算与信息检索研究中心开发,提供包括中文分词.词性标注.命名实体识别.依存句法分析.语义角色标注等丰富. 高效.精准的自然 ...

  6. Android MVP

    大家先看看目录结构 先看V层 View里面我写了一个接口LoginView 然后,在登录这个Activity 去实现这个接口,并实现其抽象方法.即看LoginActivity onCreate中引用了 ...

  7. Go语言打造以太坊智能合约测试框架(level1)

    传送门: 柏链项目学院 Go语言打造以太坊智能合约测试框架 前言 这是什么? 这是一个基于go语言编写的,自动化测试以太坊智能合约的开发框架,使用此框架,可以自动化的部署合约,自动测试合约内的功能函数 ...

  8. Python迭代器详解

    最近在看两个github项目的代码时对迭代器有些困惑,因此写一篇笔记以理清脉络,经过两天的修改完善对迭代器有了一个初步的理解,相信会比网上绝大多数笔记有用些. 一.基础概念 在进行具体的迭代类和迭代函 ...

  9. win7 wifi热点设置

    1.创建wifi热点 netsh wlan set hostednetwork mode=allow ssid=pengyanPC key=11111111 2.启动wifi热点 netsh wlan ...

  10. [RHEL 7]ISCSI服务端及客户端连接配置

    环境RHEL7.4 1.搭建服务器端主机环境 网络配置 网卡eth0 10.0.0.1 网卡eth1 10.1.0.1 网卡eth2 10.2.0.1 网卡eth3 10.3.0.1 硬盘配置 添加一 ...