JAASRealm (Apache Tomcat 9.0.71 API Documentation)

Package org.apache.catalina.realm

## Class JAASRealm

- java.lang.Object
- - org.apache.catalina.util.LifecycleBase
  - - org.apache.catalina.util.LifecycleMBeanBase
    - - org.apache.catalina.realm.RealmBase
      - - org.apache.catalina.realm.JAASRealm

- All Implemented Interfaces:
    `javax.management.MBeanRegistration`, `Contained`, `JmxEnabled`, `Lifecycle`, `Realm`

      public class JAASRealm
      extends RealmBase

  Implementation of Realm that authenticates users via the Java Authentication and Authorization Service (JAAS). JAAS support requires either JDK 1.4 (which includes it as part of the standard platform) or JDK 1.3 (with the plug-in `jaas.jar` file).

  The value configured for the `appName` property is passed to the `javax.security.auth.login.LoginContext` constructor, to specify the application name used to select the set of relevant `LoginModules` required.

  The JAAS Specification describes the result of a successful login as a `javax.security.auth.Subject` instance, which can contain zero or more `java.security.Principal` objects in the return value of the `Subject.getPrincipals()` method. However, it provides no guidance on how to distinguish Principals that describe the individual user (and are thus appropriate to return as the value of request.getUserPrincipal() in a web application) from the Principal(s) that describe the authorized roles for this user. To maintain as much independence as possible from the underlying `LoginMethod` implementation executed by JAAS, the following policy is implemented by this Realm:

  - The JAAS `LoginModule` is assumed to return a `Subject` with at least one `Principal` instance representing the user himself or herself, and zero or more separate `Principals` representing the security roles authorized for this user.
  - On the `Principal` representing the user, the Principal name is an appropriate value to return via the Servlet API method `HttpServletRequest.getRemoteUser()`.
  - On the `Principals` representing the security roles, the name is the name of the authorized security role.
  - This Realm will be configured with two lists of fully qualified Java class names of classes that implement `java.security.Principal` - one that identifies class(es) representing a user, and one that identifies class(es) representing a security role.
  - As this Realm iterates over the `Principals` returned by `Subject.getPrincipals()`, it will identify the first `Principal` that matches the "user classes" list as the `Principal` for this user.
  - As this Realm iterates over the `Principals` returned by `Subject.getPrincipals()`, it will accumulate the set of all `Principals` matching the "role classes" list as identifying the security roles for this user.
  - It is a configuration error for the JAAS login method to return a validated `Subject` without a `Principal` that matches the "user classes" list.
  - By default, the enclosing Container's name serves as the application name used to obtain the JAAS LoginContext ("Catalina" in a default installation). Tomcat must be able to find an application with this name in the JAAS configuration file. Here is a hypothetical JAAS configuration file entry for a database-oriented login module that uses a Tomcat-managed JNDI database resource:

    >     Catalina {
    >     org.foobar.auth.DatabaseLoginModule REQUIRED
    >         JNDI_RESOURCE=jdbc/AuthDB
    >       USER_TABLE=users
    >       USER_ID_COLUMN=id
    >       USER_NAME_COLUMN=name
    >       USER_CREDENTIAL_COLUMN=password
    >       ROLE_TABLE=roles
    >       ROLE_NAME_COLUMN=name
    >       PRINCIPAL_FACTORY=org.foobar.auth.impl.SimplePrincipalFactory;
    >     };

  - To set the JAAS configuration file location, set the `CATALINA_OPTS` environment variable similar to the following:

    > `CATALINA_OPTS="-Djava.security.auth.login.config=$CATALINA_HOME/conf/jaas.config"`

  - As part of the login process, JAASRealm registers its own `CallbackHandler`, called (unsurprisingly) `JAASCallbackHandler`. This handler supplies the HTTP requests's username and credentials to the user-supplied `LoginModule`
  - As with other `Realm` implementations, digested passwords are supported if the `<Realm>` element in `server.xml` contains a `digest` attribute; `JAASCallbackHandler` will digest the password prior to passing it back to the `LoginModule`
  Author:
    Craig R. McClanahan, Yoav Shapira

- - ### Nested Class Summary

    - ### Nested classes/interfaces inherited from class org.apache.catalina.realm.RealmBase

      `RealmBase.AllRolesMode`

    - ### Nested classes/interfaces inherited from interface org.apache.catalina.Lifecycle

      `Lifecycle.SingleUse`

  - ### Field Summary

    Fields
    Modifier and Type | Field | Description
    --- | --- | ---
    `protected java.lang.String` | `appName` | The application name passed to the JAAS `LoginContext`, which uses it to select the set of relevant `LoginModule`s.
    `protected java.lang.String` | `configFile` | Path to find a JAAS configuration file, if not set global JVM JAAS configuration will be used.
    `protected javax.security.auth.login.Configuration` | `jaasConfiguration` |
    `protected boolean` | `jaasConfigurationLoaded` |
    `protected java.util.List<java.lang.String>` | `roleClasses` | The list of role class names, split out for easy processing.
    `protected java.lang.String` | `roleClassNames` | Comma-delimited list of `java.security.Principal` classes that represent security roles.
    `protected boolean` | `useContextClassLoader` | Whether to use context ClassLoader or default ClassLoader.
    `protected java.util.List<java.lang.String>` | `userClasses` | The set of user class names, split out for easy processing.
    `protected java.lang.String` | `userClassNames` | Comma-delimited list of `java.security.Principal` classes that represent individual users.

    - ### Fields inherited from class org.apache.catalina.realm.RealmBase

      `allRolesMode, container, containerLog, realmPath, sm, stripRealmForGss, support, validate, x509UsernameRetriever, x509UsernameRetrieverClassName`

    - ### Fields inherited from class org.apache.catalina.util.LifecycleMBeanBase

      `mserver`

    - ### Fields inherited from interface org.apache.catalina.Lifecycle

      `AFTER_DESTROY_EVENT, AFTER_INIT_EVENT, AFTER_START_EVENT, AFTER_STOP_EVENT, BEFORE_DESTROY_EVENT, BEFORE_INIT_EVENT, BEFORE_START_EVENT, BEFORE_STOP_EVENT, CONFIGURE_START_EVENT, CONFIGURE_STOP_EVENT, PERIODIC_EVENT, START_EVENT, STOP_EVENT`

  - ### Constructor Summary

    Constructors
    Constructor | Description
    --- | ---
    `JAASRealm()` |

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `java.security.Principal` | `authenticate​(java.lang.String username, java.lang.String credentials)` | Return the `Principal` associated with the specified username and credentials, if there is one; otherwise return `null`.
    `java.security.Principal` | `authenticate​(java.lang.String username, java.lang.String clientDigest, java.lang.String nonce, java.lang.String nc, java.lang.String cnonce, java.lang.String qop, java.lang.String realmName, java.lang.String md5a2)` | Return the `Principal` associated with the specified username and digest, if there is one; otherwise return `null`.
    `protected java.security.Principal` | `authenticate​(java.lang.String username, javax.security.auth.callback.CallbackHandler callbackHandler)` | Perform the actual JAAS authentication.
    `protected java.security.Principal` | `createPrincipal​(java.lang.String username, javax.security.auth.Subject subject, javax.security.auth.login.LoginContext loginContext)` | Identify and return a `java.security.Principal` instance representing the authenticated user for the specified `Subject`.
    `java.lang.String` | `getAppName()` |
    `protected javax.security.auth.login.Configuration` | `getConfig()` | Load custom JAAS Configuration.
    `java.lang.String` | `getConfigFile()` |
    `protected java.lang.String` | `getPassword​(java.lang.String username)` | Get the password for the specified user.
    `protected java.security.Principal` | `getPrincipal​(java.lang.String username)` | Get the principal associated with the specified user.
    `java.lang.String` | `getRoleClassNames()` |
    `java.lang.String` | `getUserClassNames()` |
    `boolean` | `isAvailable()` | Return the availability of the realm for authentication.
    `boolean` | `isUseContextClassLoader()` | Returns whether to use the context or default ClassLoader.
    `protected java.lang.String` | `makeLegalForJAAS​(java.lang.String src)` | Ensure the given name is legal for JAAS configuration.
    `protected void` | `parseClassNames​(java.lang.String classNamesString, java.util.List<java.lang.String> classNamesList)` | Parses a comma-delimited list of class names, and store the class names in the provided List.
    `void` | `setAppName​(java.lang.String name)` | Set the JAAS `LoginContext` app name.
    `void` | `setConfigFile​(java.lang.String configFile)` | Set the JAAS configuration file.
    `void` | `setContainer​(Container container)` | Set the Container with which this Realm has been associated.
    `void` | `setRoleClassNames​(java.lang.String roleClassNames)` | Sets the list of comma-delimited classes that represent roles.
    `void` | `setUseContextClassLoader​(boolean useContext)` | Sets whether to use the context or default ClassLoader.
    `void` | `setUserClassNames​(java.lang.String userClassNames)` | Sets the list of comma-delimited classes that represent individual users.
    `protected void` | `startInternal()` | Prepare for the beginning of active use of the public methods of this component and implement the requirements of `LifecycleBase.startInternal()`.

    - ### Methods inherited from class org.apache.catalina.realm.RealmBase

      `addPropertyChangeListener, authenticate, authenticate, authenticate, authenticate, backgroundProcess, findSecurityConstraints, getAllRolesMode, getContainer, getCredentialHandler, getDigest, getDomainInternal, getObjectNameKeyProperties, getPrincipal, getPrincipal, getPrincipal, getRealmPath, getRealmSuffix, getRoles, getServer, getTransportGuaranteeRedirectStatus, getValidate, getX509UsernameRetrieverClassName, hasMessageDigest, hasResourcePermission, hasRole, hasRoleInternal, hasUserDataPermission, initInternal, isStripRealmForGss, main, removePropertyChangeListener, setAllRolesMode, setCredentialHandler, setRealmPath, setStripRealmForGss, setTransportGuaranteeRedirectStatus, setValidate, setX509UsernameRetrieverClassName, stopInternal, toString`

    - ### Methods inherited from class org.apache.catalina.util.LifecycleMBeanBase

      `destroyInternal, getDomain, getObjectName, postDeregister, postRegister, preDeregister, preRegister, register, setDomain, unregister, unregister`

    - ### Methods inherited from class org.apache.catalina.util.LifecycleBase

      `addLifecycleListener, destroy, findLifecycleListeners, fireLifecycleEvent, getState, getStateName, getThrowOnFailure, init, removeLifecycleListener, setState, setState, setThrowOnFailure, start, stop`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- - ### Field Detail

    - #### appName

          protected java.lang.String appName

      The application name passed to the JAAS `LoginContext`, which uses it to select the set of relevant `LoginModule`s.

    - #### roleClasses

          protected final java.util.List<java.lang.String> roleClasses

      The list of role class names, split out for easy processing.

    - #### userClasses

          protected final java.util.List<java.lang.String> userClasses

      The set of user class names, split out for easy processing.

    - #### useContextClassLoader

          protected boolean useContextClassLoader

      Whether to use context ClassLoader or default ClassLoader. True means use context ClassLoader, and True is the default value.

    - #### configFile

          protected java.lang.String configFile

      Path to find a JAAS configuration file, if not set global JVM JAAS configuration will be used.

    - #### jaasConfiguration

          protected volatile javax.security.auth.login.Configuration jaasConfiguration

    - #### jaasConfigurationLoaded

          protected volatile boolean jaasConfigurationLoaded

    - #### roleClassNames

          protected java.lang.String roleClassNames

      Comma-delimited list of `java.security.Principal` classes that represent security roles.

    - #### userClassNames

          protected java.lang.String userClassNames

      Comma-delimited list of `java.security.Principal` classes that represent individual users.

  - ### Constructor Detail

    - #### JAASRealm

          public JAASRealm()

  - ### Method Detail

    - #### getConfigFile

          public java.lang.String getConfigFile()

      Returns:
        the path of the JAAS configuration file.

    - #### setConfigFile

          public void setConfigFile​(java.lang.String configFile)

      Set the JAAS configuration file.
      Parameters:
        `configFile` - The JAAS configuration file

    - #### setAppName

          public void setAppName​(java.lang.String name)

      Set the JAAS `LoginContext` app name.
      Parameters:
        `name` - The application name that will be used to retrieve the set of relevant `LoginModule`s

    - #### getAppName

          public java.lang.String getAppName()

      Returns:
        the application name.

    - #### setUseContextClassLoader

          public void setUseContextClassLoader​(boolean useContext)

      Sets whether to use the context or default ClassLoader. True means use context ClassLoader.
      Parameters:
        `useContext` - True means use context ClassLoader

    - #### isUseContextClassLoader

          public boolean isUseContextClassLoader()

      Returns whether to use the context or default ClassLoader. True means to use the context ClassLoader.
      Returns:
        The value of useContextClassLoader

    - #### setContainer

          public void setContainer​(Container container)

      Description copied from class: `RealmBase`
      Set the Container with which this Realm has been associated.
      Specified by:
        `setContainer` in interface `Contained`
      Overrides:
        `setContainer` in class `RealmBase`
      Parameters:
        `container` - The associated Container

    - #### getRoleClassNames

          public java.lang.String getRoleClassNames()

    - #### setRoleClassNames

          public void setRoleClassNames​(java.lang.String roleClassNames)

      Sets the list of comma-delimited classes that represent roles. The classes in the list must implement `java.security.Principal`. The supplied list of classes will be parsed when `LifecycleBase.start()` is called.
      Parameters:
        `roleClassNames` - The class names list

    - #### parseClassNames

          protected void parseClassNames​(java.lang.String classNamesString,
                                         java.util.List<java.lang.String> classNamesList)

      Parses a comma-delimited list of class names, and store the class names in the provided List. Each class must implement `java.security.Principal`.
      Parameters:
        `classNamesString` - a comma-delimited list of fully qualified class names.
        `classNamesList` - the list in which the class names will be stored. The list is cleared before being populated.

    - #### getUserClassNames

          public java.lang.String getUserClassNames()

    - #### setUserClassNames

          public void setUserClassNames​(java.lang.String userClassNames)

      Sets the list of comma-delimited classes that represent individual users. The classes in the list must implement `java.security.Principal`. The supplied list of classes will be parsed when `LifecycleBase.start()` is called.
      Parameters:
        `userClassNames` - The class names list

    - #### authenticate

          public java.security.Principal authenticate​(java.lang.String username,
                                                      java.lang.String credentials)

      Return the `Principal` associated with the specified username and credentials, if there is one; otherwise return `null`.
      Specified by:
        `authenticate` in interface `Realm`
      Overrides:
        `authenticate` in class `RealmBase`
      Parameters:
        `username` - Username of the `Principal` to look up
        `credentials` - Password or other credentials to use in authenticating this username
      Returns:
        the associated principal, or `null` if there is none.

    - #### authenticate

          public java.security.Principal authenticate​(java.lang.String username,
                                                      java.lang.String clientDigest,
                                                      java.lang.String nonce,
                                                      java.lang.String nc,
                                                      java.lang.String cnonce,
                                                      java.lang.String qop,
                                                      java.lang.String realmName,
                                                      java.lang.String md5a2)

      Return the `Principal` associated with the specified username and digest, if there is one; otherwise return `null`.
      Specified by:
        `authenticate` in interface `Realm`
      Overrides:
        `authenticate` in class `RealmBase`
      Parameters:
        `username` - Username of the `Principal` to look up
        `clientDigest` - Digest to use in authenticating this username
        `nonce` - Server generated nonce
        `nc` - Nonce count
        `cnonce` - Client generated nonce
        `qop` - Quality of protection applied to the message
        `realmName` - Realm name
        `md5a2` - Second MD5 digest used to calculate the digest MD5(Method + ":" + uri)
      Returns:
        the associated principal, or `null` if there is none.

    - #### authenticate

          protected java.security.Principal authenticate​(java.lang.String username,
                                                         javax.security.auth.callback.CallbackHandler callbackHandler)

      Perform the actual JAAS authentication.
      Parameters:
        `username` - The user name
        `callbackHandler` - The callback handler
      Returns:
        the associated principal, or `null` if there is none.

    - #### getPassword

          protected java.lang.String getPassword​(java.lang.String username)

      Description copied from class: `RealmBase`
      Get the password for the specified user.
      Specified by:
        `getPassword` in class `RealmBase`
      Parameters:
        `username` - The user name
      Returns:
        the password associated with the given principal's user name. This always returns null as the JAASRealm has no way of obtaining this information.

    - #### getPrincipal

          protected java.security.Principal getPrincipal​(java.lang.String username)

      Description copied from class: `RealmBase`
      Get the principal associated with the specified user.
      Specified by:
        `getPrincipal` in class `RealmBase`
      Parameters:
        `username` - The user name
      Returns:
        the `Principal` associated with the given user name.

    - #### createPrincipal

          protected java.security.Principal createPrincipal​(java.lang.String username,
                                                            javax.security.auth.Subject subject,
                                                            javax.security.auth.login.LoginContext loginContext)

      Identify and return a `java.security.Principal` instance representing the authenticated user for the specified `Subject`. The Principal is constructed by scanning the list of Principals returned by the JAASLoginModule. The first `Principal` object that matches one of the class names supplied as a "user class" is the user Principal. This object is returned to the caller. Any remaining principal objects returned by the LoginModules are mapped to roles, but only if their respective classes match one of the "role class" classes. If a user Principal cannot be constructed, return `null`.
      Parameters:
        `username` - The associated user name
        `subject` - The `Subject` representing the logged-in user
        `loginContext` - Associated with the Principal so `LoginContext.logout()` can be called later
      Returns:
        the principal object

    - #### makeLegalForJAAS

          protected java.lang.String makeLegalForJAAS​(java.lang.String src)

      Ensure the given name is legal for JAAS configuration. Added for Bugzilla 30869, made protected for easy customization in case my implementation is insufficient, which I think is very likely.
      Parameters:
        `src` - The name to validate
      Returns:
        A string that's a valid JAAS realm name

    - #### startInternal

          protected void startInternal()
                                throws LifecycleException

      Prepare for the beginning of active use of the public methods of this component and implement the requirements of `LifecycleBase.startInternal()`.
      Overrides:
        `startInternal` in class `RealmBase`
      Throws:
        `LifecycleException` - if this component detects a fatal error that prevents this component from being used

    - #### getConfig

          protected javax.security.auth.login.Configuration getConfig()

      Load custom JAAS Configuration.
      Returns:
        the loaded configuration

    - #### isAvailable

          public boolean isAvailable()

      Description copied from interface: `Realm`
      Return the availability of the realm for authentication.
      Returns:
        `true` if the realm is able to perform authentication