I have two applications secured with Shiro allowing anonymous access to all pages. One is a WAR deployed inside a Jetty server, and the other is a standalone Java application with an embedded Jetty server.
- Why does the standalone app not create sessions but the WAR app does?
- How do I configure the standalone app so that sessions are created?
- Why does the standalone app require the session manager to be explicitly defined in the shiro.ini but the WAR app does not? (Removing it means the authcBasic filter doesn't work either).
WAR app
WEB-INF/shiro.ini:
[main]
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager
[urls]
/** = anon
WEB-INF/web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<welcome-file-list>
<welcome-file>home.jsp</welcome-file>
</welcome-file-list>
</web-app>
home.jsp:
<!DOCTYPE html>
<html>
<body>
</body>
</html>
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress osmorcNonOsgiMavenDependency -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.foo.example</groupId>
<artifactId>apache-shiro-tutorial-webapp</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>Apache Shiro Tutorial Webapp</name>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.1.0.v20131115</version>
<configuration>
<webApp>
<contextPath>/</contextPath>
</webApp>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.2.2</version>
</dependency>
</dependencies>
</project>
Standalone app
classpath:shiro.ini:
[main]
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager
[urls]
/** = anon
Main.java:
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.web.env.EnvironmentLoaderListener;
import org.apache.shiro.web.servlet.ShiroFilter;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import javax.servlet.DispatcherType;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import static java.util.EnumSet.allOf;
public class Main {
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
ShiroFilter shiroFilter = new ShiroFilter();
ServletContextHandler context = new ServletContextHandler();
context.addEventListener(new EnvironmentLoaderListener());
context.setContextPath("/");
context.addFilter(new FilterHolder(shiroFilter), "/", allOf(DispatcherType.class));
context.addServlet(new ServletHolder(dummyServlet), "/");
server.setHandler(context);
server.start();
SecurityUtils.setSecurityManager(shiroFilter.getSecurityManager());
server.join();
}
private static HttpServlet dummyServlet = new HttpServlet() {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("OK");
}
};
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.3.1.v20150714</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.3.1.v20150714</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.13</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
Proving the standalone app works (and therefore the AnonymousFilter is the problem)
In the standalone app, if I replace the shiro.ini file with:
[main]
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager
[users]
name = password
[urls]
/** = authcBasic
then I can log in as "name" and a session is created. It seems to only be the anonymous filter which refuses to create sessions.
Other info
When I say "a session is created" I mean when I browse to localhost:8080/ the I can see the Set-Cookie: JSESSIONID=blahblahblah
header in the response from the server. No such cookie is ever set by the anonymous filter in the standalone app.