-
Notifications
You must be signed in to change notification settings - Fork 614
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue/1840 : Fix for Improve password encoding support for LDAP
- Loading branch information
1 parent
d7c62a1
commit 95eaf18
Showing
7 changed files
with
179 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
.../main/java/org/carlspring/strongbox/configuration/StrongboxDelegatingPasswordEncoder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package org.carlspring.strongbox.configuration; | ||
|
||
import javax.annotation.PostConstruct; | ||
|
||
import org.springframework.security.crypto.factory.PasswordEncoderFactories; | ||
import org.springframework.security.crypto.password.PasswordEncoder; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.util.Base64Utils; | ||
|
||
/** | ||
* This class encodes given raw String or Base64 encoded string. | ||
* If given string is Base64 Encoded it will attempt to decode the password and finally delegate it to the password encoder. | ||
* | ||
* @author mbharti | ||
* @date 07/10/20 | ||
*/ | ||
@Component | ||
public class StrongboxDelegatingPasswordEncoder | ||
implements PasswordEncoder | ||
{ | ||
|
||
private PasswordEncoder passwordEncoder; | ||
|
||
@PostConstruct | ||
private void init() | ||
{ | ||
passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); | ||
} | ||
|
||
/** | ||
* This Encodes the raw password. In case given rawCharSequence is Base64 encoded, | ||
* then it will decode and then encode the decoded string. | ||
* | ||
* @param rawCharSequence Raw String or Base64 encoded String | ||
* @return Encoded String | ||
*/ | ||
@Override | ||
public String encode(CharSequence rawCharSequence) | ||
{ | ||
return passwordEncoder.encode(getDecodedString(rawCharSequence)); | ||
} | ||
|
||
/** | ||
* Verify the encoded password obtained from storage matches the submitted raw password after it too is encoded. | ||
* Returns true if the passwords match, false if they do not. The stored password itself is never decoded. | ||
* In case given rawCharSequence is Base64 encoded, then it decode it first then verifies. | ||
* | ||
* @param rawCharSequence Raw String or Base64 encoded String | ||
* @param encodedString Encoded String | ||
* @return true if the passwords match | ||
* false if the password do not match | ||
*/ | ||
@Override | ||
public boolean matches(CharSequence rawCharSequence, | ||
String encodedString) | ||
{ | ||
return passwordEncoder.matches(getDecodedString(rawCharSequence), encodedString); | ||
} | ||
|
||
private String getDecodedString(CharSequence rawCharSequence) | ||
{ | ||
if (rawCharSequence == null) | ||
{ | ||
return null; | ||
} | ||
|
||
String rawString = rawCharSequence.toString(); | ||
|
||
try | ||
{ | ||
//May throw IllegalArgumentException if raw string contains invalid Base64 characters | ||
String base64DecodedString = new String(Base64Utils.decodeFromString(rawString)); | ||
|
||
String base64EncodedString = Base64Utils.encodeToString(base64DecodedString.getBytes()); | ||
|
||
if (rawString.equals(base64EncodedString)) | ||
{ | ||
return base64DecodedString; | ||
} | ||
} | ||
catch (IllegalArgumentException e) | ||
{ | ||
return rawString; | ||
} | ||
|
||
return rawString; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
...t/java/org/carlspring/strongbox/configuration/StrongboxDelegatingPasswordEncoderTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package org.carlspring.strongbox.configuration; | ||
|
||
import javax.inject.Inject; | ||
|
||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.context.annotation.ComponentScan; | ||
import org.springframework.security.crypto.password.PasswordEncoder; | ||
import org.springframework.test.context.ActiveProfiles; | ||
import org.springframework.test.context.ContextConfiguration; | ||
import org.springframework.util.Base64Utils; | ||
|
||
|
||
@SpringBootTest | ||
@ActiveProfiles(profiles = "test") | ||
@ContextConfiguration | ||
class StrongboxDelegatingPasswordEncoderTest | ||
{ | ||
|
||
@org.springframework.context.annotation.Configuration | ||
@ComponentScan(basePackages = { "org.carlspring.strongbox.security", | ||
"org.carlspring.strongbox.testing", | ||
"org.carlspring.strongbox.configuration" }) | ||
public static class SpringConfig | ||
{ | ||
|
||
} | ||
|
||
|
||
@Inject | ||
private PasswordEncoder passwordEncoder; | ||
|
||
@Test | ||
void testNullEncodeAndMatch() | ||
{ | ||
Assertions.assertThrows(NullPointerException.class, () -> passwordEncoder.encode(null)); | ||
Assertions.assertTrue(passwordEncoder.matches(null, null)); | ||
} | ||
|
||
@Test | ||
void encodeAndMatch() | ||
{ | ||
String text = "password12"; | ||
String base64EncodedString = Base64Utils.encodeToString(text.getBytes()); | ||
|
||
String normalEncode = passwordEncoder.encode(text); | ||
String base64Encode = passwordEncoder.encode(base64EncodedString); | ||
|
||
Assertions.assertTrue(passwordEncoder.matches(text, normalEncode)); | ||
Assertions.assertTrue(passwordEncoder.matches(text, base64Encode)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters