| --- |
| title: Implementing Authentication |
| --- |
| |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| |
| 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. |
| |
| ## <a id="authentication-how-it-works"></a>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` |
| or `AuthenticationExpiredException`. The principal object is what is passed on to the `authorize` method |
| which is discussed in detail in the [authorization](authorization_overview.html) section. |
| |
| In case of an `AuthenticationExpiredException` the <%=vars.product_name%> client code will make one automatic attempt |
| to re-connect to the member that sent the exception. |
| |
| 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. |
| |
| ## <a id="authentication-server-set-creds"></a>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`. In case of systems that use tokens for authentication |
| the property `security-token` should be provided. |
| |
| 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 |
| |
| ### <a id="authentication-setserverprops"></a>Add Settings to the Server Properties File |
| |
| Set `security-username` and `security-password` or `security-token` in the server's |
| `gfsecurity.properties` file, which is read upon server startup. |
| For example: |
| |
| ``` pre |
| security-username=admin |
| security-password=xyz1234 |
| ``` |
| |
| Or: |
| |
| ```pre |
| security-token=abcdxyz |
| ``` |
| |
| The username, password, and tokens are generally base64 encoded strings which are stored in |
| cleartext, so the `gfsecurity.properties` file must be protected by restricting access with |
| file system permissions. |
| |
| ### <a id="authentication-implementserverinterface"></a>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 |
| the `AuthInitialize` interface as in the example |
| |
| ``` pre |
| 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 the `AuthInitialize` interface as in the |
| example |
| |
| ``` pre |
| security-peer-auth-init=com.example.security.ServerAuthenticate.create |
| ``` |
| |
| Implement the `getCredentials` method within the `AuthInitialize` interface to acquire values for |
| the `security-token` property or 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. |
| |
| ## <a id="authentication-client-set-creds"></a>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 |
| |
| ### <a id="authentication-implementclientinterface"></a>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 the `AuthInitialize` interface as in the example: |
| |
| ``` pre |
| 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 the `AuthInitialize` interface as in the example |
| |
| ``` pre |
| 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-token` property or 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. |
| |
| When implementing the `getCredentials()` method for a token based system keep in mind that the token |
| provider may return an existing token for a user and that this token may expire sooner than expected. |
| Make sure to understand the implications of this and consider building in a check for imminent expiry |
| in the `getCredentials()` implementation so that a newly fetched but soon to be expired token does |
| not cause undesired exceptions when used for operations. |
| |
| |
| ### <a id="authentication-provideclientcredaccess"></a>Provide Secure Access to Client Credentials |
| |
| Set the `security-token` property or 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: |
| |
| ``` pre |
| 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. |
| |
| |
| ## <a id="authentication-component-set-creds"></a>How Other Components Set Their Credentials |
| |
| `gfsh` prompts for the username and password upon invocation of |
| a`gfsh 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` or in case of token based security the appropriate header associated with the |
| scheme such as `Authorization: Bearer [encoded token-string]` for `OAuth` |
| |
| ## <a id="authentication-implement-security-mgr"></a>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](authentication_examples.html) |
| 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](enable_security.html) |
| for details about this property. |
| - Implement the `authenticate` method of the `SecurityManager` interface. |
| - Define any extra resources that the implemented authentication algorithm |
| needs in order to make a decision. |