shiro多Realm第一次调用不生效问题

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. 重启项目,运行正常了

原文地址:https://www.cnblogs.com/lonecloud/p/10242081.html

时间: 2024-10-08 19:45:20

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

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

用Shiro做登录权限控制时,密码加密是自定义的. 数据库的密码通过散列获取,如下,算法为:md5,盐为一个随机数字,散列迭代次数为3次,最终将salt与散列后的密码保存到数据库内,第二次登录时将登录的令牌再进行同样的运算后再与数据库的做对比. String algorithmName = "md5";String userName = "rose";String password = "rose123";int hashIterations =

springMvc和shiro整合,shiro的realm不能自动注入的问题

最近研究shiro,一开头就遇到了大困难,调试了3小时.问题描述如下:shiro和spring mvc整合,shiro自定义了realm.其中自定义的realm里面居然不能使用@Autowired注解标签注入相关的用户service.百思不得其解,一项项跟踪,发现原来shiro 自定义realm的认证阶段属于filter,当时的spring bean还没有读取进来. 最后通过配置web.xml文件,把spring mvc的xml提高一点优先级,才最终解决了这个问题. 1 <!-- 配置sprin

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

在使用js 调用表单组件模板的时候,表单内有一个编辑框 第一次调出的时候,百度编辑器正常显示,关闭后,再打开,百度编辑器不能显示 原因:第一次使用的时候, UE.getEditor('node_content'); 已经创建了一个对象,第二次再使用的时候,调用此方法发现对象已经存在,不再创建对象,所以第二次不能显示 解决办法: 设置一个全局对象 var editor; 第一次调用的时候 editor = UE.getEditor('node_content'); 关闭时销毁这个对象 editor

shiro realm何时调用

shiro 中的AuthorizingRealm有2个方法doGetAuthorizationInfo()和doGetAuthenticationInfo() 都继承AuthorizingRealm类然后重写doGetAuthorizationInfo和doGetAuthenticationInfo. doGetAuthenticationInfo这个方法是在用户登录的时候调用的也就是执行SecurityUtils.getSubject().login()的时候调用:(即:登录验证) 而doGe

Shiro - 关于Realm

之前在Authentication和Authorization中也提到Realm. 无论是身份验证还是权限验证,无论数据以什么方式存在,我们都需要访问一些数据并将其转换为Shiro可以识别的格式. 通常一个数据源对应一个Realm.因此,实现一个Realm时会用到该数据源相关的API. 通常一个数据源中会同时保存身份相关数据与权限相关数据.因此,一个Realm实现类可以进行认证和授权两种操作. 可以将Realm简单地理解为DAO. (虽然IDEA生成的type hirarchy diagram很

shiro双realm验证

假设现在有这样一种需求:存在两张表user和admin,分别记录普通用户和管理员的信息.并且现在要实现普通用户和管理员的分开登录,即需要两个Realm--UserRealm和AdminRealm,分别处理普通用户和管理员的验证功能.  但是正常情况下,当定义了两个Realm,无论是普通用户登录,还是管理员登录,都会由这两个Realm共同处理.这是因为,当配置了多个Realm时,我们通常使用的认证器是shiro自带的org.apache.shiro.authc.pam.ModularRealmAu

shiro 前后台realm 写法,用于分辨realm

首先改写一下  UsernamePasswordToken 这个类 新建一个类,叫UsernamePasswordUsertypeToken,继承UsernamePasswordToken package hstc.edu.cn.realm; import org.apache.shiro.authc.UsernamePasswordToken; /** * Created by win8 on 2017/5/29. */ public class UsernamePasswordUsertyp

shiro多realm验证之——shiro实现不同身份使用不同Realm进行验证(转)

转自: http://blog.csdn.net/xiangwanpeng/article/details/54802509 (使用特定的realm实现特定的验证) 假设现在有这样一种需求:存在两张表user和admin,分别记录普通用户和管理员的信息.并且现在要实现普通用户和管理员的分开登录,即需要两个Realm--UserRealm和AdminRealm,分别处理普通用户和管理员的验证功能.  但是正常情况下,当定义了两个Realm,无论是普通用户登录,还是管理员登录,都会由这两个Realm

Shiro自定义realm实现密码验证及登录、密码加密注册、修改密码的验证

一:先从登录开始,直接看代码 @RequestMapping(value="dologin",method = {RequestMethod.GET, RequestMethod.POST},produces="text/html;charset=UTF-8") @ResponseBody public ResultJson systemUserdologin(XXX xxx,HttpServletRequest request,HttpServletRespons