【问题标题】:shiro authorization filter getting called multiple timesshiro 授权过滤器被多次调用
【发布时间】:2019-01-04 14:11:51
【问题描述】:

我使用 apache shiro 和 google oauth 和 microsoft 365 oauth 编写了一个身份验证和授权模块。它允许用户使用 google/ms 凭据登录没有问题,但是授权过滤器被调用了很多次。下面是我从单次登录获得的调试日志示例。这么多次授权周期被调用。所以任何人都知道我该如何解决这个问题。

        17:39:16.998 [qtp670971910-28] INFO  com.hap.Google.GoogleRealm - GoogleRealm: doGetAuthorizationInfo is called!!
        17:39:17.105 [qtp670971910-28] INFO  com.hap.Google.GoogleRealm - GoogleRealm: doGetAuthorizationInfo is called!!
        17:39:17.224 [qtp670971910-28] INFO  com.hap.Google.GoogleRealm - GoogleRealm: doGetAuthorizationInfo is called!!
        17:39:17.348 [qtp670971910-28] INFO  com.hap.Google.GoogleRealm - GoogleRealm: doGetAuthorizationInfo is called!!
        17:39:17.408 [qtp670971910-28] INFO  com.hap.Google.GoogleRealm - GoogleRealm: doGetAuthorizationInfo is called!!
        17:39:17.479 [qtp670971910-28] INFO  com.hap.Google.GoogleRealm - GoogleRealm: doGetAuthorizationInfo is called!!
        17:39:17.596 [qtp670971910-28] INFO  com.hap.Google.GoogleRealm - GoogleRealm: doGetAuthorizationInfo is called!!
        17:39:17.713 [qtp670971910-28] INFO  com.hap.Google.GoogleRealm - GoogleRealm: doGetAuthorizationInfo is called!!
        17:39:17.838 [qtp670971910-28] INFO  com.hap.Google.GoogleRealm - GoogleRealm: doGetAuthorizationInfo is called!!
        17:39:17.967 [qtp670971910-28] INFO  com.hap.Google.GoogleRealm - GoogleRealm: doGetAuthorizationInfo is called!!
        17:39:18.087 [qtp670971910-28] INFO  com.hap.Google.GoogleRealm - GoogleRealm: doGetAuthorizationInfo is called!!

----------------------------------编辑- --------------------------

我的shiro ini如下所示,

[main]

ssl.enabled = false

authcStrategy = org.apache.shiro.authc.pam.FirstSuccessfulStrategy
securityManager.authenticator.authenticationStrategy = $authcStrategy

GoogleRealm = com.hap.Google.GoogleRealm
#GoogleRealm.permissionsLookupEnabled = true
googleCredentialsMatcher = com.hap.Google.GoogleCredentialsMatcher
GoogleRealm.credentialsMatcher = $googleCredentialsMatcher

Ms365Realm = com.hap.MsOffice365.Ms365Realm
#Ms365Realm.permissionsLookupEnabled = true
Ms365CredentialsMatcher = com.hap.MsOffice365.Ms365CredentialsMatcher
Ms365Realm.credentialsMatcher = $Ms365CredentialsMatcher

securityManager.realms = $GoogleRealm,$Ms365Realm
securityManager.rememberMeManager.cipherKey=kPH+bIxk5D2deZiIxcaaaA==
authc.loginUrl = /views/login-oauth.xhtml



[urls]
#Important
/javax.faces.resource/** = anon
/views/login-oauth.xhtml = authc
/views/access-denied.xhtml = anon
/logout = logout

/views/* = authc
/css/* = anon
/errors/* = anon
#I have to punch a hole for the css files
#/** = authc, roles[admin]

整个代码流程基于sample facebook-shiro example googleRealm 中的 doGetAuthorizationInfo 方法,实际上是从底层数据库(postgres)中获取角色和权限。

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    AuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    try {
        CommonAuthenticationMethods commonAuth = new CommonAuthenticationMethods();
        authorizationInfo = commonAuth.doGetAuthorizationInfo(principals);
        LOGGER.info("GoogleRealm: doGetAuthorizationInfo is called!!");
    } catch (Exception e) {
        LOGGER.debug("GoogleRealm : doGetAuthorizationInfo: exception occurred!! " + e.getMessage());
        //throw e;
    }
    return authorizationInfo;
}

像这样添加了 EnvironmentLoaderListener 和 ShiroFilter。关注link

<listener>
            <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
        </listener>

    <filter>
            <filter-name>ShiroFilter</filter-name>
            <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
        </filter>

        <filter-mapping>
            <filter-name>ShiroFilter</filter-name>
            <url-pattern>/*</url-pattern>
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>FORWARD</dispatcher>
            <dispatcher>INCLUDE</dispatcher>
            <dispatcher>ERROR</dispatcher>
        </filter-mapping>

为什么在这里多次调用授权过滤器?

--------------------------编辑-------- -------------------------------------------

<repositories>
        <repository>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
            <id>bintray-deluan-maven</id>
            <name>bintray</name>
            <url>http://dl.bintray.com/deluan/maven</url>
        </repository>
    </repositories>

似乎在调用shiro:hasAnyRoles 时正在调用授权方法。以上是我如何在 pom.xml 中添加 Deluan 存储库,以便能够在我拥有的 jsf 页面中使用 shiro 标签。我拥有的示例jsf页面之一如下,

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
      xmlns:ace="http://www.icefaces.org/icefaces/components"
      xmlns:icecore="http://www.icefaces.org/icefaces/core"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:shiro="http://shiro.apache.org/tags">

<h:head>
    <title>Welcome Page</title>
</h:head>
<h:body>
    <shiro:hasAnyRoles name="admin,backup-admin,sys-admin">
        <h2>     Welcome!        </h2>
    </shiro:hasAnyRoles>
    <shiro:hasAnyRoles name="user,admin">
        <h2>     You too Welcome!        </h2>
    </shiro:hasAnyRoles>   

</h:body>
</html>

这个简单的页面被用作欢迎页面,每次刷新它似乎都会调用 doAuthentication 方法 3 次。当然我在这里做错了什么:(我应该在哪里看的任何指针?

============================已编辑=================== =========

<!--  Shiro Environment Listener -->
    <listener>
        <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
    </listener>  

    <filter>
        <filter-name>ShiroFilter</filter-name>
        <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>ShiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>

【问题讨论】:

  • stackoverflow.com/help/how-to-ask 你应该添加你的配置和关于你的应用程序的任何其他细节。
  • 对于问题中的信息较少,我深表歉意。我现在添加了一堆信息。

标签: java shiro


【解决方案1】:

我遇到这个问题的主要原因是我没有在securityManager 中配置cacheManager。 Shiro 不知道您帐户的授权信息,因为没有缓存。

添加一个cacheManager,下面的代码使用内存缓存管理器,你可以添加其他类似ehcache,这里是一个使用内存缓存的示例:

@Bean
protected CacheManager cacheManager() {
    return new MemoryConstrainedCacheManager();
}

然后添加到securityManagersecurityManager.setCacheManager(cacheManager);

【讨论】:

  • 哇,我会试一试,让你知道结果,已经有意义:) 谢谢。
  • 是的,今天我终于试了一下,确实解决了问题,只是添加了一个简单的缓存。漂亮!
【解决方案2】:

天哪!我一直在犯一个愚蠢的错误。我已经分别包含了来自 Deluan 的 JSF 存储库,用于按照一些旧示例配置 jsf 的标记库,但没有意识到它已经包含在最新版本的 Shiro 中,因此授权方法被多次调用。当我从依赖项中删除它时,一切都很好。 @Brian Demers,谢谢先生您的时间和帮助:)

<dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-faces</artifactId>
        <version>2.0</version>
    </dependency>

----------------------------------- - - - - - - - - -编辑 - - - - - - - - - - - - - - - - ----------------------------------------

这并不能真正解决问题,错误是因为 shiro: 标签本身停止工作。

【讨论】:

    【解决方案3】:

    您似乎忽略了来自 commonAuth.doGetAuthorizationInfo 的错误,这将导致经过身份验证的用户能够访问您的系统。

    commonAuth.doGetAuthorizationInfo() 究竟做了什么?

    【讨论】:

    • 感谢您的回复。我到处都有异常捕获器。它实际上是从数据库中获取正确的角色和权限并分配(在 commonAuth.doGetAuthorizationInfo 内)。我想我找到了原因,在我的 xhtml 页面中,我多次调用 shiro:hasPermission、shiro:hasAnyRolesjsp shiro tags。之前没有想到每次他们应该调用 doAuthorizationInfo 方法。我的怀疑是对的吗?谢谢
    • 听起来您的主题可能未正确附加到请求中?该领域只应在会话开始时调用一次(或者如果每个请求无状态一次)
    • 好吧有道理,我的做法如下,String code = oar.getCode(); GoogleToken 令牌 = 新的 GoogleToken(代码);主题 currentUser = SecurityUtils.getSubject(); if(!currentUser.isAuthenticated()){ currentUser.login(token); ThreadContext.bind(currentUser); }
    • 您在这里发现问题了吗?一旦用户进行身份验证并且我收到一个代码,我就会申请访问令牌,并且该令牌用于登录主题。 GoogleToken 只是我根据 shiro 的本教程准备的身份验证令牌,sample facebook app
    • 我添加了更多关于如何使用 shiro: jsp 标签设置我的 xhtml 代码的配置信息,这不是我应该这样做的吗? @Brian Demers
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-28
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    相关资源
    最近更新 更多