[Wildfly 13] Writing an Elytron SecurityRealm handling SASL mechanisms like DIGEST-MD5 or SCRAM-SHA1
nephri Jul 14, 2018 11:31 AMHi,
I'm wrote a SecurityRealm that handle authentication like this:
public class TestRealm implements SecurityRealm {
public SupportLevel getCredentialAcquireSupport(Class<? extends Credential> type, String algorithm, AlgorithmParameterSpec spec) throws RealmUnavailableException {
return SupportLevel.UNSUPPORTED;
}
public SupportLevel getEvidenceVerifySupport(Class<? extends Evidence> type, String algorithm) throws RealmUnavailableException {
if( !type.isAssignableFrom( PasswordGuessEvidence.class ) ) return SupportLevel.UNSUPPORTED;
return SupportLevel.SUPPORTED;
}
public RealmIdentity getRealmIdentity(Principal principal) throws RealmUnavailableException {
return new TestRealmIdentity( principal );
}
private static class TestRealmIdentity implements RealmIdentity {
private Principal principal = null;
public TestRealmIdentity( Principal p ) {
this.principal = p;
}
public Principal getRealmIdentityPrincipal() {
return this.principal;
}
public boolean exists() throws RealmUnavailableException {
if( this.principal == null ) return false;
if( this.principal.getName() == null ) return false;
return getExpectedSha1Password( this.principal ) != null;
}
public SupportLevel getCredentialAcquireSupport(Class<? extends Credential> type, String algorithm, AlgorithmParameterSpec spec) throws RealmUnavailableException {
return SupportLevel.UNSUPPORTED;
}
public SupportLevel getEvidenceVerifySupport(Class<? extends Evidence> type, String algorithm) throws RealmUnavailableException {
if( !type.isAssignableFrom( PasswordGuessEvidence.class ) ) return SupportLevel.UNSUPPORTED;
return SupportLevel.SUPPORTED;
}
public <C extends Credential> C getCredential(Class<C> type) throws RealmUnavailableException {
return null;
}
public boolean verifyEvidence(Evidence evidence) throws RealmUnavailableException {
Principal p = this.principal;
byte[] expectedSha1Password = getExpectedSha1Password(p);
System.out.println("Verify Password for " + ( p == null ? "null" : p.getName() ) );
if( expectedSha1Password == null ) {
if( evidence instanceof PasswordGuessEvidence ) ((PasswordGuessEvidence)evidence).destroy();
return false;
}
if (evidence instanceof PasswordGuessEvidence) {
PasswordGuessEvidence guess = (PasswordGuessEvidence) evidence;
byte[] sha1 = null;
try {
sha1 = sha1( guess.getGuess() );
boolean result = Arrays.equals( expectedSha1Password , sha1 );
if( !result ) {
System.err.println("Password rejected for [" + p.getName() + "]");
}
return result;
}
finally {
guess.destroy();
if( sha1 != null ) Arrays.fill( sha1 , (byte) 0);
}
}
return false;
}
private String getExpectedSha1Password( Principal p ) {
// IMPL
}
private byte[] sha1( byte[] plain ) {
// IMPL
}
}
}
It works fine if we use the mechanism PLAIN.
But when i try to use DIGEST-MD5, the authentication fails.
I'm think i'm missing implementations about Credential acquire methods but i didn't really understand concepts in Credential and Evidence objetcs and Acquire vs Verify processes !
Can you clarify the situation and providing a way to support theses SASL mechanism ?
Thanks in advance,
Best Regards,
Sébastien.