Skip to content
This repository was archived by the owner on Jul 10, 2022. It is now read-only.

Authentication Gateways

Ian Castaño edited this page Aug 21, 2020 · 2 revisions

A user can choose with which authentication method he wants to log in each time he joins the server. Its model has a very simple field called Authentication. It is up to the rest of the team to decide how this is going to be chosen. You can also use our Model Services to update this field on the user.

Creating a super secret Gateway: "Tomato rules"

Once the authentication system has given the green light, we can do whatever we want to authenticate the user (Please do not do things like the one explained in the example on the production server).

For this time we are going to create an authentication gateway where the user will be able to join if he writes "Tomato rules" in the chat.

Modifying the User document

To begin, we are going to create a new authentication option in the UserDoc's ENUM (Remember that this must also be added in the backend to be storable).

enum Authorization {
    PASSWORD, PREMIUM, TOMATO_RULES
}

Implementing the Gateway Interface

Now, we need a concrete class that implements the basic function of a Gateway: startProcessing().

public class TomatoGateway implements AuthenticationGateway {

    @Override
    public void startProcessing(User user) {
        @Nullable Player player = Bukkit.getPlayer(user.getUsername());

        if (player != null) {
            player.sendTitle("Please type the secret password, master.");
        }
    }

    @Override
    public String getName() {
        return "TomatoRules";
    }

}

Now as long as the backend gives the user permission to authenticate (A.k.a the AuthenticationStartEvent). The corresponding listener will call the GatewayMatcher to ask for the type of authentication that the user configured. All we have to do is add our listener to the list.

@Inject public CoreGatewayMatcher(
            PasswordAuthenticationGateway passwordGateway,
            RegisterGateway registerGateway,
            TomatoGateway tomatoGateway
    ) {
        this.registerGateway = registerGateway;
        this.types = new HashMap<>();
        types.put(UserDoc.Session.Authorization.PASSWORD, passwordGateway);
        types.put(UserDoc.Session.Authorization.TOMATO_ROLES, tomatoGateway);
    }

Now, whenever a user joins and selects our authentication method, whatever we indicate in our gateway will be executed.

Authorizing the user access

Now, since the system knows our gateway and the user knows what to do, we only have to notify Centauri that the authentication was successful. We will do this by calling the AuthenticationSuccessEvent. This time we are going to call him in a chat listener.

public class UserChatListener implements Listener {

    private @Inject TomatoGateway tomatoGateway;

    public void onUserAsyncChat(AsyncPlayerChatEvent event) {
        String message = event.getMessage();
        if (event.getMessage().equalsIgnoreCase("Tomato rules")) {
            Bukkit.getPluginManager().callEvent(new AuthenticationSuccessEvent(tomatoGateway, event.getPlayer()));
            event.setCancelled(true);
        }
    }
}

Voila!. The user will be redirected to his last lobby along with a cool "Welcome back" message. For now this is the basic operation of a gateway. Obviously this is an example that you can start from to do something much more secure and reliable. In the next section you will learn how to detect when there was an invalid login attempt.

Clone this wiki locally