I have two Shiro protected apps that allow anonymous access to all pages. One is a WAR deployed inside the Jetty server, and the other is a stand-alone Java application with an integrated Jetty server.
- Why does a standalone application not create sessions, but a WAR application?
- How to set up a standalone session creation application?
- Why does a stand-alone application require the session manager to be explicitly defined in shiro.ini, but the WAR application does not work? (Removing this means that the authcBasic filter does not work either).
WAR application
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"?> <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 application
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>
Proof of a stand-alone application (and therefore a problem with AnonymousFilter)
In a standalone application, if I replaced 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 a "name" and create a session. This seems to be an anonymous filter that refuses to create sessions.
Additional Information
When I say "session created", I mean when I look at localhost: 8080 / I can see the Set-Cookie: JSESSIONID=blahblahblah header Set-Cookie: JSESSIONID=blahblahblah in the response from the server. No such cookie is set by an anonymous filter in a standalone application.