shiro授权过滤器被多次调用

时间:2018-07-27 12:41:55

标签: java shiro

我使用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>

3 个答案:

答案 0 :(得分:1)

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

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

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

这并不能真正解决问题,因为shiro:标记本身停止工作,所以出现了错误。

答案 1 :(得分:1)

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

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

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

然后将其添加到securityManager中:securityManager.setCacheManager(cacheManager);

答案 2 :(得分:0)

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

commonAuth.doGetAuthorizationInfo()实际做什么?