Authentication

The user plugin is required by most other SA plugins. Its features include:

  • Authenticating the player using internal or external identity providers. Providers for Steam, Playfab and console platforms are currently available, new ones can be created using extensibility points.

  • Keeping track of in memory session data about the player, and providing the data to other services. (Session management)

  • Providing authorization mechanisms that allow other services and plugins to restrict access to certain parts of the SA.

Dependencies

server

  • API

  • AdminAPI

client

  • Core

Usage (client)

Enabling the plugin

The plugin needs to be explicitely enabled in the client configuration before startup.

config->addPlugin(new AuthenticationPlugin());

Configuring authentication

The authentication system automatically tries to connect to the server then authenticate the client when the game client calls an online API. When this happens, the authentication system must retrieves client credentials to send to the server. If the client gets disconnected, updated credentials are requested. To provides credentials, the client must supply a getCredentialsCallback. This function returns a task, so credentials retrieval can be both synchronous (accessing stored variables) or asynchronous (performing an HTTP call or asking for credentials to the users)

For instance for device ids.

auto deviceId = "foo";
client->dependencyResolver().resolve<AuthenticationService>()->getCredentialsCallback = [deviceId](){
    AuthParameters args;
            //Type of the provider that should be used.
    args.type = "deviceidentifier";
    args.parameters.emplace("devideidentifier",deviceId);
    //Sets foo as the devide identifier. Obviously, using a different deviceidentifier for each client would be mandatory. This implementation is going to kick the first player connecting as soon as a second one connects.
    return pplx::task_from_result(args);
};

Connecting

Connection is performed transparently during the first call to an online API. The connection mechanism is fully threadsafe, so it’s possible to concurrently call several APIs and still only trigger a single conneciton attempt.

In case of connection failure, the system tries again in the background until success. Connection state updates can be tracked using the ConnectionState and onConnectionStateChanged member functions/event.

GameConnectionState connectionState() const;
Action2<GameConnectionState> connectionStateChanged;

If authentication fails, retries are disabled, connectionStateChanged reports the error and API calls waiting for authentication fail with an authentication failed error.

It’s possible to trigger authentication immediatly:

client->dependencyResolver().resolve<AuthenticationService>()->login().get();

Logins returns a task that completes with the authentication process. Authentication failure completes the task with an exception.

remark: We use .get() to block the thread until the task completes. Better implementations use .then() to provide a continuation callback.

Disconnecting

Disconnecting cancels any pending online API call and close the connection to the server.

client->dependencyResolver().resolve<AuthenticationService>()->logout().get();

Authentication providers

Device identifier

The device identifier authentication provider enables authenticating users with a simple unique identifier. It doesn’t perform any credentials verification.

Configuration

"auth":{
        "deviceIdentifier":{
                    "enabled":true|false
            }
}

Auth parameters

    args.type = "deviceidentifier";
args.parameters.emplace("devideidentifier",deviceId);

Steam

Authenticates users against the Steam API.

Configuration

    steam:{
            "apiKey":"xxxx",
            "appId":"1234"
    },
"auth":{
            "steam":{
                    "enabled":true|false
            }
    }

Auth parameters

args.type = "steam";
    args.parameters.emplace("ticket","steam-ticket");

Playfab

Authenticates the player against the playfab API. The client must get a playfab ticket by authenticating with playfab with the client WebAPI and send the ticket to the authentication service.

Configuration

playfabe:{
        "titleId":"1234",
        "secret":"xxxx",
        "apiEndpoint":"https://{{titleId}.playfabapi.com/"
},
...
"auth":{
        "playfab":{
                "enabled":true|false,
        }
}

Auth parameters

args.type = "playfabe";
args.parameters.emplace("ticket","playfabTicket");