CAS+Shiro 自定义 pac4jRealm 每次判断权限都要重复执行doGetAuthorizationInfo()两次

发布于 2022-09-07 07:26:36 字数 773 浏览 17 评论 0

代码如下:

public class UserRealm extends Pac4jRealm(){
  
  @Override
  public AuthorizationInfo  doGetAuthorizationInfo(PrincipalCollection principals) {
    // TODO Auto-generated method stub
    System.out.println("Onece");
    Set<String> roles=new HashSet()<>;
    roles.add("admin");
    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    authorizationInfo.setRoles(roles);
    return authorizationInfo ;
}

在controller层有一个方法

    @RequestMapping("/hello2")
    @ResponseBody
    public String hello2() {
        SecurityUtils.getSubject().checkRoles("user");
        return "success";
    }

当执行chekRoles 执行了doGetAuthorizationInfo() 方法 但是要打印两个"Onece" 请问这是什么原因呢

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

鲜血染红嫁衣 2022-09-14 07:26:36

很抱歉 现在才来给出问题答案(仅代表本人观点 错误请指正) 我的观点不一定是对的 仅供参考:
这个问题其实换一个标题问题更清晰:即是 Spring Aop注解执行两次 方法体执行一次!!!
在我的业务场景中 使用CGLIB动态代理 通过DynamicAdvisedInterceptor来处理 intercept是aop处理入口:
包含四个参数 第一个是代理方法 第二个是目标方法 第三个是方法参数 第四个是方法代理信息

    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object oldProxy = null;
        boolean setProxyContext = false;
        Class<?> targetClass = null;
        Object target = null;
        try {
            if (this.advised.exposeProxy) {
                // Make invocation available if necessary.
                oldProxy = AopContext.setCurrentProxy(proxy);
                setProxyContext = true;
            }
            // May be null. Get as late as possible to minimize the time we
            // "own" the target, in case it comes from a pool...
            target = getTarget();
            if (target != null) {
                targetClass = target.getClass();
            }
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
            Object retVal;
            // Check whether we only have one InvokerInterceptor: that is,
            // no real advice, but just reflective invocation of the target.
            if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
                // We can skip creating a MethodInvocation: just invoke the target directly.
                // Note that the final invoker must be an InvokerInterceptor, so we know
                // it does nothing but a reflective operation on the target, and no hot
                // swapping or fancy proxying.
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                retVal = methodProxy.invoke(target, argsToUse);
            }
            else {
                // We need to create a method invocation...
                retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
            }
            retVal = processReturnType(proxy, target, method, retVal);
            return retVal;
        }
        finally {
            if (target != null) {
                releaseTarget(target);
            }
            if (setProxyContext) {
                // Restore old proxy.
                AopContext.setCurrentProxy(oldProxy);
            }
        }
    }

通过打断点发现了bug出现的原因:

clipboard.png
第一次执行时 代理方法和目标方法 是同一个!!!

clipboard.png
第二次执行时 目标方法才是真正的方法体!!!

解决方法就是去除掉

clipboard.png
当前我的pub-shiro项目依赖了 pub-datasource模块 pub-datasource模块里面使用了

@Aspect
@EnableAspectJAutoProxy(exposeProxy=true,proxyTargetClass=true)
@Component

使用了cglib代理 而后在shiroConfig中 注入了DefaultAdvisorAutoProxyCreator代理器 存在了两个代理器 这两个代理器的区别和为什么出现该问题的原因 我还在研究中 得出答案会来更新
本问题即是Spring Aop注解执行两次 方法体执行一次!!! 代理1 代理 代理2 而 代理2 代理 真正的方法体!!! 这也就是为什么shiro中 权限校验方法执行两次 而真正的方法体执行一次的原因

迷爱 2022-09-14 07:26:36

看一下是不是配置了DefaultAdvisorAutoProxyCreator,我按照网上的说法配置,也是会调用两次doGetAuthorizationInfo() 方法,去掉DefaultAdvisorAutoProxyCreator的Bean定义就正常了。你可以试一下!!!!!

不忘初心 2022-09-14 07:26:36

我也是执行两次,请问解决了么?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文