Apache Shiro: Multiple Scope Exception Handling

We use two areas (one for hashed passwords, the other for generated plaintext keys) - this works as expected.

In one realm, we can throw a DisabledAccountException in our protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken authToken) and explicitly catch such an exception in our application.

Now that we have two areas, all exceptions are related to Shiro; therefore, if one area fails, you can try another. However, this kind of redirect will only result in generic AuthenticationExceptions for our application.

Is there any workaround with several areas so that we can have more specific exceptions (to find out if the account is locked, the credentials are simply incorrect, ...)?

+4
source share
1 answer

You need to specify your own authentication strategy in the modular RewalmAuthenticator. The ModularRealmAuthenticator uses AtLeastOneSuccessfulStrategy by default, and AtLeastOneSuccessfulStrategy ignores exceptions and continues to try to log in using all available areas.

We had a similar tynamo project scenario , and to solve this problem I implemented my own authentication strategy called FirstExceptionStrategy, which works with several areas and throws the first exception. This approach works fine as long as there is only one Realm per Token type .

The implementations are pretty simple:

 /** * {@link org.apache.shiro.authc.pam.AuthenticationStrategy} implementation that throws the first exception it gets * and ignores all subsequent realms. If there is no exceptions it works as the {@link FirstSuccessfulStrategy} * * WARN: This approach works fine as long as there is ONLY ONE Realm per Token type. * */ public class FirstExceptionStrategy extends FirstSuccessfulStrategy { @Override public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t) throws AuthenticationException { if ((t != null) && (t instanceof AuthenticationException)) throw (AuthenticationException) t; return super.afterAttempt(realm, token, singleRealmInfo, aggregateInfo, t); } } 

I repeat, this only works if ONLY ONE Realm per Token type exists.

For more information about my specific scenario, see here: http://jira.codehaus.org/browse/TYNAMO-154

+7
source

Source: https://habr.com/ru/post/1446843/


All Articles