Skip to content

Commit

Permalink
Issue/1840 : Fix for Improve password encoding support for LDAP
Browse files Browse the repository at this point in the history
  • Loading branch information
madhukarbharti committed Nov 4, 2020
1 parent cc4c8d3 commit 22a5d88
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package org.carlspring.strongbox.authentication.api.ldap;

import java.util.Base64;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.codec.Hex;
import org.springframework.security.crypto.codec.Utf8;
import org.springframework.security.ldap.userdetails.LdapUserDetailsMapper;

/**
* @author mbharti
* @date 19/10/20
*/
public class CustomLdapUserDetailsMapper
extends LdapUserDetailsMapper
{

private static final String PREFIX = "{";

private static final String SUFFIX = "}";

private boolean isBase64EncodedPassword;

private static final Logger logger = LoggerFactory.getLogger(CustomLdapUserDetailsMapper.class);

protected String mapPassword(Object passwordValue)
{
String passwordValueString;

if (!(passwordValue instanceof String))
{
passwordValueString = new String((byte[]) passwordValue);
}
else
{
passwordValueString = (String) passwordValue;
}

if (!isBase64EncodedPassword())
{
return passwordValueString;
}

return decodeBase64EncodedPassword(passwordValueString);
}

private String decodeBase64EncodedPassword(String prefixEncodedPasswordString)
{

try
{
String algorithmUsed = extractId(prefixEncodedPasswordString);

String base64DecodedPasswordAfterAlgorithm;

String extractBase64EncodedHash = prefixEncodedPasswordString;

if (StringUtils.isNotEmpty(algorithmUsed))
{
extractBase64EncodedHash = extractEncodedPassword(prefixEncodedPasswordString);

base64DecodedPasswordAfterAlgorithm =
PREFIX + algorithmUsed + SUFFIX + decodeBase64EncodedHashWithHex(extractBase64EncodedHash);
}
else
{
base64DecodedPasswordAfterAlgorithm = new String(
java.util.Base64.getDecoder().decode(Utf8.encode(extractBase64EncodedHash)));
}

return base64DecodedPasswordAfterAlgorithm;
}
catch (Exception e)
{
logger.warn("Failed to match password after decoding base64encoded hash after algorithm");
return prefixEncodedPasswordString;
}
}

private String decodeBase64EncodedHashWithHex(String base64EncodedHash)
{
try
{
return new String(Hex.encode(Base64.getDecoder().decode(Utf8.encode(base64EncodedHash))));
}
catch (Exception ex)
{
logger.warn("Failed to do Base64Decoding " + ex.getMessage());
}

return base64EncodedHash;
}

private String extractEncodedPassword(String prefixEncodedPassword)
{
int start = prefixEncodedPassword.indexOf(SUFFIX);

return prefixEncodedPassword.substring(start + 1);
}

private String extractId(String prefixEncodedPassword)
{
int start = prefixEncodedPassword.indexOf(PREFIX);

if (start != 0)
{
return StringUtils.EMPTY;
}

int end = prefixEncodedPassword.indexOf(SUFFIX, start);

if (end < 0)
{
return StringUtils.EMPTY;
}

return prefixEncodedPassword.substring(start + 1, end);
}

public boolean isBase64EncodedPassword()
{
return isBase64EncodedPassword;
}

public void setBase64EncodedPassword(boolean base64EncodedPassword)
{
isBase64EncodedPassword = base64EncodedPassword;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ public void testConfiguration(String username,

LdapUserDetailsService luds = (LdapUserDetailsService) c.getBean("ldapUserDetailsService");

luds.setUserDetailsMapper(new CustomLdapUserDetailsMapper());

UserDetails user = luds.loadUserByUsername(username);
if (!passwordEncoder.matches(password, user.getPassword()))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,9 @@
</constructor-arg>
<constructor-arg ref="ldapAuthoritiesPopulator"/>
</bean>

<bean id="customUserDetailsMapper" class="org.carlspring.strongbox.authentication.api.ldap.CustomLdapUserDetailsMapper">
<property name="base64EncodedPassword" value="true"/>
</bean>

</beans>
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ strongbox.authentication.ldap.authorities.convertToUpperCase=false
strongbox.authentication.ldap.authorities.groupRoleAttribute=cn
strongbox.authentication.ldap.authorities.rolePrefix=
strongbox.authentication.ldap.authorities.searchSubtree=true
strongbox.authentication.ldap.base64EncodedPassword=true
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public class BootProgressBeanPostProcessor
{ "npmLayoutProvider", "Loading NPM layout provider.." },
{ "rawLayoutProvider", "Loading Raw layout provider.." },
{ "transactionManager", "Loading transaction manager..." },
{ org.carlspring.strongbox.config.SecurityConfig.class.getName(), "Loading security configuration..." },
{ org.carlspring.strongbox.config.WebSecurityConfig.class.getName(), "Loading security configuration..." },
{ org.carlspring.strongbox.config.SwaggerConfig.class.getName(), "Loading documentation..." },
{ "fallback", "Waiting for services to go live..."},
}).collect(Collectors.toMap(p -> p[0], p -> p[1]));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
EventsConfig.class,
StorageCoreConfig.class,
UsersConfig.class,
SecurityConfig.class,
WebSecurityConfig.class,
ClientConfig.class,
CronTasksConfig.class,
SwaggerConfig.class })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
AuthenticationConfig.class})
@Configuration
@EnableWebSecurity
public class SecurityConfig
public class WebSecurityConfig
extends WebSecurityConfigurerAdapter
{

Expand Down

0 comments on commit 22a5d88

Please sign in to comment.