Skip to content

Commit

Permalink
Polish spring-security-ldap main code
Browse files Browse the repository at this point in the history
Manually polish `spring-security-ldap` following the formatting
and checkstyle fixes.

Issue spring-projectsgh-8945
  • Loading branch information
philwebb authored and rwinch committed Aug 24, 2020
1 parent 48957b4 commit 554ef62
Show file tree
Hide file tree
Showing 33 changed files with 241 additions and 777 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ public DefaultLdapUsernameToDnMapper(String userDnBase, String usernameAttribute
@Override
public DistinguishedName buildDn(String username) {
DistinguishedName dn = new DistinguishedName(this.userDnBase);

dn.add(this.usernameAttribute, username);

return dn;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ public class DefaultSpringSecurityContextSource extends LdapContextSource {

protected final Log logger = LogFactory.getLog(getClass());

private String rootDn;

/**
* Create and initialize an instance which will connect to the supplied LDAP URL. If
* you want to use more than one server for fail-over, rather use the
Expand All @@ -62,44 +60,36 @@ public class DefaultSpringSecurityContextSource extends LdapContextSource {
*/
public DefaultSpringSecurityContextSource(String providerUrl) {
Assert.hasLength(providerUrl, "An LDAP connection URL must be supplied.");

StringTokenizer st = new StringTokenizer(providerUrl);

StringTokenizer tokenizer = new StringTokenizer(providerUrl);
ArrayList<String> urls = new ArrayList<>();

// Work out rootDn from the first URL and check that the other URLs (if any) match
while (st.hasMoreTokens()) {
String url = st.nextToken();
String rootDn = null;
while (tokenizer.hasMoreTokens()) {
String url = tokenizer.nextToken();
String urlRootDn = LdapUtils.parseRootDnFromUrl(url);

urls.add(url.substring(0, url.lastIndexOf(urlRootDn)));

this.logger.info(" URL '" + url + "', root DN is '" + urlRootDn + "'");

if (this.rootDn == null) {
this.rootDn = urlRootDn;
}
else if (!this.rootDn.equals(urlRootDn)) {
throw new IllegalArgumentException("Root DNs must be the same when using multiple URLs");
}
Assert.isTrue(rootDn == null || rootDn.equals(urlRootDn),
"Root DNs must be the same when using multiple URLs");
rootDn = (rootDn != null) ? rootDn : urlRootDn;
}

setUrls(urls.toArray(new String[0]));
setBase(this.rootDn);
setBase(rootDn);
setPooled(true);
setAuthenticationStrategy(new SimpleDirContextAuthenticationStrategy() {

@Override
@SuppressWarnings("rawtypes")
public void setupEnvironment(Hashtable env, String dn, String password) {
super.setupEnvironment(env, dn, password);
// Remove the pooling flag unless we are authenticating as the 'manager'
// user.
// Remove the pooling flag unless authenticating as the 'manager' user.
if (!DefaultSpringSecurityContextSource.this.userDn.equals(dn)
&& env.containsKey(SUN_LDAP_POOLING_FLAG)) {
DefaultSpringSecurityContextSource.this.logger.debug("Removing pooling flag for user " + dn);
env.remove(SUN_LDAP_POOLING_FLAG);
}
}

});
}

Expand Down Expand Up @@ -146,24 +136,20 @@ public DefaultSpringSecurityContextSource(List<String> urls, String baseDn) {
private static String buildProviderUrl(List<String> urls, String baseDn) {
Assert.notNull(baseDn, "The Base DN for the LDAP server must not be null.");
Assert.notEmpty(urls, "At least one LDAP server URL must be provided.");

String trimmedBaseDn = baseDn.trim();
StringBuilder providerUrl = new StringBuilder();

for (String serverUrl : urls) {
String trimmedUrl = serverUrl.trim();
if ("".equals(trimmedUrl)) {
continue;
}

providerUrl.append(trimmedUrl);
if (!trimmedUrl.endsWith("/")) {
providerUrl.append("/");
}
providerUrl.append(trimmedBaseDn);
providerUrl.append(" ");
}

return providerUrl.toString();

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,11 @@ final class LdapEncoder {
private static final int HEX = 16;

private static String[] NAME_ESCAPE_TABLE = new String[96];

private static String[] FILTER_ESCAPE_TABLE = new String['\\' + 1];

static {

// Name encoding table -------------------------------------

// all below 0x20 (control chars)
for (char c = 0; c < ' '; c++) {
NAME_ESCAPE_TABLE[c] = "\\" + toTwoCharHex(c);
}

NAME_ESCAPE_TABLE['#'] = "\\#";
NAME_ESCAPE_TABLE[','] = "\\,";
NAME_ESCAPE_TABLE[';'] = "\\;";
Expand All @@ -55,21 +48,21 @@ final class LdapEncoder {
NAME_ESCAPE_TABLE['>'] = "\\>";
NAME_ESCAPE_TABLE['\"'] = "\\\"";
NAME_ESCAPE_TABLE['\\'] = "\\\\";
}

// Filter encoding table -------------------------------------
private static String[] FILTER_ESCAPE_TABLE = new String['\\' + 1];

static {
// fill with char itself
for (char c = 0; c < FILTER_ESCAPE_TABLE.length; c++) {
FILTER_ESCAPE_TABLE[c] = String.valueOf(c);
}

// escapes (RFC2254)
FILTER_ESCAPE_TABLE['*'] = "\\2a";
FILTER_ESCAPE_TABLE['('] = "\\28";
FILTER_ESCAPE_TABLE[')'] = "\\29";
FILTER_ESCAPE_TABLE['\\'] = "\\5c";
FILTER_ESCAPE_TABLE[0] = "\\00";

}

/**
Expand All @@ -79,15 +72,8 @@ private LdapEncoder() {
}

protected static String toTwoCharHex(char c) {

String raw = Integer.toHexString(c).toUpperCase();

if (raw.length() > 1) {
return raw;
}
else {
return "0" + raw;
}
return (raw.length() > 1) ? raw : "0" + raw;
}

/**
Expand All @@ -96,29 +82,15 @@ protected static String toTwoCharHex(char c) {
* @return a properly escaped representation of the supplied value.
*/
static String filterEncode(String value) {

if (value == null) {
return null;
}

// make buffer roomy
StringBuilder encodedValue = new StringBuilder(value.length() * 2);

int length = value.length();

for (int i = 0; i < length; i++) {

char c = value.charAt(i);

if (c < FILTER_ESCAPE_TABLE.length) {
encodedValue.append(FILTER_ESCAPE_TABLE[c]);
}
else {
// default: add the char
encodedValue.append(c);
}
char ch = value.charAt(i);
encodedValue.append((ch < FILTER_ESCAPE_TABLE.length) ? FILTER_ESCAPE_TABLE[ch] : ch);
}

return encodedValue.toString();
}

Expand All @@ -141,43 +113,31 @@ static String filterEncode(String value) {
* @return The escaped value.
*/
static String nameEncode(String value) {

if (value == null) {
return null;
}

// make buffer roomy
StringBuilder encodedValue = new StringBuilder(value.length() * 2);

int length = value.length();
int last = length - 1;

for (int i = 0; i < length; i++) {

char c = value.charAt(i);

// space first or last
if (c == ' ' && (i == 0 || i == last)) {
encodedValue.append("\\ ");
continue;
}

// check in table for escapes
if (c < NAME_ESCAPE_TABLE.length) {
// check in table for escapes
String esc = NAME_ESCAPE_TABLE[c];

if (esc != null) {
encodedValue.append(esc);
continue;
}
}

// default: add the char
encodedValue.append(c);
}

return encodedValue.toString();

}

/**
Expand All @@ -188,43 +148,32 @@ static String nameEncode(String value) {
* @throws BadLdapGrammarException
*/
static String nameDecode(String value) throws BadLdapGrammarException {

if (value == null) {
return null;
}

// make buffer same size
StringBuilder decoded = new StringBuilder(value.length());

int i = 0;
while (i < value.length()) {
char currentChar = value.charAt(i);
if (currentChar == '\\') {
// Ending with a single backslash is not allowed
if (value.length() <= i + 1) {
// Ending with a single backslash is not allowed
throw new BadLdapGrammarException("Unexpected end of value " + "unterminated '\\'");
}
char nextChar = value.charAt(i + 1);
if (isNormalBackslashEscape(nextChar)) {
decoded.append(nextChar);
i += 2;
}
else {
char nextChar = value.charAt(i + 1);
if (nextChar == ',' || nextChar == '=' || nextChar == '+' || nextChar == '<' || nextChar == '>'
|| nextChar == '#' || nextChar == ';' || nextChar == '\\' || nextChar == '\"'
|| nextChar == ' ') {
// Normal backslash escape
decoded.append(nextChar);
i += 2;
}
else {
if (value.length() <= i + 2) {
throw new BadLdapGrammarException(
"Unexpected end of value " + "expected special or hex, found '" + nextChar + "'");
}
else {
// This should be a hex value
String hexString = "" + nextChar + value.charAt(i + 2);
decoded.append((char) Integer.parseInt(hexString, HEX));
i += 3;
}
if (value.length() <= i + 2) {
throw new BadLdapGrammarException(
"Unexpected end of value " + "expected special or hex, found '" + nextChar + "'");
}
// This should be a hex value
String hexString = "" + nextChar + value.charAt(i + 2);
decoded.append((char) Integer.parseInt(hexString, HEX));
i += 3;
}
}
else {
Expand All @@ -238,4 +187,9 @@ static String nameDecode(String value) throws BadLdapGrammarException {

}

private static boolean isNormalBackslashEscape(char nextChar) {
return nextChar == ',' || nextChar == '=' || nextChar == '+' || nextChar == '<' || nextChar == '>'
|| nextChar == '#' || nextChar == ';' || nextChar == '\\' || nextChar == '\"' || nextChar == ' ';
}

}
Loading

0 comments on commit 554ef62

Please sign in to comment.