简体   繁体   中英

shiro authorization filter getting called multiple times

I wrote a authentication and authorization module using apache shiro and google oauth and microsoft 365 oauth. It lets users login using there google/ms credential no problem, but the authorization filter gets called so many times. Below is a example of the debug log i get from a single login. So many time the authorization cycle is getting called. So can any one knows how do I address this issue.

        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!!

---------------------------------------------Edit---------------------------

The shiro ini I have looks as follows,

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

The whole code flow is based on the sample facebook-shiro example doGetAuthorizationInfo method inside the googleRealm, which actually fetches the roles and permissions from underlying database(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;
}

Added the EnvironmentLoaderListener and ShiroFilter like this. following 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>

Why is authorization filter is getting called so many times here?

--------------------------------------EDIT---------------------------------------

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

It seems that the authorization method is being called when the shiro:hasAnyRoles is called. Above is how I added the Deluan repository in my pom.xml for being able to use the shiro tags inside the jsf pages I have. One of the sample jsf page I have is as follows,

<?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>

This simple page is used as the welcome page and every time its refreshed it calls the doAuthentication method 3 times it seems. Surely I have done something wrong here :( Any pointers where should I look?

=========================== Edited ============================

<!--  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>

Oh God! I have been making a stupid mistake all along. I had included the repository from Deluan for JSF separately for configuring the taglibs for jsf following some old examples, did not realize that it is already included in the latest version of Shiro and hence the authorization methods were getting called multiple times. When I remove it from the dependency everything works very nice. @Brian Demers, thank you sir for your time and help :)

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

----------------------------------------------------------------Edit------------------------------------------------------------

This does not really solve the problem, the errors go because shiro: tags itself stops working.

The main reason I had this problem was I didn't configure the cacheManager in securityManager . Shiro didn't know the Authorization info of your account, cause there is no caching.

Add a cacheManager , the code below using memory cache manager, you can add others like ehcache , here is a sample using memory cache:

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

then add into securityManager : securityManager.setCacheManager(cacheManager);

It looks like you are ignoring an error from commonAuth.doGetAuthorizationInfo which would result in an authenticated user being able to access your system.

What does commonAuth.doGetAuthorizationInfo() actually do?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM