import ballerina/http;
import ballerina/config;
import ballerina/log;
import ballerina/ldap;
ldap:LdapConnectionConfig ldapConfig = {
    domainName: "ballerina.io",
    connectionURL: "ldap://localhost:9095",
    connectionName: "uid=admin,ou=system",
    connectionPassword: "secret",
    userSearchBase: "ou=Users,dc=ballerina,dc=io",
    userEntryObjectClass: "identityPerson",
    userNameAttribute: "uid",
    userNameSearchFilter: "(&(objectClass=person)(uid=?))",
    userNameListFilter: "(objectClass=person)",
    groupSearchBase: ["ou=Groups,dc=ballerina,dc=io"],
    groupEntryObjectClass: "groupOfNames",
    groupNameAttribute: "cn",
    groupNameSearchFilter: "(&(objectClass=groupOfNames)(cn=?))",
    groupNameListFilter: "(objectClass=groupOfNames)",
    membershipAttribute: "member",
    userRolesCacheEnabled: true,
    connectionPoolingEnabled: false,
    connectionTimeoutInMillis: 5000,
    readTimeoutInMillis: 60000,
    retryAttempts: 3
};
ldap:InboundLdapAuthProvider ldapAuthProvider = new(ldapConfig, "ldap01");
http:BasicAuthHandler ldapAuthHandler = new(ldapAuthProvider);
listener http:Listener ep = new (9090, {
    auth: {
        authHandlers: [ldapAuthHandler]
    },
    secureSocket: {
        keyStore: {
            path: config:getAsString("b7a.home") +
                  "/bre/security/ballerinaKeystore.p12",
            password: "ballerina"
        }
    }
});service hello on ep {
    resource function sayHello(http:Caller caller, http:Request req) {
        error? result = caller->respond("Hello, World!!!");
        if (result is error) {
            log:printError("Error in responding to caller", result);
        }
    }
}# To run the service, execute the below command by passing the Ballerina home path
# as a system property.
ballerina run secured_service_with_ldap.bal --b7a.home=<ballerina_home_path>
[ballerina/http] started HTTPS/WSS listener 0.0.0.0:9090
curl -k -H "Authorization: Basic YWxpY2U6YWJjMTIz" \
https://localhost:9090/hello/sayHello
Hello, World!!!curl -k -u alice:abc123 https://localhost:9090/hello/sayHello
Hello, World!!!

Secured Service with LDAP

A service can be secured using LDAP and optionally by enforcing authorization. The LDAP auth provider verifies the token against the configured LDAP server. The result returned from the LDAP server is used for authentication and authorization.

import ballerina/http;
import ballerina/config;
import ballerina/log;
import ballerina/ldap;
ldap:LdapConnectionConfig ldapConfig = {
    domainName: "ballerina.io",
    connectionURL: "ldap://localhost:9095",
    connectionName: "uid=admin,ou=system",
    connectionPassword: "secret",
    userSearchBase: "ou=Users,dc=ballerina,dc=io",
    userEntryObjectClass: "identityPerson",
    userNameAttribute: "uid",
    userNameSearchFilter: "(&(objectClass=person)(uid=?))",
    userNameListFilter: "(objectClass=person)",
    groupSearchBase: ["ou=Groups,dc=ballerina,dc=io"],
    groupEntryObjectClass: "groupOfNames",
    groupNameAttribute: "cn",
    groupNameSearchFilter: "(&(objectClass=groupOfNames)(cn=?))",
    groupNameListFilter: "(objectClass=groupOfNames)",
    membershipAttribute: "member",
    userRolesCacheEnabled: true,
    connectionPoolingEnabled: false,
    connectionTimeoutInMillis: 5000,
    readTimeoutInMillis: 60000,
    retryAttempts: 3
};

Defines the LDAP connection configurations.

ldap:InboundLdapAuthProvider ldapAuthProvider = new(ldapConfig, "ldap01");

Creates an inbound LDAP authentication provider with the LDAP connection configurations.

http:BasicAuthHandler ldapAuthHandler = new(ldapAuthProvider);

Creates a Basic Auth handler with the created LDAP Auth provider.

listener http:Listener ep = new (9090, {
    auth: {
        authHandlers: [ldapAuthHandler]
    },

The endpoint used here is the http:Listener. The LDAP Auth handler is set to this endpoint using the authHandlers attribute. It is optional to override the authentication and authorization at the service and resource levels.

    secureSocket: {
        keyStore: {
            path: config:getAsString("b7a.home") +
                  "/bre/security/ballerinaKeystore.p12",
            password: "ballerina"
        }
    }
});

The secure hello world sample uses HTTPS.

service hello on ep {
    resource function sayHello(http:Caller caller, http:Request req) {
        error? result = caller->respond("Hello, World!!!");
        if (result is error) {
            log:printError("Error in responding to caller", result);
        }
    }
}
# To run the service, execute the below command by passing the Ballerina home path
# as a system property.
ballerina run secured_service_with_ldap.bal --b7a.home=<ballerina_home_path>
[ballerina/http] started HTTPS/WSS listener 0.0.0.0:9090
curl -k -H "Authorization: Basic YWxpY2U6YWJjMTIz" \
https://localhost:9090/hello/sayHello
Hello, World!!!

Start the LDAP server and invoke the service using cURL. It is required to provide the correct basic authentication header or <username>:<password> with the -u parameter and the cURL command. It will get validated against the LDAP server.

curl -k -u alice:abc123 https://localhost:9090/hello/sayHello
Hello, World!!!