// TODO - Once authorization is in place we may be able to relax the realm check to
// allow anonymous along side fully authenticated connections.
// If the mechanism is ANONYMOUS and we don't have a realm we return quickly.
if (ANONYMOUS.equals(mechanismName) && realm == null) {
return new CallbackHandler() {
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (Callback current : callbacks) {
throw new UnsupportedCallbackException(current, "ANONYMOUS mechanism so not expecting a callback");
}
}
};
}
// For now for the JBOSS_LOCAL_USER we are only supporting the $local user and not allowing for
// an alternative authorizationID.
if (JBOSS_LOCAL_USER.equals(mechanismName)) {
return new CallbackHandler() {
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (Callback current : callbacks) {
if (current instanceof NameCallback) {
NameCallback ncb = (NameCallback) current;
if (DOLLAR_LOCAL.equals(ncb.getDefaultName()) == false) {
throw new SaslException("Only " + DOLLAR_LOCAL + " user is acceptable.");
}
} else if (current instanceof AuthorizeCallback) {
AuthorizeCallback acb = (AuthorizeCallback) current;
acb.setAuthorized(acb.getAuthenticationID().equals(acb.getAuthorizationID()));
} else {
throw new UnsupportedCallbackException(current);
}
}
}
};
}
// In this calls only the AuthorizeCallback is needed, we are not making use if an authorization ID just yet
// so don't need to be linked back to the realms.
if (EXTERNAL.equals(mechanismName)) {
return new CallbackHandler() {
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (Callback current : callbacks) {
if (current instanceof AuthorizeCallback) {
AuthorizeCallback acb = (AuthorizeCallback) current;
acb.setAuthorized(acb.getAuthenticationID().equals(acb.getAuthorizationID()));
} else {
throw new UnsupportedCallbackException(current);
}
}
}
};
}
final CallbackHandler realmCallbackHandler; // Referenced later by an inner-class so needs to be final.
// We must have a match in this block or throw an IllegalStateException.
if (DIGEST_MD5.equals(mechanismName) && digestMd5Supported() ||
PLAIN.equals(mechanismName) && plainSupported()) {
realmCallbackHandler = realm.getCallbackHandler();
} else {
return null;
}
// If there is not serverCallbackHandler then we don't need to wrap it so we can just return the realm
// name fix handler which is already wrapping the real handler.
if (serverCallbackHandler == null) {
return realmCallbackHandler;
}
return new CallbackHandler() {
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
serverCallbackHandler.handle(callbacks);
if (handled(callbacks) == false) {
realmCallbackHandler.handle(callbacks);
}
}
/*
* Check if the PasswordCallback had already been handled.