| Method from org.apache.catalina.realm.JAASRealm Detail: |
public Principal authenticate(String username,
String credentials) {
// Establish a LoginContext to use for authentication
try {
LoginContext loginContext = null;
if( appName==null ) appName="Tomcat";
if( log.isDebugEnabled())
log.debug(sm.getString("jaasRealm.beginLogin", username, appName));
// What if the LoginModule is in the container class loader ?
ClassLoader ocl = null;
if (!isUseContextClassLoader()) {
ocl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(
this.getClass().getClassLoader());
}
try {
loginContext = new LoginContext
(appName, new JAASCallbackHandler(this, username,
credentials));
} catch (Throwable e) {
log.error(sm.getString("jaasRealm.unexpectedError"), e);
return (null);
} finally {
if(!isUseContextClassLoader()) {
Thread.currentThread().setContextClassLoader(ocl);
}
}
if( log.isDebugEnabled())
log.debug("Login context created " + username);
// Negotiate a login via this LoginContext
Subject subject = null;
try {
loginContext.login();
subject = loginContext.getSubject();
if (subject == null) {
if( log.isDebugEnabled())
log.debug(sm.getString("jaasRealm.failedLogin", username));
return (null);
}
} catch (AccountExpiredException e) {
if (log.isDebugEnabled())
log.debug(sm.getString("jaasRealm.accountExpired", username));
return (null);
} catch (CredentialExpiredException e) {
if (log.isDebugEnabled())
log.debug(sm.getString("jaasRealm.credentialExpired", username));
return (null);
} catch (FailedLoginException e) {
if (log.isDebugEnabled())
log.debug(sm.getString("jaasRealm.failedLogin", username));
return (null);
} catch (LoginException e) {
log.warn(sm.getString("jaasRealm.loginException", username), e);
return (null);
} catch (Throwable e) {
log.error(sm.getString("jaasRealm.unexpectedError"), e);
return (null);
}
if( log.isDebugEnabled())
log.debug(sm.getString("jaasRealm.loginContextCreated", username));
// Return the appropriate Principal for this authenticated Subject
Principal principal = createPrincipal(username, subject);
if (principal == null) {
log.debug(sm.getString("jaasRealm.authenticateFailure", username));
return (null);
}
if (log.isDebugEnabled()) {
log.debug(sm.getString("jaasRealm.authenticateSuccess", username));
}
return (principal);
} catch( Throwable t) {
log.error( "error ", t);
return null;
}
}
Return the Principal associated with the specified username and
credentials, if there is one; otherwise return null.
If there are any errors with the JDBC connection, executing
the query or anything we return null (don't authenticate). This
event is also logged, and the connection will be closed so that
a subsequent request will automatically re-open it. |
protected Principal createPrincipal(String username,
Subject subject) {
// Prepare to scan the Principals for this Subject
List< String > roles = new ArrayList< String >();
Principal userPrincipal = null;
// Scan the Principals for this Subject
Iterator< Principal > principals = subject.getPrincipals().iterator();
while (principals.hasNext()) {
Principal principal = principals.next();
String principalClass = principal.getClass().getName();
if( log.isDebugEnabled() ) {
log.debug(sm.getString("jaasRealm.checkPrincipal", principal, principalClass));
}
if (userPrincipal == null && userClasses.contains(principalClass)) {
userPrincipal = principal;
if( log.isDebugEnabled() ) {
log.debug(sm.getString("jaasRealm.userPrincipalSuccess", principal.getName()));
}
}
if (roleClasses.contains(principalClass)) {
roles.add(principal.getName());
if( log.isDebugEnabled() ) {
log.debug(sm.getString("jaasRealm.rolePrincipalAdd", principal.getName()));
}
}
}
// Print failure message if needed
if (userPrincipal == null) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("jaasRealm.userPrincipalFailure"));
log.debug(sm.getString("jaasRealm.rolePrincipalFailure"));
}
} else {
if (roles.size() == 0) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("jaasRealm.rolePrincipalFailure"));
}
}
}
// Return the resulting Principal for our authenticated user
return new GenericPrincipal(this, username, null, roles, userPrincipal);
}
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 tha 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. |
public String getAppName() {
return appName;
}
getter for the appName member variable |
protected String getName() {
return (name);
}
Return a short name for this Realm implementation. |
protected String getPassword(String username) {
return (null);
}
Return the password associated with the given principal's user name. |
protected Principal getPrincipal(String username) {
return (null);
}
Return the Principal associated with the given user name. |
public String getRoleClassNames() {
return (this.roleClassNames);
}
|
public String getUserClassNames() {
return (this.userClassNames);
}
|
public boolean isUseContextClassLoader() {
return useContextClassLoader;
}
Returns whether to use the context or default ClassLoader.
True means to use the context ClassLoader. |
protected String makeLegalForJAAS(String src) {
String result = src;
// Default name is "other" per JAAS spec
if(result == null) {
result = "other";
}
// Strip leading slash if present, as Sun JAAS impl
// barfs on it (see Bugzilla 30869 bug report).
if(result.startsWith("/")) {
result = result.substring(1);
}
return result;
}
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. |
protected void parseClassNames(String classNamesString,
List classNamesList) {
classNamesList.clear();
if (classNamesString == null) return;
ClassLoader loader = this.getClass().getClassLoader();
if (isUseContextClassLoader())
loader = Thread.currentThread().getContextClassLoader();
String[] classNames = classNamesString.split("[ ]*,[ ]*");
for (int i=0; i< classNames.length; i++) {
if (classNames[i].length()==0) continue;
try {
Class principalClass = Class.forName(classNames[i], false,
loader);
if (Principal.class.isAssignableFrom(principalClass)) {
classNamesList.add(classNames[i]);
} else {
log.error("Class "+classNames[i]+" is not implementing "+
"java.security.Principal! Class not added.");
}
} catch (ClassNotFoundException e) {
log.error("Class "+classNames[i]+" not found! Class not added.");
}
}
}
Parses a comma-delimited list of class names, and store the class names
in the provided List. Each class must implement
java.security.Principal. |
public void setAppName(String name) {
// ------------------------------------------------------------- Properties
appName = name;
} Deprecated! JAAS - should use the Engine (domain) name and webpp/host overrides
setter for the appName member variable |
public void setContainer(Container container) {
super.setContainer(container);
if( appName==null ) {
String name=container.getName();
name = makeLegalForJAAS(name);
appName=name;
log.info("Set JAAS app name " + appName);
}
}
|
public void setRoleClassNames(String roleClassNames) {
this.roleClassNames = 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 #start() is
called. |
public void setUseContextClassLoader(boolean useContext) {
useContextClassLoader = useContext;
log.info("Setting useContextClassLoader = " + useContext);
}
Sets whether to use the context or default ClassLoader.
True means use context ClassLoader. |
public void setUserClassNames(String userClassNames) {
this.userClassNames = 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 #start() is called. |
public void start() throws LifecycleException {
// Perform normal superclass initialization
super.start();
// These need to be called after loading configuration, in case
// useContextClassLoader appears after them in xml config
parseClassNames(userClassNames, userClasses);
parseClassNames(roleClassNames, roleClasses);
}
Prepare for active use of the public methods of this Component. |
public void stop() throws LifecycleException {
// Perform normal superclass finalization
super.stop();
}
Gracefully shut down active use of the public methods of this Component. |