Dedicated server async authentication on PreLogin/Login

I have a dedicated server set up to which clients can connect but I want this connection to be authenticated. I took a look into the C++ code and it seems the authentication should be done in GameMode - PreLogin / Login functions. The trouble is these functions return a string value immediately and there is no way to make them wait while I do my authentication (through REST using VAREST).

Is there a way to kick off some async task in PreLogin / Login functions and pause them until the async task is carried out? Preferably if the async task could then be implemented in Blueprint.

One way to do this would be to start an AsyncTask on the Login() method from which you will send your HTTP request and pass in a delegate which you can subscribe to from your GameMode class that will be the OnTaskCompleted delegate or something simillar. While all of this is happening you can have your player stay in spectator or show a loading screen etc.

After that delegate fires meaning the task has been processed, depending on the authentication result you can either kick the player or “accept” him by removing the loading screen and / or allowing him to spawn in the game.

This could be accomplished through C++ with an FNonAbandonableTask child:(A new, community-hosted Unreal Engine Wiki - Announcements - Unreal Engine Forums)

Or you could look into Blueprint Async Operations:
(A new, community-hosted Unreal Engine Wiki - Announcements - Unreal Engine Forums)

Thanks, I can do the spectate mode with the spectator flags in C++ but how to swap from spectator to actual player? And is there a function to kick player?

For kicking, you can look into AGameSession::KickPlayer, for the spectator mode, what you can do is just set the default pawn to a spectator pawn, and / or in your gamemode’s constructor do bStartPlayersAsSpectators = true and then when you are ready to spawn the player in, simply create a new playable pawn using SpawnActor and then call the Possess method of the player’s player controller with a server RPC to possess the pawn that you just spawned.

Found possibly better solution.
Since UE4 managing auth inside of chain that heads from UControlChannel::ReceivedBunch to UWorld::NotifyControlMessage, it is possible to override its logic and reroute NMT_Join or NMT_Login packages to your custom channel class derived from UControlChannel.
You may not close your connection nor sending any data to it and it will remain stall, waiting for your response.
Mean while you can do anything asynchronously and than respond to that connection later in way it responds by default.
No stalls, no freezes, no need to allow unauthorized player to get any data from game session.

You may override control channel class via DefaultEngine.ini in your project config folder by adding following lines

[/Script/Engine.NetDriver]
-ChannelDefinitions=(ChannelName=Control, ClassName=/Script/Engine.ControlChannel, StaticChannelIndex=0, bTickOnCreate=true, bServerOpen=false, bClientOpen=true, bInitialServer=false, bInitialClient=true)
+ChannelDefinitions=(ChannelName=Control, ClassName=/Script/YourGameModule.UYourCustomControlChannel, StaticChannelIndex=0, bTickOnCreate=true, bServerOpen=false, bClientOpen=true, bInitialServer=false, bInitialClient=true)