Class AuthenticatingRealm

  • All Implemented Interfaces:
    LogoutAware, org.apache.shiro.cache.CacheManagerAware, Realm, org.apache.shiro.util.Initializable, org.apache.shiro.util.Nameable
    Direct Known Subclasses:
    AuthorizingRealm

    public abstract class AuthenticatingRealm
    extends CachingRealm
    implements org.apache.shiro.util.Initializable
    A top-level abstract implementation of the Realm interface that only implements authentication support (log-in) operations and leaves authorization (access control) behavior to subclasses.

    Authentication Caching

    For applications that perform frequent repeated authentication of the same accounts (e.g. as is often done in REST or Soap applications that authenticate on every request), it might be prudent to enable authentication caching to alleviate constant load on any back-end data sources.

    This feature is disabled by default to retain backwards-compatibility with Shiro 1.1 and earlier. It may be enabled by setting authenticationCachingEnabled = true (and configuring Shiro with a CacheManager of course), but NOTE:

    ONLY enable authentication caching if either of the following is true for your realm implementation:
    • The doGetAuthenticationInfo implementation returns AuthenticationInfo instances where the credentials are securely obfuscated and NOT plaintext (raw) credentials. For example, if your realm references accounts with passwords, that the AuthenticationInfo's credentials are safely hashed and salted or otherwise fully encrypted.

    • The doGetAuthenticationInfo implementation returns AuthenticationInfo instances where the credentials are plaintext (raw) AND the cache region storing the AuthenticationInfo instances WILL NOT overflow to disk and WILL NOT transmit cache entries over an unprotected (non TLS/SSL) network (as might be the case with a networked/distributed enterprise cache). This should be the case even in private/trusted/corporate networks.

    These points are very important because if authentication caching is enabled, this abstract class implementation will place AuthenticationInfo instances returned from the subclass implementations directly into the cache, for example:
     cache.put(cacheKey, subclassAuthenticationInfoInstance);
     

    Enabling authentication caching is ONLY safe to do if the above two scenarios apply. It is NOT safe to enable under any other scenario.

    When possible, always represent and store credentials in a safe form (hash+salt or encrypted) to eliminate plaintext visibility.

    Authentication Cache Invalidation on Logout

    If authentication caching is enabled, this implementation will attempt to evict (remove) cached authentication data for an account during logout. This can only occur if the getAuthenticationCacheKey(org.apache.shiro.authc.AuthenticationToken) and getAuthenticationCacheKey(org.apache.shiro.subject.PrincipalCollection) methods return the exact same value.

    The default implementations of these methods expect that the AuthenticationToken.getPrincipal() (what the user submits during login) and getAvailablePrincipal (what is returned by the realm after account lookup) return the same exact value. For example, the user submitted username is also the primary account identifier.

    However, if your application uses, say, a username for end-user login, but returns a primary key ID as the primary principal after authentication, then you will need to override either getAuthenticationCacheKey(token) or getAuthenticationCacheKey(principals) (or both) to ensure that the same cache key can be used for either object.

    This guarantees that the same cache key used to cache the data during authentication (derived from the AuthenticationToken) will be used to remove the cached data during logout (derived from the PrincipalCollection).

    Unmatching Cache Key Values

    If the return values from getAuthenticationCacheKey(org.apache.shiro.authc.AuthenticationToken) and getAuthenticationCacheKey(org.apache.shiro.subject.PrincipalCollection) are not identical, cached authentication data removal is at the mercy of your cache provider settings. For example, often cache implementations will evict cache entries based on a timeToIdle or timeToLive (TTL) value.

    If this lazy eviction capability of the cache product is not sufficient and you want discrete behavior (highly recommended for authentication data), ensure that the return values from those two methods are identical in the subclass implementation.
    Since:
    0.2
    • Constructor Detail

      • AuthenticatingRealm

        public AuthenticatingRealm()
      • AuthenticatingRealm

        public AuthenticatingRealm(org.apache.shiro.cache.CacheManager cacheManager)
      • AuthenticatingRealm

        public AuthenticatingRealm(org.apache.shiro.cache.CacheManager cacheManager,
                                   CredentialsMatcher matcher)
    • Method Detail

      • getCredentialsMatcher

        public CredentialsMatcher getCredentialsMatcher()
        Returns the CredentialsMatcher used during an authentication attempt to verify submitted credentials with those stored in the system.

        Unless overridden by the setCredentialsMatcher method, the default value is a SimpleCredentialsMatcher instance.

        Returns:
        the CredentialsMatcher used during an authentication attempt to verify submitted credentials with those stored in the system.
      • setCredentialsMatcher

        public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher)
        Sets the CrendialsMatcher used during an authentication attempt to verify submitted credentials with those stored in the system. The implementation of this matcher can be switched via configuration to support any number of schemes, including plain text comparisons, hashing comparisons, and others.

        Unless overridden by this method, the default value is a SimpleCredentialsMatcher instance.

        Parameters:
        credentialsMatcher - the matcher to use.
      • setAuthenticationCache

        public void setAuthenticationCache(org.apache.shiro.cache.Cache<Object,AuthenticationInfo> authenticationCache)
        Sets an explicit Cache instance to use for authentication caching. If not set and authentication caching is enabled, any available cacheManager will be used to acquire the cache instance if available.

        WARNING: Only set this property if safe caching conditions apply, as documented at the top of this page in the class-level JavaDoc.
        Parameters:
        authenticationCache - an explicit Cache instance to use for authentication caching or null if the cache should possibly be obtained another way.
        Since:
        1.2
        See Also:
        isAuthenticationCachingEnabled()
      • isAuthenticationCachingEnabled

        public boolean isAuthenticationCachingEnabled()
        Returns true if authentication caching should be utilized if a CacheManager has been configured, false otherwise.

        The default value is true.
        Returns:
        true if authentication caching should be utilized, false otherwise.
      • setAuthenticationCachingEnabled

        public void setAuthenticationCachingEnabled(boolean authenticationCachingEnabled)
        Sets whether or not authentication caching should be utilized if a CacheManager has been configured, false otherwise.

        The default value is false to retain backwards compatibility with Shiro 1.1 and earlier.

        WARNING: Only set this property to true if safe caching conditions apply, as documented at the top of this page in the class-level JavaDoc.
        Parameters:
        authenticationCachingEnabled - the value to set
      • setName

        public void setName(String name)
        Specified by:
        setName in interface org.apache.shiro.util.Nameable
        Overrides:
        setName in class CachingRealm
      • supports

        public boolean supports(AuthenticationToken token)
        Convenience implementation that returns getAuthenticationTokenClass().isAssignableFrom( token.getClass() );. Can be overridden by subclasses for more complex token checking.

        Most configurations will only need to set a different class via setAuthenticationTokenClass(java.lang.Class<? extends org.apache.shiro.authc.AuthenticationToken>), as opposed to overriding this method.

        Specified by:
        supports in interface Realm
        Parameters:
        token - the token being submitted for authentication.
        Returns:
        true if this authentication realm can process the submitted token instance of the class, false otherwise.
      • init

        public final void init()
        Initializes this realm and potentially enables an authentication cache, depending on configuration. Based on the availability of an authentication cache, this class functions as follows:
        1. If the cache property has been set, it will be used to cache the AuthenticationInfo objects returned from getAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken) method invocations. All future calls to getAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken) will attempt to use this cache first to alleviate any potentially unnecessary calls to an underlying data store.
        2. If the cache property has not been set, the cacheManager property will be checked. If a cacheManager has been set, it will be used to eagerly acquire an authentication cache, and this cache which will be used as specified in #1.
        3. If neither the (org.apache.shiro.cache.Cache) authenticationCache or cacheManager properties are set, caching will not be utilized and authentication look-ups will be delegated to subclass implementations for each authentication attempt.

        This method finishes by calling onInit() is to allow subclasses to perform any init behavior desired.
        Specified by:
        init in interface org.apache.shiro.util.Initializable
        Since:
        1.2
      • onInit

        protected void onInit()
        Template method for subclasses to implement any initialization logic. Called from init().
        Since:
        1.2
      • afterCacheManagerSet

        protected void afterCacheManagerSet()
        This implementation attempts to acquire an authentication cache if one is not already configured.
        Overrides:
        afterCacheManagerSet in class CachingRealm
        Since:
        1.2
      • getAuthenticationInfo

        public final AuthenticationInfo getAuthenticationInfo(AuthenticationToken token)
                                                       throws AuthenticationException
        This implementation functions as follows:
        1. It attempts to acquire any cached AuthenticationInfo corresponding to the specified AuthenticationToken argument. If a cached value is found, it will be used for credentials matching, alleviating the need to perform any lookups with a data source.
        2. If there is no cached AuthenticationInfo found, delegate to the doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken) method to perform the actual lookup. If authentication caching is enabled and possible, any returned info object will be cached to be used in future authentication attempts.
        3. If an AuthenticationInfo instance is not found in the cache or by lookup, null is returned to indicate an account cannot be found.
        4. If an AuthenticationInfo instance is found (either cached or via lookup), ensure the submitted AuthenticationToken's credentials match the expected AuthenticationInfo's credentials using the credentialsMatcher. This means that credentials are always verified for an authentication attempt.
        Specified by:
        getAuthenticationInfo in interface Realm
        Parameters:
        token - the submitted account principal and credentials.
        Returns:
        the AuthenticationInfo corresponding to the given token, or null if no AuthenticationInfo could be found.
        Throws:
        AuthenticationException - if authentication failed.
      • assertCredentialsMatch

        protected void assertCredentialsMatch(AuthenticationToken token,
                                              AuthenticationInfo info)
                                       throws AuthenticationException
        Asserts that the submitted AuthenticationToken's credentials match the stored account AuthenticationInfo's credentials, and if not, throws an AuthenticationException.
        Parameters:
        token - the submitted authentication token
        info - the AuthenticationInfo corresponding to the given token
        Throws:
        AuthenticationException - if the token's credentials do not match the stored account credentials.
      • getAuthenticationCacheKey

        protected Object getAuthenticationCacheKey(AuthenticationToken token)
        Returns the key under which AuthenticationInfo instances are cached if authentication caching is enabled. This implementation defaults to returning the token's principal, which is usually a username in most applications.

        Cache Invalidation on Logout

        NOTE: If you want to be able to invalidate an account's cached AuthenticationInfo on logout, you must ensure the getAuthenticationCacheKey(org.apache.shiro.subject.PrincipalCollection) method returns the same value as this method.
        Parameters:
        token - the authentication token for which any successful authentication will be cached.
        Returns:
        the cache key to use to cache the associated AuthenticationInfo after a successful authentication.
        Since:
        1.2
      • clearCachedAuthenticationInfo

        protected void clearCachedAuthenticationInfo(PrincipalCollection principals)
        Clears out the AuthenticationInfo cache entry for the specified account.

        This method is provided as a convenience to subclasses so they can invalidate a cache entry when they change an account's authentication data (e.g. reset password) during runtime. Because an account's AuthenticationInfo can be cached, there needs to be a way to invalidate the cache for only that account so that subsequent authentication operations don't used the (old) cached value if account data changes.

        After this method is called, the next authentication for that same account will result in a call to doGetAuthenticationInfo, and the resulting return value will be cached before being returned so it can be reused for later authentications.

        If you wish to clear out all associated cached data (and not just authentication data), use the CachingRealm.clearCache(org.apache.shiro.subject.PrincipalCollection) method instead (which will in turn call this method by default).
        Parameters:
        principals - the principals of the account for which to clear the cached AuthorizationInfo.
        Since:
        1.2
        See Also:
        CachingRealm.clearCache(org.apache.shiro.subject.PrincipalCollection)
      • doGetAuthenticationInfo

        protected abstract AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
                                                               throws AuthenticationException
        Retrieves authentication data from an implementation-specific datasource (RDBMS, LDAP, etc) for the given authentication token.

        For most datasources, this means just 'pulling' authentication data for an associated subject/user and nothing more and letting Shiro do the rest. But in some systems, this method could actually perform EIS specific log-in logic in addition to just retrieving data - it is up to the Realm implementation.

        A null return value means that no account could be associated with the specified token.
        Parameters:
        token - the authentication token containing the user's principal and credentials.
        Returns:
        an AuthenticationInfo object containing account data resulting from the authentication ONLY if the lookup is successful (i.e. account exists and is valid, etc.)
        Throws:
        AuthenticationException - if there is an error acquiring data or performing realm-specific authentication logic for the specified token