📄 jndirealm.java
字号:
* a directory search. If no roles are associated with this user,
* a zero-length List is returned.
*
* @param context The directory context we are searching
* @param user The User to be checked
*
* @exception NamingException if a directory server error occurs
*/
protected List getRoles(DirContext context, User user)
throws NamingException {
if (user == null)
return (null);
String dn = user.dn;
String username = user.username;
if (dn == null || username == null)
return (null);
if (debug >= 2)
log(" getRoles(" + dn + ")");
// Start with roles retrieved from the user entry
ArrayList list = user.roles;
if (list == null) {
list = new ArrayList();
}
// Are we configured to do role searches?
if ((roleFormat == null) || (roleName == null))
return (list);
// Set up parameters for an appropriate search
String filter = roleFormat.format(new String[] { doRFC2254Encoding(dn), username });
SearchControls controls = new SearchControls();
if (roleSubtree)
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
else
controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
controls.setReturningAttributes(new String[] {roleName});
// Perform the configured search and process the results
if (debug >= 3) {
log(" Searching role base '" + roleBase + "' for attribute '" +
roleName + "'");
log(" With filter expression '" + filter + "'");
}
NamingEnumeration results =
context.search(roleBase, filter, controls);
if (results == null)
return (list); // Should never happen, but just in case ...
while (results.hasMore()) {
SearchResult result = (SearchResult) results.next();
Attributes attrs = result.getAttributes();
if (attrs == null)
continue;
list = addAttributeValues(roleName, attrs, list);
}
if (debug >= 2) {
if (list != null) {
log(" Returning " + list.size() + " roles");
for (int i=0; i<list.size(); i++)
log( " Found role " + list.get(i));
} else {
log(" getRoles about to return null ");
}
}
return (list);
}
/**
* Return a String representing the value of the specified attribute.
*
* @param attrId Attribute name
* @param attrs Attributes containing the required value
*
* @exception NamingException if a directory server error occurs
*/
private String getAttributeValue(String attrId, Attributes attrs)
throws NamingException {
if (debug >= 3)
log(" retrieving attribute " + attrId);
if (attrId == null || attrs == null)
return null;
Attribute attr = attrs.get(attrId);
if (attr == null)
return (null);
Object value = attr.get();
if (value == null)
return (null);
String valueString = null;
if (value instanceof byte[])
valueString = new String((byte[]) value);
else
valueString = value.toString();
return valueString;
}
/**
* Add values of a specified attribute to a list
*
* @param attrId Attribute name
* @param attrs Attributes containing the new values
* @param values ArrayList containing values found so far
*
* @exception NamingException if a directory server error occurs
*/
private ArrayList addAttributeValues(String attrId,
Attributes attrs,
ArrayList values)
throws NamingException{
if (debug >= 3)
log(" retrieving values for attribute " + attrId);
if (attrId == null || attrs == null)
return values;
if (values == null)
values = new ArrayList();
Attribute attr = attrs.get(attrId);
if (attr == null)
return (values);
NamingEnumeration e = attr.getAll();
while(e.hasMore()) {
String value = (String)e.next();
values.add(value);
}
return values;
}
/**
* Close any open connection to the directory server for this Realm.
*
* @param context The directory context to be closed
*/
protected void close(DirContext context) {
// Do nothing if there is no opened connection
if (context == null)
return;
// Close our opened connection
try {
if (debug >= 1)
log("Closing directory context");
context.close();
} catch (NamingException e) {
log(sm.getString("jndiRealm.close"), e);
}
this.context = null;
}
/**
* Return a short name for this Realm implementation.
*/
protected String getName() {
return (name);
}
/**
* Return the password associated with the given principal's user name.
*/
protected String getPassword(String username) {
return (null);
}
/**
* Return the Principal associated with the given user name.
*/
protected Principal getPrincipal(String username) {
return (null);
}
/**
* Open (if necessary) and return a connection to the configured
* directory server for this Realm.
*
* @exception NamingException if a directory server error occurs
*/
protected DirContext open() throws NamingException {
// Do nothing if there is a directory server connection already open
if (context != null)
return (context);
try {
// Ensure that we have a directory context available
context = new InitialDirContext(getDirectoryContextEnvironment());
} catch (NamingException e) {
connectionAttempt = 1;
// log the first exception.
log(sm.getString("jndiRealm.exception"), e);
// Try connecting to the alternate url.
context = new InitialDirContext(getDirectoryContextEnvironment());
} finally {
// reset it in case the connection times out.
// the primary may come back.
connectionAttempt = 0;
}
return (context);
}
/**
* Create our directory context configuration.
*
* @return java.util.Hashtable the configuration for the directory context.
*/
protected Hashtable getDirectoryContextEnvironment() {
Hashtable env = new Hashtable();
// Configure our directory context environment.
if (debug >= 1 && connectionAttempt == 0)
log("Connecting to URL " + connectionURL);
else if (debug >= 1 && connectionAttempt > 0)
log("Connecting to URL " + alternateURL);
env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory);
if (connectionName != null)
env.put(Context.SECURITY_PRINCIPAL, connectionName);
if (connectionPassword != null)
env.put(Context.SECURITY_CREDENTIALS, connectionPassword);
if (connectionURL != null && connectionAttempt == 0)
env.put(Context.PROVIDER_URL, connectionURL);
else if (alternateURL != null && connectionAttempt > 0)
env.put(Context.PROVIDER_URL, alternateURL);
if (authentication != null)
env.put(Context.SECURITY_AUTHENTICATION, authentication);
if (protocol != null)
env.put(Context.SECURITY_PROTOCOL, protocol);
if (referrals != null)
env.put(Context.REFERRAL, referrals);
return env;
}
/**
* Release our use of this connection so that it can be recycled.
*
* @param context The directory context to release
*/
protected void release(DirContext context) {
; // NO-OP since we are not pooling anything
}
// ------------------------------------------------------ Lifecycle Methods
/**
* Prepare for active use of the public methods of this Component.
*
* @exception LifecycleException if this component detects a fatal error
* that prevents it from being started
*/
public void start() throws LifecycleException {
// Validate that we can open our connection
try {
open();
} catch (NamingException e) {
throw new LifecycleException(sm.getString("jndiRealm.open"), e);
}
// Perform normal superclass initialization
super.start();
}
/**
* Gracefully shut down active use of the public methods of this Component.
*
* @exception LifecycleException if this component detects a fatal error
* that needs to be reported
*/
public void stop() throws LifecycleException {
// Perform normal superclass finalization
super.stop();
// Close any open directory server connection
close(this.context);
}
/**
* Given a string containing LDAP patterns for user locations (separated by
* parentheses in a pseudo-LDAP search string format -
* "(location1)(location2)", returns an array of those paths. Real LDAP
* search strings are supported as well (though only the "|" "OR" type).
*
* @param userPatternString - a string LDAP search paths surrounded by
* parentheses
*/
protected String[] parseUserPatternString(String userPatternString) {
if (userPatternString != null) {
ArrayList pathList = new ArrayList();
int startParenLoc = userPatternString.indexOf('(');
if (startParenLoc == -1) {
// no parens here; return whole thing
return new String[] {userPatternString};
}
int startingPoint = 0;
while (startParenLoc > -1) {
int endParenLoc = 0;
// weed out escaped open parens and parens enclosing the
// whole statement (in the case of valid LDAP search
// strings: (|(something)(somethingelse))
while ( (userPatternString.charAt(startParenLoc + 1) == '|') ||
(startParenLoc != 0 && userPatternString.charAt(startParenLoc - 1) == '\\') ) {
startParenLoc = userPatternString.indexOf("(", startParenLoc+1);
}
endParenLoc = userPatternString.indexOf(")", startParenLoc+1);
// weed out escaped end-parens
while (userPatternString.charAt(endParenLoc - 1) == '\\') {
endParenLoc = userPatternString.indexOf(")", endParenLoc+1);
}
String nextPathPart = userPatternString.substring
(startParenLoc+1, endParenLoc);
pathList.add(nextPathPart);
startingPoint = endParenLoc+1;
startParenLoc = userPatternString.indexOf('(', startingPoint);
}
return (String[])pathList.toArray(new String[] {});
}
return null;
}
/**
* Given an LDAP search string, returns the string with certain characters
* escaped according to RFC 2254 guidelines.
* The character mapping is as follows:
* char -> Replacement
* ---------------------------
* * -> \2a
* ( -> \28
* ) -> \29
* \ -> \5c
* \0 -> \00
* @param inString string to escape according to RFC 2254 guidelines
* @return
*/
protected String doRFC2254Encoding(String inString) {
StringBuffer buf = new StringBuffer(inString.length());
for (int i = 0; i < inString.length(); i++) {
char c = inString.charAt(i);
switch (c) {
case '\\':
buf.append("\\5c");
break;
case '*':
buf.append("\\2a");
break;
case '(':
buf.append("\\28");
break;
case ')':
buf.append("\\29");
break;
case '\0':
buf.append("\\00");
break;
default:
buf.append(c);
break;
}
}
return buf.toString();
}
}
// ------------------------------------------------------ Private Classes
/**
* A private class representing a User
*/
class User {
String username = null;
String dn = null;
String password = null;
ArrayList roles = null;
User(String username, String dn, String password, ArrayList roles) {
this.username = username;
this.dn = dn;
this.password = password;
this.roles = roles;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -