I ended up redirecting slf4j to java.util.logging (JUL). To do this simply use slf4j-jdk14 as your logger implementation in place of logback. Unfortunately, this trades off one problem for another.
On the one hand, your logging is unified. On the other hand, you inherit all the problems associated with JUL. You cannot use any logback-specific features. You cannot use logback.xml to configure your logging. In fact, you cannot even configure different logging rules per webapp (see GLASSFISH-18776). I ended up with the following code in my ServletContextListener:
public void contextInitialized(ServletContextEvent servletContextEvent)
It doesn't solve the problem of all webapps sharing the same logging configuration, but at least now the configuration is packaged in the webapp itself (as opposed to logging.properties in Glassfish's installation directory).