/** * <p>Checks if a message should be allowed to create a new channel.</p> * <p>A subscribe message or publish message to a channel not yet known to the server triggers this check. * Both remote sessions and local sessions, when performing subscribes or publishes via * {@link ClientSessionChannel#subscribe(ClientSessionChannel.MessageListener)} or * {@link ClientSessionChannel#publish(Object)} are therefore subject to this check.</p> * <p>Direct calls to {@link BayeuxServer#createChannelIfAbsent(String, ConfigurableServerChannel.Initializer...)} * are not subject to this check.</p> * * @param server the {@link BayeuxServer} object * @param session the client sending the message * @param channelId the channel to be created * @param message the message trying to create the channel * @param promise the promise to notify whether the channel should be created */ default void canCreate(BayeuxServer server, ServerSession session, String channelId, ServerMessage message, Promise<Boolean> promise) { promise.succeed(canCreate(server, session, channelId, message)); }
/** * <p>Checks if a handshake message should be accepted.</p> * <p>Both remote sessions and local sessions are subject to this check. * Applications usually want local sessions (that is, server-side only sessions related to services) * to always pass this check, so a typical implementation filters local session using * {@link ServerSession#isLocalSession()}.</p> * * @param server the {@link BayeuxServer} object * @param session the session (not yet added to the BayeuxServer) * @param message the handshake message * @param promise the promise to notify whether the handshake message should be accepted and the * {@link ServerSession} instance associated to the {@link BayeuxServer} object */ default void canHandshake(BayeuxServer server, ServerSession session, ServerMessage message, Promise<Boolean> promise) { promise.succeed(canHandshake(server, session, message)); }
/** * <p>Checks if a client can publish a message to a channel.</p> * <p>Both remote and local sessions are subject to this check when performing publishes via * {@link ClientSessionChannel#publish(Object)}.</p> * <p>Server-side publishes are not subject to this check.</p> * * @param server the {@link BayeuxServer} object * @param session the client sending the message * @param channel the channel to publish to * @param message the message to being published * @param promise the promise to notify whether the client can publish to the channel */ default void canPublish(BayeuxServer server, ServerSession session, ServerChannel channel, ServerMessage message, Promise<Boolean> promise) { promise.succeed(canPublish(server, session, channel, message)); }
/** * <p>Checks if a subscribe message from a client is allowed to subscribe to a channel.</p> * <p>Both remote and local sessions are subject to this check when performing subscribes via * {@link ClientSessionChannel#subscribe(ClientSessionChannel.MessageListener)}.</p> * <p>{@link ServerChannel#subscribe(ServerSession)} is not subject to this check.</p> * * @param server the {@link BayeuxServer} object * @param session the client sending the message * @param channel the channel to subscribe to * @param message the subscribe message * @param promise the promise to notify whether the client can subscribe to the channel */ default void canSubscribe(BayeuxServer server, ServerSession session, ServerChannel channel, ServerMessage message, Promise<Boolean> promise) { promise.succeed(canSubscribe(server, session, channel, message)); }
private void isSubscribeAuthorized(ServerChannel channel, ServerSession session, ServerMessage message, Promise<Authorizer.Result> promise) { if (_policy != null) { _policy.canSubscribe(this, session, channel, message, Promise.from(can -> { if (can == null || can) { isOperationAuthorized(Authorizer.Operation.SUBSCRIBE, session, message, channel.getChannelId(), promise); } else { _logger.info("{} denied Subscribe@{} by {}", session, channel, _policy); promise.succeed(Authorizer.Result.deny("denied_by_security_policy")); } }, promise::fail)); } else { isOperationAuthorized(Authorizer.Operation.SUBSCRIBE, session, message, channel.getChannelId(), promise); } }
private void handleMetaHandshake(ServerSessionImpl session, Mutable message, Promise<Boolean> promise) { BayeuxContext context = message.getBayeuxContext(); if (context != null) { session.setUserAgent(context.getHeader("User-Agent")); } if (_policy != null) { _policy.canHandshake(this, session, message, Promise.from(can -> { if (can) { handleMetaHandshake2(session, message, promise); } else { ServerMessage.Mutable reply = message.getAssociated(); error(reply, "403::handshake_denied"); // The user's SecurityPolicy may have customized the response's advice Map<String, Object> advice = reply.getAdvice(true); if (!advice.containsKey(Message.RECONNECT_FIELD)) { advice.put(Message.RECONNECT_FIELD, Message.RECONNECT_NONE_VALUE); } promise.succeed(false); } }, promise::fail)); } else { handleMetaHandshake2(session, message, promise); } }
private void isCreationAuthorized(ServerSession session, ServerMessage message, String channel, Promise<Authorizer.Result> promise) { if (_policy != null) { _policy.canCreate(BayeuxServerImpl.this, session, channel, message, Promise.from(can -> { if (can == null || can) { isOperationAuthorized(Authorizer.Operation.CREATE, session, message, new ChannelId(channel), promise); } else { _logger.info("{} denied creation of channel {} by {}", session, channel, _policy); promise.succeed(Authorizer.Result.deny("denied_by_security_policy")); } }, promise::fail)); } else { isOperationAuthorized(Authorizer.Operation.CREATE, session, message, new ChannelId(channel), promise); } }
private void isPublishAuthorized(ServerChannel channel, ServerSession session, ServerMessage message, Promise<Authorizer.Result> promise) { if (_policy != null) { _policy.canPublish(this, session, channel, message, Promise.from(can -> { if (can == null || can) { isOperationAuthorized(Authorizer.Operation.PUBLISH, session, message, channel.getChannelId(), promise); } else { _logger.info("{} denied publish on channel {} by {}", session, channel.getId(), _policy); promise.succeed(Authorizer.Result.deny("denied_by_security_policy")); } }, promise::fail)); } else { isOperationAuthorized(Authorizer.Operation.PUBLISH, session, message, channel.getChannelId(), promise); } }