I am using Apache CXF with Quarkus to implement receiving a WSS UsernameToken in a SOAP request. The password is plain text.
I would like to use the elytron-security Quarkus extension to authenticate the UsernameToken against LDAP.
My CXF endpoint looks as follows:
@Produces
@Named
CxfEndpoint cxfBeanClient() {
final CxfEndpoint cxfEndpoint = new CxfEndpoint();
cxfEndpoint.setDataFormat(DataFormat.CXF_MESSAGE);
cxfEndpoint.setWsdlURL("wsdl/Service123.wsdl");
cxfEndpoint.setAddress("/MyService");
Map<String, Object> endpointProperties = new HashMap<>();
endpointProperties.put(SecurityConstants.USERNAME_TOKEN_VALIDATOR, new UsernameTokenLDAPValidator());
cxfEndpoint.setProperties(endpointProperties);
Map<String, Object> securityProperties = new HashMap<>();
securityProperties.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
securityProperties.put(WSHandlerConstants.PASSWORD_TYPE, "PasswordText");
WSS4JInInterceptor wss4jInInterceptor = new WSS4JInInterceptor(securityProperties);
cxfEndpoint.getInInterceptors().add(wss4jInInterceptor);
return cxfEndpoint;
}
and my UsernameTokenLDAPValidator looks like this :
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.dom.handler.RequestData;
import org.apache.wss4j.dom.message.token.UsernameToken;
import org.apache.wss4j.dom.validate.UsernameTokenValidator;
public class UsernameTokenLDAPValidator extends UsernameTokenValidator {
@Override
protected void verifyPlaintextPassword(UsernameToken usernameToken, RequestData data) throws WSSecurityException {
String userName = usernameToken.getName();
String password = usernameToken.getPassword();
// authenticate with LDAP here
}
}
So the incoming request (with the SOAP WS security header) gets routed to UsernameTokenLDAPValidator, and the userName and password can be extracted from the usernameToken. So far so good.
The challenge is how to authenticate the user against LDAP. I got it working by creating an LdapContext which I can use to search/query the LDAP server :
Hashtable environment = new Hashtable();
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
environment.put(Context.PROVIDER_URL, ...);
environment.put(Context.SECURITY_PRINCIPAL, ...);
environment.put(Context.SECURITY_CREDENTIALS, ...);
LdapContext context = new InitialLdapContext(environment, null);
etc....
This works, but I don’t like the manual configuration. I would rather use the elytron-security Quarkus extension, this is recommended by Quarkus at https://quarkus.io/guides/security-ldap. I want to configure the LDAP connection as explained on that page, and then somehow get hold of an LDAP context bean or object in my UsernameTokenLDAPValidator class, which I can then use to query the LDAP server.
Unfortunately, the instructions on that page don’t really explain how to do this in Java. So I’m wondering if it is possible at all. Can anyone shed some light on this? Thanks in advance for any pointers or tips.
coder5749 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.