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 thejavax.security.auth.login.LoginContext
constructor, to specify the application name used to select the set of relevantLoginModules
required.The JAAS Specification describes the result of a successful login as a
javax.security.auth.Subject
instance, which can contain zero or morejava.security.Principal
objects in the return value of theSubject.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 underlyingLoginMethod
implementation executed by JAAS, the following policy is implemented by this Realm:- The JAAS
LoginModule
is assumed to return aSubject
with at least onePrincipal
instance representing the user himself or herself, and zero or more separatePrincipals
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 methodHttpServletRequest.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 bySubject.getPrincipals()
, it will identify the firstPrincipal
that matches the "user classes" list as thePrincipal
for this user. - As this Realm iterates over the
Principals
returned bySubject.getPrincipals()
, it will accumulate the set of allPrincipals
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 aPrincipal
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-suppliedLoginModule
- As with other
Realm
implementations, digested passwords are supported if the<Realm>
element inserver.xml
contains adigest
attribute;JAASCallbackHandler
will digest the password prior to passing it back to theLoginModule
- 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 JAASLoginContext
, which uses it to select the set of relevantLoginModule
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 ofjava.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 ofjava.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 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 thePrincipal
associated with the specified username and credentials, if there is one; otherwise returnnull
.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 thePrincipal
associated with the specified username and digest, if there is one; otherwise returnnull
.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 ajava.security.Principal
instance representing the authenticated user for the specifiedSubject
.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 JAASLoginContext
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 ofLifecycleBase.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, getRealmPath, getRealmSuffix, 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
-
-
-
-
Field Detail
-
appName
protected java.lang.String appName
The application name passed to the JAASLoginContext
, which uses it to select the set of relevantLoginModule
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 ofjava.security.Principal
classes that represent security roles.
-
userClassNames
protected java.lang.String userClassNames
Comma-delimited list ofjava.security.Principal
classes that represent individual users.
-
-
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 JAASLoginContext
app name.- Parameters:
name
- The application name that will be used to retrieve the set of relevantLoginModule
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 interfaceContained
- Overrides:
setContainer
in classRealmBase
- 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 implementjava.security.Principal
. The supplied list of classes will be parsed whenLifecycleBase.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 implementjava.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 implementjava.security.Principal
. The supplied list of classes will be parsed whenLifecycleBase.start()
is called.- Parameters:
userClassNames
- The class names list
-
authenticate
public java.security.Principal authenticate(java.lang.String username, java.lang.String credentials)
Return thePrincipal
associated with the specified username and credentials, if there is one; otherwise returnnull
.- Specified by:
authenticate
in interfaceRealm
- Overrides:
authenticate
in classRealmBase
- Parameters:
username
- Username of thePrincipal
to look upcredentials
- 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 thePrincipal
associated with the specified username and digest, if there is one; otherwise returnnull
.- Specified by:
authenticate
in interfaceRealm
- Overrides:
authenticate
in classRealmBase
- Parameters:
username
- Username of thePrincipal
to look upclientDigest
- Digest to use in authenticating this usernamenonce
- Server generated noncenc
- Nonce countcnonce
- Client generated nonceqop
- Quality of protection applied to the messagerealmName
- Realm namemd5a2
- 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 namecallbackHandler
- 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 classRealmBase
- 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 classRealmBase
- 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 ajava.security.Principal
instance representing the authenticated user for the specifiedSubject
. The Principal is constructed by scanning the list of Principals returned by the JAASLoginModule. The firstPrincipal
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, returnnull
.- Parameters:
username
- The associated user namesubject
- TheSubject
representing the logged-in userloginContext
- Associated with the Principal soLoginContext.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 ofLifecycleBase.startInternal()
.- Overrides:
startInternal
in classRealmBase
- 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
-
-