Server Authentication for Server for Client - Single-Threaded

I am creating a login server for my client for a server application.

Basically there are 5 servers, and all of these servers are connected to the same login server.

A client can connect to any of these 5 servers, but it must authenticate with a username and password. Authentication should be performed on the login server, and the login server should return a response to the actual server, which should return a response to the client.

So like this:

Client β†’ Server β†’ Login Server β†’ Server β†’ Client (response code)

Now I use Netty and this is NIO, it is not a stream to the client. Now, in order to authenticate using NIO, we have to wait for a response from the login server, and this may take some time and delay other clients who want to log in, in fact, you can’t just wait for a response from NIO, so I I thought about how I can make it work. My idea started the request in another thread and had an event with the onResponse(String key, int responseCode) method onResponse(String key, int responseCode) , and then put the client channel on the map with the generated key so that we can find out who the answer belongs to. Therefore, when we authenticate, we send the key and user data.

But I feel that this is a bad way, and there is a more efficient method for this. Any ideas?

+5
source share
4 answers

Assuming you have full control over the entire system:

Assign an identifier for each client connection on the server. Then, when you need to authenticate the user, specify this connection identifier in the request from the server to the login server and return it without waiting for a response from the login server.

For some time in the future, your server will receive a login from the login server. If the response to the input contains the identifier for connecting to the client, use this identifier to find the connection to the server with the client and transfer it back to the client.

+2
source

Here is how I did it.

Customization

Create a channel wrapper class so that you can determine which channel belongs to the client.

 public class CustomChannel implements Channel { private final Channel channel; private final String clientId; ... } 

Create your own ChannelMatcher to match the client channel:

 public class CustomChannelMatcher implements ChannelMatcher { private final String clientId; public CustomChannelMatcher(String clientId) { this.clientId = clientId; } @Override public boolean matches(Channel channel) { if (channel instanceof CustomChannel) { return clientId.equals(((CustomChannel) channel).getClientId()); } return false; } ... } 

Processing request

In the client handler, use ChannelGroup to track the channels of your clients.

 ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); ... channelGroup.add(new CustomChannel(ctx.channel(), clientId)); // send request to another server without blocking 

Response processing

In the server handler, use your CustomChannelMatcher to match the client channel.

 // when the server responds sometimes later channelGroup.writeAndFlush(responseMessage, new CustomChannelMatcher(clientId)); 

In the above code you will find the corresponding client channel and write a message to it.

+1
source

You are worried about blocking the NIO workflow, but you are using a different thread to log in. In any case, you used another thread. So define more threads on your server for http (s) and do with it. If you do not expect more than 100 simultaneous entries, there is no problem.

NIO is reevaluated; The OS is great for scheduling threads and switching contexts, much better than in java running backflips using asyn apis. Waiting threads do not consume a processor.

+1
source

I know you said you were on Netty. I just need to say something about the servlet api, though (in case you can use it):

FYI, this is an api 3.0+ servlet problem that allows you to do just that job in AsynContext. Don’t joke, read on servlet 3.0, preferably javaone youtube presentations and tutorials, even the PDF specification is better than javadoc.

And if you even want to perform NIO in servetworkputstream / servletoutputstream, you can do this (albeit a bit) using the api 3.1 servlet. The javaone presentation (2014, I think) is wonderful.

0
source

Source: https://habr.com/ru/post/1241248/


All Articles