package restx.security;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import org.slf4j.MDC;
import restx.*;
import restx.factory.Component;
import java.io.IOException;
/**
* This filter is responsible for:
* - setting authenticated principal name in MDC.
* - touching sessions, used in sessions admin console to get some details on client sessions.
*
* It is set at priority -110, authentication filters should be set between priority -200 (RestxSessionCookieFilter)
* and -110 to be logged.
*/
@Component(priority = -110)
public class RestxSessionLogFilter implements RestxRouteFilter, RestxHandler {
private final Sessions sessions;
public RestxSessionLogFilter(Sessions sessions) {
this.sessions = sessions;
}
@Override
public Optional<RestxHandlerMatch> match(RestxRoute route) {
return Optional.of(new RestxHandlerMatch(new StdRestxRequestMatch("/*"), this));
}
@Override
public void handle(RestxRequestMatch match, RestxRequest req, RestxResponse resp, RestxContext ctx) throws IOException {
RestxSession session = RestxSession.current();
ImmutableMap<String, String> metadata = prepareSessionStatsMetadata(req, session);
if (session.getPrincipal().isPresent()) {
String name = session.getPrincipal().get().getName();
sessions.touch(name, metadata);
MDC.put("principal", name);
} else {
sessions.touch("anonymous@" + req.getClientAddress(), metadata);
}
ctx.nextHandlerMatch().handle(req, resp, ctx);
}
/**
* Prepares the metadata to be used for session stats monitoring.
*
* If you override this method, make sure to include the map built by the default implementation if you want
* the monitor admin session view to work properly, unless you override it too.
*
* @param req the request for which metadata should be prepared
* @param session the session for which metadata should be prepared
* @return the prepared metadata
*/
protected ImmutableMap<String, String> prepareSessionStatsMetadata(RestxRequest req, RestxSession session) {
return ImmutableMap.of(
"clientAddress", req.getClientAddress(),
"userAgent", req.getHeader("User-Agent").or("Unknown"));
}
}