Фильтр авторизации 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!!

---------------------------------------------Редактировать---- -----------------------

Широ Ини у меня выглядит следующим образом,

[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]

Весь поток кода основан на примере примера метода doGetAuthorizationInfo facebook-shiro внутри googleRealm, который фактически выбирает роли и разрешения из базовой базы данных (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, как это. следующая ссылка

<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 для возможности использовать теги shiro на страницах jsf, которые у меня есть. Одна из примеров 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 ответа

Основной причиной этой проблемы было то, что я не настроил cacheManager в securityManager, Широ не знал информацию об авторизации вашей учетной записи, потому что нет кэширования.

Добавить cacheManager, код ниже, используя менеджер кэша памяти, вы можете добавить другие, как ehcacheВот пример использования кеша памяти:

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

затем добавить в securityManager: securityManager.setCacheManager(cacheManager);

О Боже! Я все время совершал глупую ошибку. Я включил репозиторий из Deluan для JSF отдельно для настройки taglibs для jsf, следуя некоторым старым примерам, не осознавая, что он уже включен в последнюю версию Shiro, и, следовательно, методы авторизации вызывались несколько раз. Когда я удаляю его из зависимости, все работает очень хорошо. @ Брайан Демерс, спасибо, сэр, за ваше время и помощь:)

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

Похоже, вы игнорируете ошибку от commonAuth.doGetAuthorizationInfo в результате аутентифицированный пользователь сможет получить доступ к вашей системе.

Что значит commonAuth.doGetAuthorizationInfo() на самом деле делать?

Другие вопросы по тегам