Search code examples
javaguiceshiro

Shiro: Forcing second realm authentication even though existing session is already authenticated via other realm


In my web application that uses Apache Shiro for AuthC and AuthZ I have two authentication realms: One for the regular web interface (called SsoRealm) and another one for the REST API (called RestRealm) using an API token. The principals authenticated by both realms have disjunct permissions (and AuthenticationTokens). If there is no pre-existing session and an API call arrives via the REST interface everything is fine and the authentication (and authorization) happens via the RestRealm. However, if there is an existing session previously authenticated via the SsoRealm no authentication attempt via the RestRealm happens and the consecutive authorization check (using Subject.isPermitted) fails as the subject is from the wrong realm.

The corresponding authentication filters are registered as (using Shiro Guice):

addFilterChain("/api/x/*/y", REST_AUTH, NO_SESSION_CREATION);
addFilterChain("/**", SSO_AUTH);

Is there anything I can do to force a re-authentication with the "correct" realm?

Would a custom AuthenticationStrategy help (i.e., does the AuthenticationStrategy contract allow the implementation of a strategy "if RestRealm is involved, the RestRealm authentication needs to be successful")? AFAICS ModularRealmAuthenticator.doMultiRealmAuthentication is not called again if there is an existing authenticated session...


Solution

  • As it turned out, this one was rather easy to solve: Just overwrite AuthenticatingFilter#isAccessAllowed to make sure that the 'right' principal type is authenticated for your realm (the default implementation just uses Subject#isAuthenticated to test whether any principal is authenticated - no matter whether it fits the realm or not).