---
title:  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.
-->

A client is authenticated when it connects with valid credentials to a <%=vars.product_name%> cache server that is configured with the client `Authenticator` callback.
For details on the server's role in authentication and what it expects from the client, see [Implementing Authentication](geodeman/managing/security/implementing_authentication.html) in the *<%=vars.product_name%> User Guide*.

Examples of various implementations can be found in the Native Client source distribution's `../templates/security` directory.

In your application, authentication credentials must be set when creating the cache. In practice,
this means setting the authentication credentials when you create the CacheFactory.

### .NET Authentication Example

The following excerpt is taken from the .NET example provided with your Native Client distribution in the `../examples/dotnet/AuthInitialize` directory.
In this C# authentication example, credentials are implemented in the GetCredentials member function of the ExampleAuthInitialize class, which implements the IAuthInitialize interface.


```cs
  class ExampleAuthInitialize : IAuthInitialize
  {
    public ExampleAuthInitialize()
    {
      // TODO initialize your resources here
      Console.Out.WriteLine("ExampleAuthInitialize::ExampleAuthInitialize called");
    }

    public void Close()
    {
      // TODO close your resources here
      Console.Out.WriteLine("ExampleAuthInitialize::Close called");
    }

    public Properties<string, object> GetCredentials(Properties<string, string> props, string server)
    {
      // TODO get your username and password
      Console.Out.WriteLine("ExampleAuthInitialize::GetCredentials called");

      var credentials = new Properties<string, object>();
      credentials.Insert("security-username", "root");
      credentials.Insert("security-password", "root");
      return credentials;
    }
  }

```

### C++ Authentication Example

In this C++ authentication example, credentials are implemented in the getCredentials member function of the AuthInitialize abstract class.

```cpp
class UserPasswordAuthInit : public AuthInitialize {
public:
  UserPasswordAuthInit() = default;
  
  ~UserPasswordAuthInit() noexcept override = default;
  
  std::shared_ptr<Properties> getCredentials(
    const std::shared_ptr<Properties> &securityprops,
    const std::string &) override {
    std::shared_ptr<Cacheable> userName;
    if (securityprops == nullptr ||
      (userName = securityprops->find(SECURITY_USERNAME)) == nullptr) {
      throw AuthenticationFailedException(
      "UserPasswordAuthInit: user name "
      "property [SECURITY_USERNAME] not set.");
    }
  
    auto credentials = Properties::create();
    credentials->insert(SECURITY_USERNAME, userName->toString().c_str());
    auto passwd = securityprops->find(SECURITY_PASSWORD);
    if (passwd == nullptr) {
      passwd = CacheableString::create("");
    }
    credentials->insert(SECURITY_PASSWORD, passwd->value().c_str());
    return credentials;
  }

  void close() override { return; }
};

```
