Authorization

Ampool supports authorization to control access to data by authenticated user. The admin can control access to a table data depending on the identity of the user attempting the operation.

Sentry Authorization

Apache Sentry is a centralized store of authorization data and enforce fine grain role based authorization to data stored in data storage system such as Ampool ADS.

Setting up sentry authorization

There are two parts to setting up sentry authorization with Ampool
- Sentry server should be able to store Ampool authorization permissions.
- Ampool processes have to be configured to talk to Sentry for authorization decisions.

Setting up the sentry server

  • To allow Ampool to connect to sentry and retrieve authorization data make sure that the property sentry.service.allow.connect has the ampool user included in the list in sentry-site.xml.
  <property>
    <name>sentry.service.allow.connect</name>
    <value>hive,impala,hue,hdfs,solr,...,ampool_user</value>
  </property>
  • Add the class name of Ampool action factory in sentry-site-xml
  <property>
    <name>sentry.ampool.action.factory</name> 
    <value>io.ampool.security.sentry.model.AmpoolSentryActionFactory</value>
  </property>
  • Copy ampool-security-.jar from your ampool node:$AMPOOL_HOME/lib-security/ to $SENTRY_HOME/lib/plugins/
  • Restart sentry service.

Enabling Sentry authorization in Ampool

The following properties have to be passed to Ampool services(locators and servers) while starting in the file specified as security-properties-file:

security-manager=io.ampool.security.AmpoolSecurityManager
security-client-auth-init=io.ampool.security.AmpoolAuthInitClient.create
security-enable-sentry-authz=true
security-ampool-sentry-kerberos-principal=ampool_user@KRB_REALM
security-ampool-sentry-kerberos-keytab=/home/ampool/sentry-client/ampool_user.keytab
security-authz-sentry-site=/home/ampool/sentry-client/sentry-site.xml

Note

security-ampool-sentry-kerberos-principal and security-ampool-sentry-kerberos-keytab can be skipped of sentry.service.security.mode is not kerberos in sentry-site.xml.
One of the authentication mechanisms also needs to be enabled for Ampool to establish an identity to be authorized.

Description of properties

Property Details Defaults
security-manager Security manager to be used None
security-client-auth-init Security manager authentication client side initializer None
security-enable-sentry-authz Enable sentry authorization false
security-ampool-sentry-kerberos-principal Kerberos principal to be used while connecting to sentry server None
security-ampool-sentry-kerberos-keytab Keytab file for the kerberos principal None
security-authz-sentry-site Path to sentry-site.xml None
security-authz-sentry-disable-caching Disable Caching of privileges in ampool processes false
security-authz-sentry-cache-expiration-time Time in seconds for which a cached privilege is valid. A value of 0 will never expire the cache. 3600
(1 hour)
security-authz-sentry-client-retries Number of attempts the Ampool services will make to refresh the privilege cache before returning an error 3

sentry-site.xml should minimally have these properties defined to enable Ampool to connect to sentry.

<configuration>
  <property>
    <name>sentry.service.client.server.rpc-address</name>
    <value>__address_of_sentry_server__</value>
  </property>
  <property>
    <name>sentry.service.client.server.rpc-port</name>
    <value>__sentry_server's_rpc_port__</value>
  </property>
  <property>
    <name>sentry.service.server.principal</name>
    <value>__sentry_server's_service_principal__</value>
  </property>
  <property>
    <name>sentry.service.security.mode</name>
    <value>kerberos</value>
  </property>
</configuration>

Note

sentry.service.server.principal can be ignored of sentry.service.security.mode is not kerberos.

Modifying authorization data stored on sentry server.

Sentry uses roles based authorization i.e permissions are granted to roles instead of groups or users. Roles are assigned to groups which in turn have one or more users. You can alter the authorization data i.e can grant or revoke access to Ampool objects using mash. Similar to locators and servers you will need a security-properties-file with the following properties to let the CLI talk to sentry server.

security-enable-sentry-authz=true
security-manager=io.ampool.security.AmpoolSecurityManager
security-ampool-sentry-kerberos-principal=ampool_admin@KRB_REALM
security-ampool-sentry-kerberos-keytab=/home/ampool/sentry-client/ampool_admin.keytab
security-authz-sentry-site=/home/ampool/sentry-client/sentry-site.xml

this property file can be passed to mash as a global param using the -g option

mash -g "security-properties-file=<path of the security properties file>"

or can be set as a environment variable in mash

mash>set variable --name=security-properties-file --value=<path to the security properties file>

This file can also be specified as a arg to the individual CLIs for e.g.

mash>create role --role-name=test --security-properties-file=<path to security properties file>

The CLI will internally check in the following order for the file path
1. Args to command
2. mash environment variable
3. Global param to mash

command will fail if the security-properties-file args is not specified in at least one of the ways. Following examples show how mash can be used to manage roles and privileges in sentry.

Creating and listing roles

$  ./geode-assembly/build/install/ampool/bin/mash -g "security-properties-file=/home/ampool/sentry-client/client.props"
    ______________________________     __
   / _    _   / _____  / ______/ /____/ /
  / / /  / / / /____/ /_____  / _____  / 
 / / /__/ / /  ____  /_____/ / /    / /  
/_/      /_/_/    /_/_______/_/    /_/    1.5.0

Memory Analytics Shell:To Monitor and manage Ampool

mash>create role --role-name=testRole
Role create successfully: testRole

mash>list roles
Roles
--------------------
testrole

Granting roles to groups

mash>grant role --role-name=testRole --groups=admin,root
Role granted successfully: testRole

mash>list roles --group=root
Roles
--------
testrole

mash>list roles --group=admin
Roles
--------
testrole

mash>

Granting privileges to roles

mash>grant privilege --role-name=testRole --privilege=DATA:READ
Privilege granted successfully: testRole
mash>list privileges --role-name=testRole
Privileges
----------
DATA:READ

Revoking privileges from roles

mash>revoke privilege --role-name=testRole --privilege=DATA:READ
Privilege revoked successfully: testRole

mash>list privileges --role-name=testRole

mash>

Revoking roles from groups

mash>revoke role --role-name=testRole --groups=admin
Role revoked successfully: testRole

mash>list roles --group=admin

mash>list roles --group=root
Roles
--------
testrole

LDAP Authorization

One can configure Ampool ADS to leverage an LDAP server for user authorization. In this use case, the LDAP server creates and manages users, and no information about users is stored on Ampool. Group/role information is managed both on the LDAP server and on Ampool. Following table lists the location of information in case of LDAP authorization:

Information Management and storage
User names and passwords LDAP database
Group names and group members LDAP database
Group to Role mapping Ampool as a security repository
Roles and permissions Ampool as a security repository

Configuration for LDAP role based authorization.

User must use the following security configuration properties to use LDAP authorization.

Option Description Required
security-enable-ldap-authz Flag to enable LDAP authorization. Yes
security-ldap-server LDAP server to connect to Yes
security-ldap-search-base The DN relative to the LDAP base DN to query for user records (e.g. ou=group or ou=user). Yes
security-ldap-usessl Set to true if require secure connection. No
security-ldap-bind-dn User DN to be used for LDAP binding Yes
security-ldap-bind-password Bind user password information. If not specified empty password will be used in bind. No
security-ldap-group-search-filter Filter used to search group information stored. Yes
security-ldap-group-role-mapping JSON string to specify mapping between LDAP groups and your application roles. Yes
security-ldap-user-group-attribute In case group information is stored in user attribute one need to use this property. Default, memberOf
security-ldap-authz-repository-class Security repository class to fetch roles to permission mapping. No
security-authz-ldap-disable-caching Disable Caching of authorization-info (user -> groups) in ampool processes Default is false
security-ldap-cache-timeout Time in seconds for which a cached authorization-info (user -> groups) is valid. A value of 0 will never expire the cache. Default is 3600
(1 hour)

The LDAP Authorization flow

  • A client connects to Ampool ADS and performs authentication with any supported authentication mechanism. ADS binds to to the LDAP server specified with “security-ldap-server” using the credentials specified with “security-ldap-bind-dn” and “security-ldap-bind-password”.

  • ADS constructs an LDAP query using the “security-ldap-group-search-filter” and queries the LDAP server for the authenticated user’s group membership. The LDAP server evaluates the query and returns the list of groups to which the authenticated user belongs.

  • ADS authorizes the user to perform actions on the server by mapping each returned group’s Distinguished Name (DN) to a role. Group to role mapping is specified in “security-ldap-group-role-mapping”. If a returned group DN has an entry in “security-ldap-group-role-mapping” with a corresponding role specified, ADS grants the user the associated role and privileges assigned to that role. See ADS Roles for LDAP Authorization for more information.

  • The client can perform actions on the ADS server which require the roles or privileges granted to the authenticated user.

Default Role to Permissions mapping (role-permission.json).

  • Default role to permission mapping can be specified in role-permission.json, Though user can plug-in custom mechanism by implementing SecurityRepository interface.

  • Sample example showing how user can provide JSON document containing roles and corresponding permissions. While starting the server user needs to provide a classpath containing location of this file.

{
 "roles": [{
 "name": "admin",
 "operationsAllowed": [
 "CLUSTER:MANAGE",
 "CLUSTER:WRITE",
 "CLUSTER:READ",
 "DATA:MANAGE",
 "DATA:WRITE",
 "DATA:READ"
 ]
 },
 {
 "name": "guest",
 "operationsAllowed": [
 "DATA:READ",
 "CLUSTER:READ"
 ]
 },
 {
 "name": "user",
 "operationsAllowed": [
 "DATA:READ",
 "DATA:WRITE"
 ]
 },
 {
 "name": "enterprise_admins",
 "operationsAllowed": [
 "CLUSTER:MANAGE",
 "CLUSTER:WRITE",
 "CLUSTER:READ",
 "DATA:MANAGE",
 "DATA:WRITE",
 "DATA:READ"
 ]
 },
 {
 "name": "group_policy_owners_R",
 "operationsAllowed": [
 "CLUSTER:READ",
 "DATA:READ"
 ]
 },
 {
 "name": "schema_admins_W",
 "operationsAllowed": [
 "CLUSTER:WRITE",
 "DATA:WRITE"
 ]
 },
 {
 "name": "domain_admins_M",
 "operationsAllowed": [
 "CLUSTER:MANAGE",
 "DATA:MANAGE"
 ]
 }
 ]
}

Plug-in your own security repository module.

User can plug-in their own system having Roles to permissions mapping (DBs, or any external security systems) into the ADS LDAP authorization framework using the following property. security-ldap-authz-repository-class=. Kindly note CUSTOM_REPOSITORY_CLASS, has to implement following interface.

public interface SecurityRepository {

 /**
 * Initialize the security repository
 * @param securityProperties
 * @throws NotAuthorizedException
 */
 void init(final Properties securityProperties) throws NotAuthorizedException;

 /**
 * Populate the role instance for the given role name
 * @param roleName
 * @return
 */
 Role getRole(String roleName);

 /**
 * close the resources for security-repository
 */
 default void close() {}
}

Demo Tutorials.

1. Authorize Users Using OpenLdap or apache directory service.

Introduction.

  • Demonstrate a use-case where group membership information is stored as a group attribute “member”.

  • Ampool ADS provides support for proxying user authorization requests to a specified LDAP service such as OpenLdap or apache directory services.

  • This tutorial describes how to configure Ampool ADS to perform authorization through an openLdap server via LDAPAuthorizer. Though user can enable its own choice of authentication mechanism, for simplicity a very simple authentication mechasim (SimpleTestAuthenticator) is used in this tutorial.

  • Locator authorize a cluster join request from server using LDAP authorization.

  • Locator authorize requests from Mash and server authorizes request from the java clients.

  • Membership information is stored as a "member" attribute of "group" object type. Authorization is based on userDN of the authenticated user.

Example OpenLdap or Apache Directory Schema

This tutorial uses the following example objects as the basis for the provided queries, configurations, and output. Each object shows only a subset of the possible attribute

User Objects

dn: uid=super-user,ou=users,dc=example,dc=com
objectClass: top
objectClass: inetOrgPerson
objectClass: person
objectClass: organizationalPerson
cn: super user
sn: super
uid: super-user
userPassword:: e1NTSEF9eE4yUUh2cnZ5UE9ma1NNYTl5NGhSb20xQUthWThxRVFOYk5oNGc9PQ==

dn: uid=guest-user,ou=users,dc=example,dc=com
objectClass: top
objectClass: inetOrgPerson
objectClass: person
objectClass: organizationalPerson
cn: guest user
sn: guest
uid: guest-user
userPassword:: e1NTSEF9M2FQd3lBUW91L2ZmYVNwSkp5ZCsvUjBReXdkTzdQcllHUlJJVVE9PQ==

dn: uid=system-user,ou=users,dc=example,dc=com
objectClass: top
objectClass: inetOrgPerson
objectClass: person
objectClass: organizationalPerson
cn: system user
sn: system
uid: system-user
userPassword:: e1NTSEF9Sk81THV5cFpJTmk0aHZNYlJtT3hxYkd2Z3k2TTJrb21vWE0yWnc9PQ==

dn: uid=nhpatel,ou=users,dc=example,dc=com
objectClass: top
objectClass: inetOrgPerson
objectClass: person
objectClass: organizationalPerson
cn: ****** *****
sn: Patel
mail: nil****.****@gmail.com
telephoneNumber: 98***14****
uid: nhpatel
userPassword:: e1NTSEF9Wnd5anloV0JSWGFEOXNIdTVBaDFqSTNFRTZ6UEZsWHh2VEJmY0E9PQ==

Group Objects.

dn: cn=admin,ou=groups,dc=example,dc=com
objectClass: top
objectClass: groupOfNames
cn: admin
member: cn=Hugo Williams,ou=users,dc=example,dc=com
member: cn=John Keats,ou=users,dc=example,dc=com
member: uid=nhpatel,ou=users,dc=example,dc=com
member: uid=super-user,ou=users,dc=example,dc=com

dn: cn=user,ou=groups,dc=example,dc=com
objectClass: top
objectClass: groupOfNames
cn: user
member: cn=Hugo Williams,ou=users,dc=example,dc=com
member: cn=John Keats,ou=users,dc=example,dc=com
member: cn=John Milton,ou=users,dc=example,dc=com
member: cn=Robert Browning,ou=users,dc=example,dc=com
member: uid=system-user,ou=users,dc=example,dc=com

dn: cn=guest,ou=groups,dc=example,dc=com
objectClass: top
objectClass: groupOfNames
cn: guest
member: uid=nhpatel,ou=users,dc=example,dc=com
member: uid=guest-user,ou=users,dc=example,dc=com

Configure the “admin” and “guest” roles to demonstrate the AD based authorization.

Username Role Permissions
super-user admin All
system-user admin DATA:READ, DATA:WRITE
guest-user guest DATA:READ, CLUSTER:

Create roles for mapping returned LDA Groups (groups to role mapping)

Groups to roles mapping is configured using “security-ldap-group-role-mapping” property and value for this property has to be provided as a JSON string.

security-ldap-group-role-mapping={\"cn=admin,ou=groups,dc=example,dc=com\":\"admin\",\"cn=guest,ou=groups,dc=example,dc=com\":\"guest\",\"cn=user,ou=groups,dc=example,dc=com\":\"user\"}

For the demo purpose, three different user named "super-user" (admin role), "system-user" (user role)and "ampool" (guest role) are considered. Only admin user super-user has a access permissions to start locators and servers.

I. Security configuration

Security configuration required for locator, server1 and server2. Default security-repository (JsonSecurityRepository) is used to map role-permission mapping.

Security configuration required for locator, server1 and server2. Default security-repository (JsonSecurityRepository) is used to map role-permission mapping.

secureLdapAuthz.properties

security-custom-authenticator-class=io.ampool.security.ldap.SimpleTestAuthenticator
security-manager=io.ampool.security.AmpoolSecurityManager
security-username=super-user
security-password=super-user
security-enable-ldap-authz=true
security-ldap-server=localhost:10389
security-ldap-search-base=ou=groups,dc=example,dc=com
security-ldap-bind-dn=uid=nhpatel,ou=users,dc=example,dc=com
security-ldap-bind-password=nhpatel
security-ldap-group-search-filter=(&(objectClass=groupOfNames)(member=uid={0},ou=users,dc=example,dc=com))
security-ldap-group-role-mapping={\"cn=admin,ou=groups,dc=example,dc=com\":\"admin\",\"cn=guest,ou=groups,dc=example,dc=com\":\"guest\",\"cn=user,ou=groups,dc=example,dc=com\":\"user\"}

II. Start a ampool cluster (1 locator and 2 servers)

Start locator.

mash>start locator --name=locator --classpath=/ldapAuthzDemo --security-properties-file=/ldapAuthzDemo/locator/secureLocator.properties

Start server-1

mash>start server --name=server1 --locators=localhost[10334] --classpath=/ldapAuthzDemo --security-properties-file=/ldapAuthzDemo/server1/secureServer1.properties

Start server-2

mash>start server --name=server2 --locators=localhost[10334] --classpath=/ldapAuthzDemo --security-properties-file=/ldapAuthzDemo/server2/secureServer2.properties --server-port=40405

Note

Start server-3 with user "system-user" (user role) who does not have a required permissions to start server.

mash>start server --name=server3 --locators=localhost[10334] --classpath=/ldapAuthzDemo --security-properties-file=/ldapAuthzDemo/server3/secureServer3.properties --server-port=40406
Starting a Ampool Server in /ldapAuthzDemo/server3...
Exception in thread "main" org.apache.geode.security.GemFireSecurityException: Security check failed. system-user not authorized for CLUSTER:MANAGE

III. Connecting from mash using “admin” user.

mash>connect
Connecting to Locator at [host=localhost, port=10334] ..
Connecting to Manager at [host=localhost, port=1099] ..
user: super-user
password: ********
Successfully connected to: [host=localhost, port=1099]

mash>list members
 Name             | Id
--------------------------- | ---------------------------------------------------------------------
locator | 192.168.1.101(locator:27005:locator)<ec><v0>:1024
server1 | 192.168.1.101(server1:27109)<v1>:1025
server2 | 192.168.1.101(server2:27685)<v2>:1026

mash>list tables
No Tables Found

mash>create table --type=UNORDERED --name=secure_table --schema-json="{"house":"STRING","money":"LONG","id_number":"LONG","status":"STRING"}"
Successfully created the table: secure_table

mash>list tables
 Name        | Type
------------ | ---------
secure_table | Unordered

mash>describe table --name=/secure_table
..........................................................
Name            : secure_table
Data Policy     : partition
Hosting Members : server1
 server2

Non-Default Attributes Shared By Hosting Members 

 Type            |         Name          | Value
---------------- | --------------------- | -------------------
Table            | size                  | 0
 | data-policy   | PARTITION
Eviction         | eviction-action       | overflow-to-disk
 | eviction-algorithm    | lru-heap-percentage
Table Attributes | table-type            | UNORDERED
 | max-versions          | 1
 | persistence-enabled   | false
 | disk-write-policy     | ASYNCHRONOUS
 | observer-coprocessors |
Table Schema     | house                 | STRING
 | money                 | LONG
 | id_number             | LONG
 | status                | STRING
 | __ROW__KEY__COLUMN__  | BINARY

Connecting with user "ampool" having role "guest" having permissions (DATA:READ, CLUSTER:READ)

mash>connect
Connecting to Locator at [host=localhost, port=10334] ..
Connecting to Manager at [host=localhost, port=1099] ..
user: guest-user
password: ******
Successfully connected to: [host=localhost, port=1099]

mash>list members
 Name             | Id
--------------------------- | ---------------------------------------------------------------------
locator | 192.168.1.101(locator:27005:locator)<ec><v0>:1024
server1 | 192.168.1.101(server1:27109)<v1>:1025
server2 | 192.168.1.101(server2:27685)<v2>:1026

mash>list tables
 Name     | Type
------------ | ---------
secure_table | Unordered

mash>describe table --name=/secure_table
..........................................................
Name            : secure_table
Data Policy     : partition
............

mash>create table --type=UNORDERED --name=secure_table --schema-json="{"house":"STRING","money":"LONG","id_number":"LONG","status":"STRING"}"
Unauthorized. Reason : guest-user not authorized for DATA:MANAGE

mash>tput --table=/secure_table --key=1 --value-json='{"house":"country","money":2102584,"id_number":101662015,"status":"Married"}'
Unauthorized. Reason : guest-user not authorized for DATA:WRITE:secure_table

mash>delete table --name=/secure_table
Unauthorized. Reason : guest-user not authorized for DATA:MANAGE

Connecting with user "system-user" having role "user" having permissions (DATA:READ, DATA:WRITE)

mash>connect
Connecting to Locator at [host=localhost, port=10334] ..
Connecting to Manager at [host=localhost, port=1099] ..
user: system-user
password: system-user
Successfully connected to: [host=localhost, port=1099]

mash>list members
Unauthorized. Reason : system-user not authorized for CLUSTER:READ

mash>list tables
 Name     | Type
------------ | ---------
secure_table | Unordered

mash>create table --type=UNORDERED --name=hack_table --schema-json="{"house":"STRING","money":"LONG","id_number":"LONG","status":"STRING"}"
Unauthorized. Reason : system-user not authorized for DATA:MANAGE

mash>tput --table=/secure_table --key=1 --value-json='{"house":"country","money":"2102584","id_number":"101662015","status":"Married"}'
Put completed successfully

mash>tscan --table=/secure_table

Result     : true
startCount : 0
endCount   : 20
Rows       : 1

Result
----------------------------------------------------------------------------------------------------------
RowID = [49] house=country, money=2102584, id_number=101662015, status=Married, __ROW__KEY__COLUMN__=[49]

NEXT_STEP_NAME : END

mash>delete table --name=/secure_table
Unauthorized. Reason : system-user not authorized for DATA:MANAGE

Java API code snippet.

public class MTableSecureClient {
 private static final String[] COLUMN_NAMES =
 new String[] {"NAME", "ID", "AGE", "SALARY", "DEPT", "DOJ"};

 public static void main(String args[]) {
 System.out.println("MTable Quickstart example!");

 String locator_host = "localhost";
 int locator_port = 10334;
 if (args.length == 2) {
 locator_host = args[0];
 locator_port = Integer.parseInt(args[1]);
 }

 // Step:1 create client that connects to the guest-user cluster via locator.
 props.setProperty(USER_NAME, "guest-user");
 props.setProperty(PASSWORD, "guest-user");
 props.put(DistributionConfig.SECURITY_CLIENT_AUTH_INIT_NAME,
 "io.ampool.security.AmpoolAuthInitClient.create");

 final AmpoolClient aClient = new AmpoolClient(locator_host, locator_port, props);
 System.out.println("AmpoolClient connected to the cluster successfully!");

 // Step:2 create the schema.
 final Schema schema = new Schema(COLUMN_NAMES);
 MTableDescriptor tableDescriptor = new MTableDescriptor();
 tableDescriptor.setSchema(schema);

 Admin admin = aClient.getAdmin();
 String tableName = "EmployeeTable";

 MTable table = admin.createMTable(tableName, tableDescriptor);

 //Delete a table
 admin.deleteMTable(tableName);
 System.out.println("Table is deleted successfully!");

 //close the client connection
 aClient.close();
 System.out.println("Connection to monarch DS closed successfully!");
}

Output:

Exception in thread "main" org.apache.geode.security.NotAuthorizedException: ampool not authorized for DATA:MANAGE
Caused by: org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [DATA:MANAGE]

Note

With the user "super-user" having admin role, above code snippet successfully creates a table.

2. Authorize Users Using Microsoft Active Directory.

Introduction.

  • Demonstrate a use-case where group membership information is stored as a part of user attribute. To query group membership information stored as a user attribute, one has to set value of “security-ldap-user-group-attribute”. We have set its value to “memberOf” in the demonstration.

  • Ampool ADS provides support for proxying user authorization requests to a specified LDAP service such as Active Directory (AD).

  • This tutorial describes how to configure Ampool ADS to perform authorization through an Microsoft Active Directory (AD) server via LDAPAuthorizer. Though user can enable its own choice of authentication mechanism, for simplicity a very simple authentication mechanism (SimpleTestAuthenticator) is used in this tutorial.

Prerequisites.

  • A full description of AD is beyond the scope of this tutorial. This tutorial assumes prior knowledge of AD. For this Demo, it has been assumed that a AD server is up and running and setup with desired users and groups.

Considerations.

  • This tutorial explains configuring Ampool ADS for AD authorization.

  • To perform this procedure on your own Ampool ADS server, you must modify the given procedure with respect to your own specific infrastructure, especially Active Directory configurations, constructing AD queries, or managing users.

Example Active Directory Schema.

This tutorial uses the following example AD objects as the basis for the provided queries, configurations, and output. Each object shows only a subset of the possible attribute

User Objects.

CN=Administrator,CN=Users,DC=ampool,DC=io
memberOf: CN=Group Policy Creator Owners,CN=Users,DC=ampool,DC=io
memberOf: CN=Domain Admins,CN=Users,DC=ampool,DC=io
memberOf: CN=Enterprise Admins,CN=Users,DC=ampool,DC=io
memberOf: CN=Schema Admins,CN=Users,DC=ampool,DC=io
memberOf: CN=Administrators,CN=Builtin,DC=ampool,DC=io

CN=Guest,CN=Users,DC=ampool,DC=io
memberOf: CN=Group Policy Creator Owners,CN=Users,DC=ampool,DC=io
memberOf: CN=Guests,CN=Builtin,DC=ampool,DC=io

CN=nhpatel,CN=Users,DC=ampool,DC=io
memberOf: CN=Domain Admins,CN=Users,DC=ampool,DC=io
memberOf: CN=Administrators,CN=Builtin,DC=ampool,DC=io

Group Objects

CN=Domain Admins,CN=Users,DC=ampool,DC=io
member: CN=nhpatel,CN=Users,DC=ampool,DC=io
member: CN=Administrator,CN=Users,DC=ampool,DC=io

CN=Group Policy Creator Owners,CN=Users,DC=ampool,DC=io
member: CN=Guest,CN=Users,DC=ampool,DC=io
member: CN=Administrator,CN=Users,DC=ampool,DC=io

CN=Enterprise Admins,CN=Users,DC=ampool,DC=io
member: CN=Administrator,CN=Users,DC=ampool,DC=io

CN=Schema Admins,CN=Users,DC=ampool,DC=io
member: CN=Administrator,CN=Users,DC=ampool,DC=io

CN=Administrators,CN=Builtin,DC=ampool,DC=io
member: CN=Domain Admins,CN=Users,DC=ampool,DC=io
member: CN=Enterprise Admins,CN=Users,DC=ampool,DC=io
member: CN=nhpatel,CN=Users,DC=ampool,DC=io
member: CN=Administrator,CN=Users,DC=ampool,DC=io

Configure the “admin” and “guest” roles to demonstrate the AD based authorization.**

Username Role Permissions
Administrator admin All
nhpatel admin All
Guest guest DATA:READ, CLUSTER:READ

As shown in “role-permission.json”, admin role is configured with all permissions.

User “Guest” belongs to AD group “Group Policy Creator Owners” for which role mapped is “group_policy_owners_R”. Permissions associated with this roles are “CLUSTER:READ” and “DATA:READ”.

Create roles for mapping returned AD groups (groups to role mapping)**

Groups to roles mapping is configured using “security-ldap-group-role-mapping” property and value for this property has to be provided as a JSON string.

security-ldap-group-role-mapping=
{\"CN=Group Policy Creator Owners,CN=Users,DC=ampool,DC=io\":\"group_policy_owners_R\",
\"CN=Domain Admins,CN=Users,DC=ampool,DC=io\":\"domain_admins_M\",
\"CN=Enterprise Admins,CN=Users,DC=ampool,DC=io\":\"enterprise_admins\",
\"CN=Schema Admins,CN=Users,DC=ampool,DC=io\":\"schema_admins_W\",
\"CN=Administrators,CN=Builtin,DC=ampool,DC=io\":\"admin\"}

Membership information is stored as a "memberOf" attribute of "user" object type. Authorization is based on user attributed "sAMAccountName". One need to change a query filter based on the query requirements.

I. Security configuration

Security configuration required for locator, server1 and server2.

secureADAuthz.properties

security-custom-authenticator-class=io.ampool.security.ldap.SimpleTestAuthenticator
security-manager=io.ampool.security.AmpoolSecurityManager
security-username=Administrator
security-password=Administrator
security-enable-ldap-authz=true
security-ldap-server=35.187.196.243:389
security-ldap-search-base=CN=Users,DC=ampool,DC=io
security-ldap-bind-dn=nhpatel@ampool.io
security-ldap-bind-password=ampool@123
security-ldap-group-search-filter=(&(objectClass=user)(sAMAccountName={0}))
security-ldap-group-role-mapping={\"CN=Group Policy Creator Owners,CN=Users,DC=ampool,DC=io\":\"group_policy_owners_R\",\"CN=Domain Admins,CN=Users,DC=ampool,DC=io\":\"domain_admins_M\",\"CN=Enterprise Admins,CN=Users,DC=ampool,DC=io\":\"enterprise_admins\",\"CN=Schema Admins,CN=Users,DC=ampool,DC=io\":\"schema_admins_W\",\"CN=Administrators,CN=Builtin,DC=ampool,DC=io\":\"admin\"}
security-ldap-user-group-attribute=memberOf

II. Start a ampool cluster (1 locator and 2 servers)

//Start a locator
mash>start locator --name=locator --classpath=/ldapAuthzDemo --security-properties-file=/ldapAuthzDemo/locator/secureADAuthz.properties

//Start a server1
mash>start server --name=server1 --locators=localhost[10334] --classpath=/ldapAuthzDemo --security-properties-file=/ldapAuthzDemo/server1/secureADAuthz.properties

//Start a server2
mash>start server --name=server2 --locators=localhost[10334] --classpath=/ldapAuthzDemo --security-properties-file=/ldapAuthzDemo/server2/secureADAuthz.properties –server-port=40405

III. From mash, Connecting with user "Administrator"

mash>connect
Connecting to Locator at [host=localhost, port=10334] ..
Connecting to Manager at [host=localhost, port=1099] ..
user: Administrator
password: *************
Successfully connected to: [host=localhost, port=1099]

mash>list members
 Name             | Id
--------------------------- | --------------------------------------------------------------------
locator | 192.168.1.101(locator:2241:locator)<ec><v0>:1024
server1 | 192.168.1.101(server1:2403)<v1>:1025
server2 | 192.168.1.101(server2:2645)<v2>:1026

mash>list tables
No Tables Found

mash>create table --type=UNORDERED --name=hack_table1 --schema-json="{"house":"STRING","money":"LONG","id_number":"LONG","status":"STRING"}"
Successfully created the table: hack_table1

mash>list tables
 Name     | Type
----------- | ---------
hack_table1 | Unordered

mash>tput --table=/hack_table1 --key=1 --value-json='{"house":"country","money":"2102584","id_number":"101662015","status":"Married"}'
Put completed successfully

mash>tscan --table=/hack_table1

Result     : true
startCount : 0
endCount   : 20
Rows       : 1

Result
----------------------------------------------------------------------------------------------------------
RowID = [49] house=country, money=2102584, id_number=101662015, status=Married, __ROW__KEY__COLUMN__=[49]

NEXT_STEP_NAME : END

IV. Connecting with user "Guest".

Guest user has a role "group_policy_owners_R" which is mapped to (CLUSTER:READ and DATA:READ)

mash>connect
Connecting to Locator at [host=localhost, port=10334] ..
Connecting to Manager at [host=localhost, port=1099] ..
user: Guest
password: *****
Successfully connected to: [host=localhost, port=1099]

mash>list members
 Name             | Id
--------------------------- | --------------------------------------------------------------------
locator | 192.168.1.101(locator:2241:locator)<ec><v0>:1024
server1 | 192.168.1.101(server1:2403)<v1>:1025
server2 | 192.168.1.101(server2:2645)<v2>:1026

mash>create table --type=UNORDERED --name=hack_table2 --schema-json="{"house":"STRING","money":"LONG","id_number":"LONG","status":"STRING"}"
Unauthorized. Reason : Guest not authorized for DATA:MANAGE

mash>list tables
 Name     | Type
----------- | ---------
hack_table1 | Unordered

mash>tput --table=/hack_table1 --key=1 --value-json='{"house":"country","money":"2102584","id_number":"101662015","status":"Married"}'
Unauthorized. Reason : Guest not authorized for DATA:WRITE:hack_table1

mash>tscan --table=/hack_table1

Result     : true
startCount : 0
endCount   : 20
Rows       : 1

Result
----------------------------------------------------------------------------------------------------------
RowID = [49] house=country, money=2102584, id_number=101662015, status=Married, __ROW__KEY__COLUMN__=[49]

NEXT_STEP_NAME : END

mash>delete table --name=/hack_table1
Unauthorized. Reason : Guest not authorized for DATA:MANAGE