rsocket / rsocket-java

Java implementation of RSocket
http://rsocket.io
Apache License 2.0
2.35k stars 354 forks source link

Using SocketAcceptorInterceptor: The Issue of Metadata in Multiple Connections #1111

Open MrWangGang opened 1 month ago

MrWangGang commented 1 month ago

Assume there are two connections that both transmit metadata upon establishment. In SocketAcceptorInterceptor, metadata from one connection can be accessed from the other connection. However, I want to ensure that only the unique metadata of each connection can be retrieved. How can I achieve this, or what steps should I take to identify and handle this?

    @Override
    public SocketAcceptor apply(SocketAcceptor socketAcceptor) {
        return (setup, sendingSocket) -> {
            SecurityStash securityStash = getValueFromMetadata(setup.metadata());
            return socketAcceptor.accept(setup,sendingSocket).map(rsocket->{
                return createRSocket(rsocket,securityStash);
            });
        };
    }

    private SecurityStash getValueFromMetadata(ByteBuf metadata) {
        SecurityStash securityStash = SecurityStash.builder().build();
        if(metadata!=null){
            CompositeMetadata compositeMetadata = new CompositeMetadata(metadata, false);
            if(compositeMetadata!=null){
                compositeMetadata.stream()
                        .forEach(entry -> {
                            if(AUTHTOKEN_STASH_NAMING.equals(entry.getMimeType())){
                                ByteBuf content = entry.getContent();
                                String _authtoken = content.toString(io.netty.util.CharsetUtil.UTF_8);
                                securityStash.setAuthToken(_authtoken);
                            }
                            if(PRINCIPAL_STASH_NAMING.equals(entry.getMimeType())){
                                ByteBuf content = entry.getContent();
                                String _principal = content.toString(io.netty.util.CharsetUtil.UTF_8);
                                securityStash.setPrincipal(_principal);
                            }
                        });
                return securityStash;
            }
        }
        return securityStash;
    }

setup.metadata() can retrieve metadata from other connections, but I want to obtain only the unique metadata of the current connection.

The difference between setup.metadata() and setup.data() is that setup.metadata() can retrieve metadata from other connections, while setup.data() retrieves only the data unique to the current connection. When I have two connections that both use metadata transmission, I find that setup.metadata() in the second connection can still access the metadata from the first connection. However, when using the data part for transmission, setup.data() retrieves only the data unique to the current connection. It seems that setup.data() is easier to use for user authentication logic. Why does this difference occur, and what causes this discrepancy?

help,ps... This is crucial for the framework I'm writing. I'm using sockets, and during connection setup, I want to validate user information. However, setup.metadata can retrieve data from other connections, making it difficult for me to determine the user token for the current connection. Using data seems feasible, but I'm unsure about the difference between data and metadata. Is the buffer of metadata shared in memory?