shiro authorization filter getting called multiple times

shiro permission pattern
shiro filter
shiro get session
shiro ini
shiro spring
shiro api
shiro filterchaindefinitions
shiro rbac

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>

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

java - shiro authorization filter getting called multiple times, 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  shiro authorization filter getting called multiple times - JavaTechji - December 30, 2019 […] whole code flow is based on the sample facebook-shiro example doGetAuthorizationInfo method inside the googleRealm, which actually fetches the roles and […]

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.

shiro authorization filter getting called multiple times, shiro authorization filter getting called multiple times. I wrote a authentication and authorization module using apache shiro and google oauth  mappedValue - the filter-specific config value mapped to this filter in the URL rules mappings. Returns: true if the request should proceed through the filter normally, false if the request should be processed by this filter's AccessControlFilter.onAccessDenied(ServletRequest,ServletResponse,Object) method instead.

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?

(springboot) shiro security framework custom filter appeared several , (springboot) shiro security framework custom filter appeared several difficult Problem 1: Repeated redirection problems multiple times (matching multiple filter chains to repeatedly call their corresponding filters) to integrate the shiro security authentication framework, I stepped on a lot of pits. Get all the intercept url. Shiro’s goal is to eliminate much of the complexity around authorization so that you can more easily build secure software. Below is a highlight of the Shiro authorization features. Features. Subject-based - Almost everything you do in Shiro is based on the currently executing user, called a Subject. And you can easily access the subject

Authorization, Permissions in Apache Shiro represent the most atomic element of a security policy. checks to reflect the change in your security model, every time such a change For example, to see if a Subject has a particular (single) role, you can call the subject. Step 3: The SecurityManager , being a basic 'umbrella' component,  Most Shiro filters use this url as the location to redirect a user when the filter requires authentication. Unless overridden, the DEFAULT_LOGIN_URL is assumed. Overrides:

Java Authorization Guide, Full documentation on Apache Shiro's Authorization functionality. can get complicated with larger user bases and more complex applications. If they do, then the method is called as expected, and if they don't, then an exception is thrown. the community is improving and expanding the documentation all the time. Sets the name to use in the ServletResponse's WWW-Authenticate header. Per RFC 2617, this name name is displayed to the end user when they are asked to authenticate. Unless overridden by this method, the default value is "application" For example, setting this property to the value Awesome Webapp will result in the following header: WWW-Authenticate: Basic realm="Awesome Webapp" Side note: As

Introduction to Apache Shiro, Discover Apache Shiro, a versatile Java security framework. 3. Configuring Security Manager. The SecurityManager is the center The admin role is granted permission and access to every part of the Calling SecurityUtils. way to get user credentials from a database rather than from the shiro.ini file. And in Shiro, you'll also be able to dynamically add, remove, or change roles at runtime and your authorization checks will always have up to date values. This means you won't have to force users to log out and log back in order to get their new permissions.

Comments
  • stackoverflow.com/help/how-to-ask You should add your configuration and any other specifics about your application.
  • I apologize for less info in the question. I added bunch of info now.
  • Wow, I will give it a try and let you know the results, makes sense already :) Thanks.
  • Yes today I finally tried it, it does solve the problem indeed, just by adding a simple cache. Beautiful!
  • Thank you for the response. I have exception catchers everywhere. It is actually fetching the correct role and permission from the database and assigning(inside the commonAuth.doGetAuthorizationInfo) . I think I found the reason, inside my xhtml page i am calling multiple times the shiro:hasPermission, shiro:hasAnyRolesjsp shiro tags. Did not think before that everytime they ought to call doAuthorizationInfo method. Is my suspicion right? Thanks
  • Sounds like your subject might not be attached to the request correctly? The realm should only be called once when the session starts (or if stateless once per request)
  • Ok this makes sense, the way I am doing it is as follows, String code = oar.getCode(); GoogleToken token = new GoogleToken(code); Subject currentUser = SecurityUtils.getSubject(); if(!currentUser.isAuthenticated()){ currentUser.login(token); ThreadContext.bind(currentUser); }
  • Do you see an issue here? Once the user authenticates and I receive a code I apply for the access token and the token is used to login the subject. GoogleToken is just a authentication token which i prepared following this tutorial from shiro, sample facebook app
  • I added more config information about how I set up my xhtml code with the shiro: jsp tags from DeLuans repository, isn't that how I should do this? @Brian Demers