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:
  `MBeanRegistration`, `Contained`, `GSSRealm`, `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 String`
`appName`
The application name passed to the JAAS `LoginContext`, which uses it to select the set of relevant `LoginModule`s.
`protected String`
`configFile`
Path to find a JAAS configuration file, if not set global JVM JAAS configuration will be used.
`protected Configuration`
`jaasConfiguration`
`protected boolean`
`jaasConfigurationLoaded`
`protected static final String`
`name`
Deprecated.
This will be removed in Tomcat 9 onwards.
`protected final List<String>`
`roleClasses`
The list of role class names, split out for easy processing.
`protected 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 final List<String>`
`userClasses`
The set of user class names, split out for easy processing.
`protected 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, USER_ATTRIBUTES_DELIMITER, USER_ATTRIBUTES_WILDCARD, userAttributes, userAttributesList, 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

Modifier and Type
Method
Description
`Principal`
`authenticate(String username, String credentials)`
Try to authenticate using the specified username and credentials.
`Principal`
`authenticate(String username, String clientDigest, String nonce, String nc, String cnonce, String qop, String realmName, String digestA2, String algorithm)`
Try to authenticate with the specified username, which matches the digest calculated using the given parameters using the method described in RFC 7616.
`protected Principal`
`authenticate(String username, CallbackHandler callbackHandler)`
Perform the actual JAAS authentication.
`protected Principal`
`createPrincipal(String username, Subject subject, LoginContext loginContext)`
Identify and return a `java.security.Principal` instance representing the authenticated user for the specified `Subject`.
`String`
`getAppName()`
`protected Configuration`
`getConfig()`
Load custom JAAS Configuration.
`String`
`getConfigFile()`
`protected String`
`getName()`
Deprecated.
`protected String`
`getPassword(String username)`
Get the password for the specified user.
`protected Principal`
`getPrincipal(String username)`
Get the principal associated with the specified user.
`String`
`getRoleClassNames()`
`String`
`getUserClassNames()`
`boolean`
`isAvailable()`
Return the availability of the realm for authentication.
`boolean`
`isUseContextClassLoader()`
Returns whether to use the context or default ClassLoader.
`protected String`
`makeLegalForJAAS(String src)`
Ensure the given name is legal for JAAS configuration.
`protected void`
`parseClassNames(String classNamesString, List<String> classNamesList)`
Parses a comma-delimited list of class names, and store the class names in the provided List.
`void`
`setAppName(String name)`
Set the JAAS `LoginContext` app name.
`void`
`setConfigFile(String configFile)`
Set the JAAS configuration file.
`void`
`setContainer(Container container)`
Set the `Container` with which this instance is associated.
`void`
`setRoleClassNames(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(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, authenticate, backgroundProcess, Digest, findSecurityConstraints, getAllRolesMode, getContainer, getCredentialHandler, getDigest, getDigest, getDomainInternal, getObjectNameKeyProperties, getPrincipal, getPrincipal, getPrincipal, getRealmPath, getRealmSuffix, getRoles, getServer, getTransportGuaranteeRedirectStatus, getUserAttributes, getValidate, getX509UsernameRetrieverClassName, hasMessageDigest, hasResourcePermission, hasRole, hasRoleInternal, hasUserDataPermission, initInternal, isStripRealmForGss, main, parseUserAttributes, removePropertyChangeListener, setAllRolesMode, setCredentialHandler, setRealmPath, setStripRealmForGss, setTransportGuaranteeRedirectStatus, setUserAttributes, setValidate, setX509UsernameRetrieverClassName, stopInternal, toString`

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

`destroyInternal, getDomain, getObjectName, postDeregister, postRegister, preDeregister, preRegister, register, setDomain, 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 Details

### appName

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

### name

@Deprecated protected static final String name
Deprecated.
This will be removed in Tomcat 9 onwards.
Descriptive information about this `Realm` implementation.

See Also:
  - Constant Field Values

### roleClasses

protected final List<String> roleClasses
The list of role class names, split out for easy processing.

### userClasses

protected final List<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 String configFile
Path to find a JAAS configuration file, if not set global JVM JAAS configuration will be used.

### jaasConfiguration

protected volatile Configuration jaasConfiguration

### jaasConfigurationLoaded

protected volatile boolean jaasConfigurationLoaded

### roleClassNames

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

### userClassNames

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

## Constructor Details

### JAASRealm

public JAASRealm()

## Method Details

### getConfigFile

public String getConfigFile()

Returns:
  the path of the JAAS configuration file.

### setConfigFile

public void setConfigFile(String configFile)
Set the JAAS configuration file.

Parameters:
  `configFile` - The JAAS configuration file

### setAppName

public void setAppName(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 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 interface: `Contained`
Set the `Container` with which this instance is associated.

Specified by:
  `setContainer` in interface `Contained`
Overrides:
  `setContainer` in class `RealmBase`
Parameters:
  `container` - The Container instance with which this instance is to be associated, or `null` to disassociate this instance from any Container

### getRoleClassNames

public String getRoleClassNames()

### setRoleClassNames

public void setRoleClassNames(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(String classNamesString, List<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 String getUserClassNames()

### setUserClassNames

public void setUserClassNames(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 Principal authenticate(String username, String credentials)
Description copied from interface: `Realm`
Try to authenticate using the specified username and credentials.

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 Principal authenticate(String username, String clientDigest, String nonce, String nc, String cnonce, String qop, String realmName, String digestA2, String algorithm)
Description copied from interface: `Realm`
Try to authenticate with the specified username, which matches the digest calculated using the given parameters using the method described in RFC 7616.

Specified by:
  `authenticate` in interface `Realm`
Overrides:
  `authenticate` in class `RealmBase`
Parameters:
  `username` - Username of the Principal to look up
  `clientDigest` - Digest which has been submitted by the client
  `nonce` - Unique (or supposedly unique) token which has been used for this request
  `nc` - the nonce counter
  `cnonce` - the client chosen nonce
  `qop` - the "quality of protection" (`nc` and `cnonce` will only be used, if `qop` is not `null`).
  `realmName` - Realm name
  `digestA2` - Second digest calculated as digest(Method + ":" + uri)
  `algorithm` - The message digest algorithm to use
Returns:
  the associated principal, or `null` if there is none.

### authenticate

protected Principal authenticate(String username, 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.

### getName

@Deprecated protected String getName()
Deprecated.

Specified by:
  `getName` in class `RealmBase`
Returns:
  a short name for this Realm implementation, for use in log messages.

### getPassword

protected String getPassword(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 Principal getPrincipal(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 Principal createPrincipal(String username, Subject subject, 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 String makeLegalForJAAS(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
Description copied from class: `RealmBase`
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 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.

Specified by:
  `isAvailable` in interface `Realm`
Overrides:
  `isAvailable` in class `RealmBase`
Returns:
  `true` if the realm is able to perform authentication