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. nginx系列6:nginx的进程结构

    nginx的进程结构 如下图: 通过ps –ef | grep nginx可以看到共有三个进程,一个master进程,两个worker进程. nginx是多进程结构,多进程结构设计是为了保证nginx ...

  2. web服务器负载均衡与集群基本概念二

    前面已经说过负载均衡的作用是在多个节点之间按照一定的策略(算法)分发网络或计算处理负载.负载均衡可以采用软件和硬件来实现.一般的框架结构可以参考下图.    后台的多个Web节点上面有相同的Web应用 ...

  3. 基于Django 的 FreeSwitch 开源GUI 管理系统 YouPBX

    YouPBX YouPBX 是一个强大 FreeSwift (电话软交换系统) 的管理GUI系统,基于Django开发,功能全面,体验友好,可以基于此项目做一个完善的IPPBX系统.呼叫中心应用等 项 ...

  4. Dynamics 365-关于Solution的那些事(一)

    关于CRM Solution,我准备写两到三篇的博客来做下介绍:包括一些基本信息,超大solution,还有增量更新solution操作等. CRM中的component,都是放在一个名叫Soluti ...

  5. Kotlin 扩展——省略findViewById

    现在 Kotlin 安卓扩展插件能够提供与这些开源库功能相同的体验,不需要添加任何额外代码. import kotlinx.android.synthetic.main.activity_main.* ...

  6. typescript中的泛型

    泛型:软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性. 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能. 在像C#和Ja ...

  7. TSC条码打印机C#例程(tsclib.dll调用) 【转】

    //----  program.cs using System;using System.Collections.Generic;using System.Windows.Forms; using S ...

  8. C# 虚拟串口通信

    将主端口COM8拆分成 COM1和COM2两个虚拟端口 COM8接收的消息会传递给COM1和COM2 SerialPort spSend;//spSend,spReceive用虚拟串口连接,它们之间可 ...

  9. Vue.js02:数据绑定v-model用法

    <!-- v-model 实现数据的双向绑定 --> <!-- v-model 只能用在表单元素中 --> 示例: <!DOCTYPE html> <!-- ...

  10. Diagnostics: File file:/tmp/spark-95cbb984-da28-4784-8b99-eb83ad74437f/__spark_libs__1421840316395076250.zip does not exist

    搭建spark环境,测试在yarn 上运行spark shell的时候出现的错误:Diagnostics: File file:/tmp/spark-95cbb984-da28-4784-8b99-e ...