From f732fe886c9dcbe08fae2d188a415766b6a0172d Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Fri, 14 Aug 2026 14:21:00 +0200 Subject: [PATCH] Fix broken login flow in shiro-basic example The example was unusable: every request redirected to Shiro's default loginUrl of /login.jsp, which does not exist here, producing an infinite redirect loop. shiro.ini defined only [users] and [roles], so no filter chain was configured and Shiro protected every path including the login page and the form it posts to. Because shiroFilter is mapped for FORWARD as well as REQUEST, the JSPs the Struts actions forward to were caught too, so listing only the actions would not have been enough. Adds a [main] section pointing authc at the login action, and a [urls] chain leaving the login path anonymous while protecting the rest. Separately, the container rewrote redirect URLs as ...;jsessionid=... on a visitor's first request, and Jetty 11 rejects its own rewritten URI with HTTP 400 Invalid request. Restricting session tracking to cookies stops the rewriting. Verified in a browser and over HTTP: login as lonestarr renders the welcome page with roles and permissions resolved, logout returns to the login page, and welcome.action is no longer reachable afterwards. Co-Authored-By: Claude Opus 5 --- shiro-basic/src/main/resources/shiro.ini | 28 ++++++++++++++++++++- shiro-basic/src/main/webapp/WEB-INF/web.xml | 8 ++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/shiro-basic/src/main/resources/shiro.ini b/shiro-basic/src/main/resources/shiro.ini index 436c4658..dec7d78d 100644 --- a/shiro-basic/src/main/resources/shiro.ini +++ b/shiro-basic/src/main/resources/shiro.ini @@ -4,6 +4,17 @@ # Usernames/passwords are based on the classic Mel Brooks' film "Spaceballs" :) # ============================================================================= +# ----------------------------------------------------------------------------- +# Shiro objects and settings +# +# This example authenticates programmatically in LoginAction rather than letting +# Shiro's form filter do it, so authc only needs to know where to send an +# unauthenticated visitor. Shiro's default is /login.jsp, which does not exist +# here — the login form is rendered by the "login" Struts action. +# ----------------------------------------------------------------------------- +[main] +authc.loginUrl = /login.action + # ----------------------------------------------------------------------------- # Users and their (optional) assigned roles # username = password, role1, role2, ..., roleN @@ -22,4 +33,19 @@ lonestarr = vespa, goodguy, schwartz [roles] admin = * schwartz = lightsaber:* -goodguy = winnebago:drive:eagle5 \ No newline at end of file +goodguy = winnebago:drive:eagle5 + +# ----------------------------------------------------------------------------- +# Filter chain, evaluated top-down — the first matching path wins. +# +# Without this section Shiro protects every path, including the login page and +# the form it posts to, which leaves an unauthenticated visitor in a redirect +# loop. Note that shiroFilter is mapped for FORWARD as well as REQUEST, so the +# JSPs the Struts actions forward to must be listed too, not just the actions. +# ----------------------------------------------------------------------------- +[urls] +/index.jsp = anon +/login.action = anon +/authuser.action = anon +/pages/login.jsp = anon +/** = authc \ No newline at end of file diff --git a/shiro-basic/src/main/webapp/WEB-INF/web.xml b/shiro-basic/src/main/webapp/WEB-INF/web.xml index 7cfbe3ef..4bad1e46 100644 --- a/shiro-basic/src/main/webapp/WEB-INF/web.xml +++ b/shiro-basic/src/main/webapp/WEB-INF/web.xml @@ -4,6 +4,14 @@ xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd" version="6.0"> struts2shiro + + + + COOKIE + + org.apache.shiro.web.env.EnvironmentLoaderListener