This repo shows a sample of how to use the External Callout policy with LDAP for Apigee X/hybrid.
The external callout service implements two actions:
- Authenticate username and password
Accepts a username/password combination, tests the credentials against the configured LDAP and a flow variable ldap-result
with the bool true
or false
. The message template is:
{"ldapAuthRequest": {"username":"billy","password":"test"}}
Optional parameters include: scope
(oneOf object, onelevel or subtree), baseDN
(default = dc=example,dc=org) and objectClass
(default = inetOrgPerson).
- Search entity
Accepts a query and attributes, searches against the configured LDAP and returns the entities as well as a flow variable ldap-search-result
with the count of entities. The message template is:
{"ldapSearchRequest": {"query":"uid=billy","attributes":["dn"]}}
Optional parameters include scope
(oneOf object, onelevel or subtree) and baseDN
(default = dc=example,dc=org).
OpenLDAP can be started locally on docker.
docker build -t openldap -f Dockerfile.ldap .
docker run --rm -p 389:389 -p 636:636 openldap
Start the External callout service
go run cmd/server/main.go --host=ldap://localhost:389 --binduser="cn=readonly,dc=example,dc=org" --bindpasswd=passwr0rd!
Start a REST External callout client
go run cmd/client/main.go
Test the configuration (Successful Message)
curl localhost:8080/processmessage -H "Content-Type: application/json" -d '{"ldapAuthRequest": {"username":"billy","password":"test"}}'
{"response":{},"additionalFlowVariables":{"ldap-result":{"bool":true}}}
Test the configuration (Invalid Message)
curl localhost:8080/processmessage -H "Content-Type: application/json" -d '{"ldapAuthRequest": {"username":"billy","password":"test123"}}'
{"response":{"content":"{\"status_code\":500,\"message\":\"LDAP Result Code 49 \\\"Invalid Credentials\\\": \"}"},"additionalFlowVariables":{"ldap-result":{"bool":false}}}
Test Search (Successful Message)
curl localhost:8080/processmessage -H "Content-Type: application/json" -d '{"ldapSearchRequest": {"query":"uid=billy","attributes":["dn"]}}'
{"response":{"content":"{\"Entries\":[{\"DN\":\"uid=billy,dc=example,dc=org\",\"Attributes\":null}],\"Referrals\":[],\"Controls\":[]}"},"additionalFlowVariables":{"ldap-search-count":{"int32":1}}}
Test Search (Unsuccessful Search)
curl localhost:8080/processmessage -H "Content-Type: application/json" -d '{"ldapSearchRequest": {"query":"uid=bill","attributes":["dn"]}}'
{"response":{"content":"{\"Entries\":[],\"Referrals\":[],\"Controls\":[]}"},"additionalFlowVariables":{"ldap-search-count":{"int32":0}}}
- Build and deploy the External callout service
skaffold run -p gcb --default-repo=gcr.io/xxx -f skaffold-apigee-ldap.yaml
-
Deploy the API Proxy included here
-
Create the target server
auth="Authorization: Bearer $(gcloud auth print-access-token)"
curl "https://apigee.googleapis.com/v1/organizations/$ORG/environments/$ENV/targetservers" -X POST -H $auth -H "Content-Type: application/json" --data-raw '{
"name": "ldap-server",
"host": "HOSTNAME",
"port": 50051,
"isEnabled": true,
"protocol": "GRPC",
"sSLInfo": {
"enabled": false
}
}'
4. To test the setup (invalid creds),
```sh
curl https://api.acme.com/ldap -u test:test -v
...
< HTTP/2 403
< content-length: 115
< date: Thu, 24 Jun 2021 19:28:31 GMT
< server: istio-envoy
<
{
"error":"authentication_error",
"error_description": "username or password did not match"
}
- To test the setup (valid creds),
curl https://api.acme.com/ldap -u billy:test -v
...
< via: 1.1 google
< alt-svc: clear
< server: istio-envoy
<
Hello, Guest!
This is not an officially supported Google product