Hi Marinus,

Could you please provide this as a patch to a Jira issue?  These
things always get lost in mailing lists - Jira is the right place for
code submissions.

Thanks!

Les

On Fri, Dec 9, 2011 at 5:55 AM, geuze <[email protected]> wrote:
> Dear Shiro users,
>
> I implemented the Shiro framework in our application. When doing so I found
> something strange in the
> org.apache.shiro.authc.pam.ModularRealmAuthenticator and
> org.apache.shiro.authz.ModularRealmAuthorizer class.
>
> ModularRealmAuthenticator: authentication strategy FirstSuccessfulStrategy
> is not properly implemented
> ModularRealmAuthenticator: logout is not done on realm when this is not
> needed
> ModularRealmAuthorizer: isPermitted is not called on realm when this is not
> needed
>
> Therefore I extended these classes and made some fixes. Maybe these fixes
> should be part of the official version. This way I hope to do something back
> for the community.
>
> Greets,
> Marinus
>
> public final class ModularRealmAuthenticator extends
> org.apache.shiro.authc.pam.ModularRealmAuthenticator {
>
>        /**
>         * NOTE: copy of code in ModularRealmAuthenticator of Shiro, add 
> because
> authentication strategy was not properly
>         * implemented
>         */
>        @Override
>        protected AuthenticationInfo 
> doMultiRealmAuthentication(Collection<Realm>
> realms, AuthenticationToken token) {
>
>                AuthenticationStrategy strategy = getAuthenticationStrategy();
>
>                AuthenticationInfo aggregate = 
> strategy.beforeAllAttempts(realms, token);
>
> //        if (log.isTraceEnabled()) {
> //            log.trace("Iterating through {} realms for PAM
> authentication", realms.size());
> //        }
>
>                for (Realm realm : realms) {
>
>                        aggregate = strategy.beforeAttempt(realm, token, 
> aggregate);
>
>                        if (realm.supports(token)) {
>
> //                log.trace("Attempting to authenticate token [{}] using
> realm [{}]", token, realm);
>
>                                AuthenticationInfo info = null;
>                                Throwable t = null;
>                                try {
>                                        info = 
> realm.getAuthenticationInfo(token);
>                                } catch (Throwable throwable) {
>                    t = throwable;
> //                    if (log.isDebugEnabled()) {
> //                        String msg = "Realm [" + realm + "] threw an
> exception during a multi-realm authentication attempt:";
> //                        log.debug(msg, t);
> //                    }
>                                }
>
>                                aggregate = strategy.afterAttempt(realm, 
> token, info, aggregate, t);
>
>                                // EXTENSION of Shiro code
>                                if (aggregate != null && 
> isFirstSuccessfulStrategy(strategy)) {
>                                        break;
>                                }
>                                // END EXTENSION of Shiro code
>
>                        } else {
> //                log.debug("Realm [{}] does not support token {}.  Skipping
> realm.", realm, token);
>                        }
>                }
>
>                aggregate = strategy.afterAllAttempts(token, aggregate);
>
>                return aggregate;
>        }
>
>        /**
>         * NOTE: copy of code in ModularRealmAuthenticator of Shiro, add 
> because
> logout per realm was not property
>         * implemented
>         */
>        @Override
>        public void onLogout(PrincipalCollection principals) {
>        notifyLogout(principals);
>
>        Collection<Realm> realms = getRealms();
>        if (!CollectionUtils.isEmpty(realms)) {
>            for (Realm realm : realms) {
>                if (realm instanceof LogoutAware) {
>                                        // EXTENSION of Shiro code
>                        Collection<?> fromRealm =
> principals.fromRealm(realm.getName());
>                        if (fromRealm == null || fromRealm.isEmpty()) {
>                                continue;
>                        }
>                                // END EXTENSION of Shiro code
>
>                    ((LogoutAware) realm).onLogout(principals);
>                }
>            }
>        }
>        }
>        private boolean isFirstSuccessfulStrategy(AuthenticationStrategy 
> strategy)
> {
>                return strategy.getClass().equals(new
> FirstSuccessfulStrategy().getClass());
>        }
> }
>
>
>
> public final class ModularRealmAuthorizer extends
> org.apache.shiro.authz.ModularRealmAuthorizer {
>
>        @Override
>        public boolean isPermitted(PrincipalCollection principals, Permission
> permission) {
>
>                assertRealmsConfigured();
>                for (Realm realm : getRealms()) {
>
>                        // EXTENSION of Shiro code
>                        Collection<?> fromRealm = 
> principals.fromRealm(realm.getName());
>                        if (fromRealm == null || fromRealm.isEmpty()) {
>                                continue;
>                        }
>                        // END EXTENSION of Shiro code
>
>                        if (!(realm instanceof Authorizer))
>                                continue;
>                        if (((Authorizer) realm).isPermitted(principals, 
> permission)) {
>                                return true;
>                        }
>                }
>                return false;
>        }
> }
>
> --
> View this message in context: 
> http://shiro-user.582556.n2.nabble.com/Improvements-in-ModularRealmAuthenticator-and-ModularRealmAuthorizer-tp7078260p7078260.html
> Sent from the Shiro User mailing list archive at Nabble.com.

Reply via email to