Implementing Authentication
Authentication lends a measure of security to a cluster by verifying the identity of components as they connect to the system. All components use the same authentication mechanism.
How Authentication Works
When a component initiates a connection to the cluster, the SecurityManager.authenticate
method is invoked.
The component provides its credentials in the form of properties as a parameter to the authenticate
method.
The credentials parameter is generated by the security-client-auth-init
class’s getCredentials()
call,
for example a token, a certificate, or a user/password combination.
The authenticate
method is expected to either return an object
representing a principal or throw an AuthenticationFailedException
.
A well-designed authenticate
method will have a set of known credentials, such as user and password pairs, that can be
compared to the credentials presented or will have a way of obtaining those credentials.
How a Server Sets Its Credentials
In order to connect with a locator that performs authentication,
a server must set its credentials, a username and password specified as the two properties
security-username
and security-password
.
Choose one of two ways to set the server credentials:
- Add settings to the server properties file, if the credentials comprise a simple username/password combination, or
- Implement the
AuthInitialize
interface for the server
Add Settings to the Server Properties File
Set security-username
and security-password
in the server’s
gfsecurity.properties
file, which is read upon server startup.
For example:
security-username=admin
security-password=xyz1234
The username and password are stored in cleartext, so the
gfsecurity.properties
file must be protected by restricting access with
file system permissions.
Implement the AuthInitialize Interface for the Server
To implement the AuthInitialize
interface for the server, set the
security-peer-auth-init
property so that an object of the class that implements the AuthInitialize
interface will be instantiated. There are two ways to do this:
- You can set the
security-peer-auth-init
property to the fully-qualified class name that implements theAuthInitialize
interface as in the example
security-peer-auth-init=com.example.security.ServerAuthenticate
- You can set the
security-peer-auth-init
property to the fully-qualified method name of a method that instantiates an object of the class that implements theAuthInitialize
interface as in the example
security-peer-auth-init=com.example.security.ServerAuthenticate.create
Implement the getCredentials
method within the AuthInitialize
interface to acquire values for
the security-username
and security-password
properties in whatever way you wish. For example,
it might look up values in a database or another external resource.
Gateway senders and receivers communicate as components of their respective server members. Therefore, the credentials of the server become those of the gateway sender or receiver.
How a Client Cache Sets its Credentials
In order to connect with a locator or a server that performs authentication,
a client must set its credentials. The credentials parameter is generated by the security-client-auth-init
class’s getCredentials()
call,
for example a token, a certificate, or a user/password combination.
You must perform two actions to set to set the client credentials:
- Implement the
AuthInitialize
interface for the client - Provide
Authinitialize.getCredentials()
with secure access to the client credentials
Implement the AuthInitialize Interface for the Client
To implement the AuthInitialize
interface for the client, set the security-client-auth-init
property,
so that an object of the class that implements the AuthInitialize
interface will be instantiated.
There are two ways to do this:
- You can set the
security-client-auth-init
property to the fully-qualified class name that implements theAuthInitialize
interface as in the example:
security-client-auth-init=com.example.security.ClientAuthInitialize
- You can set the
security-client-auth-init
property to the fully-qualified name of a static method that instantiates an object of the class that implements theAuthInitialize
interface as in the example
security-client-auth-init=com.example.security.ClientAuthInitialize.create
Implement the getCredentials()
method of the AuthInitialize
interface for the client to acquire values for
the security-username
and security-password
properties in whatever way
wish. For example, it might look up values in a database or another external resource,
or it might prompt for values.
Provide Secure Access to Client Credentials
Set the security-username
and security-password
properties for the client in a way that can be
accessed by the getCredentials
implementation in AuthInitialize
. This can be done via the APIs,
properties file or other external sources:
Properties properties = new Properties();
properties.setProperty("security-username", "exampleuser23");
properties.setProperty("security-password", "xyz1234");
ClientCache cache = new ClientCacheFactory(properties).create();
For security, take care that credentials set in this manner are not accessible to observers of the code.
How Other Components Set Their Credentials
gfsh
prompts for the username and password upon invocation of
agfsh connect
command. These username/password combinations will be provided as properties
to the authenticate
method in the keys of security-username
and security-password
.
Pulse prompts for the username and password upon start up.
Due to the stateless nature of the REST API,
a web application or other component that speaks to a server or locator
via the REST API goes through authentication on each request.
The header of the request needs to include attributes that define values for
security-username
and security-password
.
Implement SecurityManager Interface
Complete these items to implement authentication done by either a locator or a server.
- Decide upon an authentication algorithm.
The Authentication Example
stores a set of username and
password pairs that represent the identities of components
that will connect to the system.
This simplistic algorithm returns the username as a principal
if the username and password passed to the
authenticate
method are a match for one of the stored pairs. - Define the
security-manager
property. See Enable Security with Property Definitions for details about this property. - Implement the
authenticate
method of theSecurityManager
interface. - Define any extra resources that the implemented authentication algorithm needs in order to make a decision.