diff --git a/web/src/main/java/org/apache/shiro/web/filter/PathMatchingFilter.java b/web/src/main/java/org/apache/shiro/web/filter/PathMatchingFilter.java index e507ad32d4..be1da71a54 100644 --- a/web/src/main/java/org/apache/shiro/web/filter/PathMatchingFilter.java +++ b/web/src/main/java/org/apache/shiro/web/filter/PathMatchingFilter.java @@ -123,10 +123,12 @@ protected String getPathWithinApplication(ServletRequest request) { */ protected boolean pathsMatch(String path, ServletRequest request) { String requestURI = getPathWithinApplication(request); - if (requestURI != null && requestURI.endsWith(DEFAULT_PATH_SEPARATOR)) { + if (requestURI != null && !DEFAULT_PATH_SEPARATOR.equals(requestURI) + && requestURI.endsWith(DEFAULT_PATH_SEPARATOR)) { requestURI = requestURI.substring(0, requestURI.length() - 1); } - if (path != null && path.endsWith(DEFAULT_PATH_SEPARATOR)) { + if (path != null && !DEFAULT_PATH_SEPARATOR.equals(path) + && path.endsWith(DEFAULT_PATH_SEPARATOR)) { path = path.substring(0, path.length() - 1); } log.trace("Attempting to match pattern '{}' with current requestURI '{}'...", path, Encode.forHtml(requestURI)); diff --git a/web/src/main/java/org/apache/shiro/web/filter/mgt/PathMatchingFilterChainResolver.java b/web/src/main/java/org/apache/shiro/web/filter/mgt/PathMatchingFilterChainResolver.java index 7adcda733f..c35ab9b290 100644 --- a/web/src/main/java/org/apache/shiro/web/filter/mgt/PathMatchingFilterChainResolver.java +++ b/web/src/main/java/org/apache/shiro/web/filter/mgt/PathMatchingFilterChainResolver.java @@ -105,7 +105,8 @@ public FilterChain getChain(ServletRequest request, ServletResponse response, Fi // in spring web, the requestURI "/resource/menus" ---- "resource/menus/" bose can access the resource // but the pathPattern match "/resource/menus" can not match "resource/menus/" // user can use requestURI + "/" to simply bypassed chain filter, to bypassed shiro protect - if(requestURI != null && requestURI.endsWith(DEFAULT_PATH_SEPARATOR)) { + if(requestURI != null && !DEFAULT_PATH_SEPARATOR.equals(requestURI) + && requestURI.endsWith(DEFAULT_PATH_SEPARATOR)) { requestURI = requestURI.substring(0, requestURI.length() - 1); } @@ -113,7 +114,8 @@ public FilterChain getChain(ServletRequest request, ServletResponse response, Fi //the 'chain names' in this implementation are actually path patterns defined by the user. We just use them //as the chain name for the FilterChainManager's requirements for (String pathPattern : filterChainManager.getChainNames()) { - if (pathPattern != null && pathPattern.endsWith(DEFAULT_PATH_SEPARATOR)) { + if (pathPattern != null && !DEFAULT_PATH_SEPARATOR.equals(pathPattern) + && pathPattern.endsWith(DEFAULT_PATH_SEPARATOR)) { pathPattern = pathPattern.substring(0, pathPattern.length() - 1); } diff --git a/web/src/test/java/org/apache/shiro/web/filter/PathMatchingFilterTest.java b/web/src/test/java/org/apache/shiro/web/filter/PathMatchingFilterTest.java index 116aaae7d4..c6e81d4139 100644 --- a/web/src/test/java/org/apache/shiro/web/filter/PathMatchingFilterTest.java +++ b/web/src/test/java/org/apache/shiro/web/filter/PathMatchingFilterTest.java @@ -121,6 +121,20 @@ public void testEnabled() throws Exception { verify(request); } + /** + * Test asserting SHIRO-742. + */ + @Test + public void testPathMatchEqualUrlSeparatorEnabled() { + expect(request.getContextPath()).andReturn(CONTEXT_PATH).anyTimes(); + expect(request.getRequestURI()).andReturn("/").anyTimes(); + replay(request); + + boolean matchEnabled = filter.pathsMatch("/", request); + assertTrue("PathMatch can match URL end with Separator", matchEnabled); + verify(request); + } + /** * Test asserting SHIRO-682. */ diff --git a/web/src/test/java/org/apache/shiro/web/filter/mgt/PathMatchingFilterChainResolverTest.java b/web/src/test/java/org/apache/shiro/web/filter/mgt/PathMatchingFilterChainResolverTest.java index 68a8fa2e00..758be4d1f3 100644 --- a/web/src/test/java/org/apache/shiro/web/filter/mgt/PathMatchingFilterChainResolverTest.java +++ b/web/src/test/java/org/apache/shiro/web/filter/mgt/PathMatchingFilterChainResolverTest.java @@ -186,6 +186,28 @@ public void testGetChain() { verify(request); } + /** + * Test asserting SHIRO-742. + */ + @Test + public void testGetChainEqualUrlSeparator() { + HttpServletRequest request = createNiceMock(HttpServletRequest.class); + HttpServletResponse response = createNiceMock(HttpServletResponse.class); + FilterChain chain = createNiceMock(FilterChain.class); + + //ensure at least one chain is defined: + resolver.getFilterChainManager().addToChain("/", "authcBasic"); + + expect(request.getAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE)).andReturn(null).anyTimes(); + expect(request.getContextPath()).andReturn(""); + expect(request.getRequestURI()).andReturn("/"); + replay(request); + + FilterChain resolved = resolver.getChain(request, response, chain); + assertNotNull(resolved); + verify(request); + } + /** * Test asserting SHIRO-682. */