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. mysql 设置自增主键id的起始值

    修改user表,主键自增从20000开始 alter table user AUTO_INCREMENT=20000;

  2. Nginx配置了解

    安装Nginx常用编译选项说明 nginx大部分常用模块,编译时./configure --help查看,以--without开头的都是默认安装. --prefix=PATH 指定nginx的安装目录 ...

  3. 渐进式Web应用程序的深入概述

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://www.grapecity.com.cn/blogs/wijmo-depth-ove ...

  4. 关于SQL Server 数据库归档的一些思考和改进

    一.需求背景 SQL Server开源的归档工具不多,DBA一般都是通过计划任务来触发执行,执行的脚本多是SP或者是SSIS包.SSIS包的性能稍好一些,但是维护更新成本高些.所以更常见的是通过SP脚 ...

  5. mybaties xml 的头部

    config.xml的头部: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE config ...

  6. 记录Javascript的数据方法参考

    concat >>连接2个或更多数组,并返回结果 var arr1 = [1,2,3]; var arr2 = [-1,-2,-3]; console.log(arr1.concat(ar ...

  7. SQL 游标的使用

    适用场景:对查询出的结果集遍历,作用类似于其他语言的列表循环语句. 相关语法: --定义游标 DECLARE cr CURSOR FOR( SELECT Cust_ID ,Cust_Name ,IDC ...

  8. TypeError: argument 1 must be an integer, not _subprocess_handle/OSError: [WinError 87]

    Error Msg: Traceback (most recent call last): File "c:\python27\lib\site-packages\celery\worker ...

  9. ABP之启动配置

    ASP.NET Boilerplate提供了在StartUp中配置其模块的基础设施和模型. 配置ASP.NET Boilerplate 配置ABP是在模块的PreInitialize 方法中做的,如下 ...

  10. opencv : imread()的应用

    概述: imread()是opencv中用于读取图片的一个工具.怎么读取图片看似一个很简单的工作,但实际上也有一些细节需要我们注意,以避免在后续的操作中出现bug. 函数原型: 函数原型: Mat i ...