You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by bd...@apache.org on 2020/11/04 15:48:11 UTC

[shiro] 01/03: Add ShiroUrlHelper and related Spring configuration

This is an automated email from the ASF dual-hosted git repository.

bdemers pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shiro.git

commit 16fc47ae44e330297ed24f080a20d211c2666667
Author: Brian Demers <bd...@apache.org>
AuthorDate: Thu Sep 10 18:08:47 2020 -0400

    Add ShiroUrlHelper and related Spring configuration
    
    and related tests
---
 .../samples/spring/config/ApplicationConfig.java   |  4 +-
 .../samples/spring/config/JspViewsConfig.java      |  4 +-
 .../autoconfigure/ShiroWebAutoConfiguration.java   | 10 +++++
 .../ShiroWebMvcAutoConfiguration.java              | 32 +++++++++++++++
 .../src/main/resources/META-INF/spring.factories   |  3 +-
 support/spring/pom.xml                             | 15 ++++---
 .../shiro/spring/web/ShiroUrlPathHelper.java       | 41 +++++++++++++++++++
 .../web/config/AbstractShiroWebConfiguration.java  |  5 +++
 .../web/config/ShiroRequestMappingConfig.java      | 31 +++++++++++++++
 .../spring/web/config/ShiroWebConfiguration.java   |  7 ++++
 .../shiro/spring/web/ShiroUrlPathHelperTest.groovy | 46 ++++++++++++++++++++++
 11 files changed, 189 insertions(+), 9 deletions(-)

diff --git a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/ApplicationConfig.java b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/ApplicationConfig.java
index 67a5cca..9c06eae 100644
--- a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/ApplicationConfig.java
+++ b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/ApplicationConfig.java
@@ -30,6 +30,7 @@ import org.apache.shiro.spring.config.ShiroBeanConfiguration;
 import org.apache.shiro.spring.remoting.SecureRemoteInvocationExecutor;
 import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
 import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
+import org.apache.shiro.spring.web.config.ShiroRequestMappingConfig;
 import org.apache.shiro.spring.web.config.ShiroWebConfiguration;
 import org.apache.shiro.spring.web.config.ShiroWebFilterConfiguration;
 import org.springframework.context.annotation.Bean;
@@ -53,7 +54,8 @@ import static org.apache.shiro.web.filter.mgt.DefaultFilter.anon;
         ShiroWebConfiguration.class,
         ShiroWebFilterConfiguration.class,
         JspViewsConfig.class,
-        RemotingServletConfig.class})
+        RemotingServletConfig.class,
+        ShiroRequestMappingConfig.class})
 @ComponentScan("org.apache.shiro.samples.spring")
 public class ApplicationConfig {
 
diff --git a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/JspViewsConfig.java b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/JspViewsConfig.java
index 551089c..34f9912 100644
--- a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/JspViewsConfig.java
+++ b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/JspViewsConfig.java
@@ -25,7 +25,7 @@ import org.springframework.core.annotation.Order;
 import org.springframework.web.servlet.ViewResolver;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 import org.springframework.web.servlet.view.InternalResourceViewResolver;
 import org.springframework.web.servlet.view.JstlView;
 
@@ -35,7 +35,7 @@ import org.springframework.web.servlet.view.JstlView;
 @Configuration
 @ComponentScan("org.apache.shiro.samples.spring")
 @EnableWebMvc
-public class JspViewsConfig extends WebMvcConfigurerAdapter {
+public class JspViewsConfig implements WebMvcConfigurer {
 
     @Bean
     @Order(1)
diff --git a/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroWebAutoConfiguration.java b/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroWebAutoConfiguration.java
index 4ab440c..3b89b63 100644
--- a/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroWebAutoConfiguration.java
+++ b/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroWebAutoConfiguration.java
@@ -33,9 +33,11 @@ import org.apache.shiro.session.mgt.SessionFactory;
 import org.apache.shiro.session.mgt.SessionManager;
 import org.apache.shiro.session.mgt.eis.SessionDAO;
 import org.apache.shiro.spring.boot.autoconfigure.ShiroAutoConfiguration;
+import org.apache.shiro.spring.web.ShiroUrlPathHelper;
 import org.apache.shiro.spring.web.config.AbstractShiroWebConfiguration;
 import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
 import org.apache.shiro.web.servlet.Cookie;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
 import org.springframework.boot.autoconfigure.AutoConfigureBefore;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -47,6 +49,7 @@ import org.springframework.context.annotation.Configuration;
  */
 @Configuration
 @AutoConfigureBefore(ShiroAutoConfiguration.class)
+@AutoConfigureAfter(ShiroWebMvcAutoConfiguration.class)
 @ConditionalOnProperty(name = "shiro.web.enabled", matchIfMissing = true)
 public class ShiroWebAutoConfiguration extends AbstractShiroWebConfiguration {
 
@@ -147,4 +150,11 @@ public class ShiroWebAutoConfiguration extends AbstractShiroWebConfiguration {
     protected ShiroFilterChainDefinition shiroFilterChainDefinition() {
         return super.shiroFilterChainDefinition();
     }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected ShiroUrlPathHelper shiroUrlPathHelper() {
+        return super.shiroUrlPathHelper();
+    }
 }
diff --git a/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroWebMvcAutoConfiguration.java b/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroWebMvcAutoConfiguration.java
new file mode 100644
index 0000000..26fdeb7
--- /dev/null
+++ b/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroWebMvcAutoConfiguration.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shiro.spring.config.web.autoconfigure;
+
+import org.apache.shiro.spring.web.config.ShiroRequestMappingConfig;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+
+@Configuration
+@ConditionalOnClass(RequestMappingHandlerMapping.class)
+@Import(ShiroRequestMappingConfig.class)
+@ConditionalOnProperty(name = "shiro.web.enabled", matchIfMissing = true)
+public class ShiroWebMvcAutoConfiguration { }
diff --git a/support/spring-boot/spring-boot-web-starter/src/main/resources/META-INF/spring.factories b/support/spring-boot/spring-boot-web-starter/src/main/resources/META-INF/spring.factories
index b69324a..328062d 100644
--- a/support/spring-boot/spring-boot-web-starter/src/main/resources/META-INF/spring.factories
+++ b/support/spring-boot/spring-boot-web-starter/src/main/resources/META-INF/spring.factories
@@ -1,3 +1,4 @@
 org.springframework.boot.autoconfigure.EnableAutoConfiguration = \
   org.apache.shiro.spring.config.web.autoconfigure.ShiroWebAutoConfiguration,\
-  org.apache.shiro.spring.config.web.autoconfigure.ShiroWebFilterConfiguration
+  org.apache.shiro.spring.config.web.autoconfigure.ShiroWebFilterConfiguration, \
+  org.apache.shiro.spring.config.web.autoconfigure.ShiroWebMvcAutoConfiguration
diff --git a/support/spring/pom.xml b/support/spring/pom.xml
index 254373f..78d8b65 100644
--- a/support/spring/pom.xml
+++ b/support/spring/pom.xml
@@ -50,6 +50,16 @@
             <artifactId>spring-context</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <optional>true</optional>
+        </dependency>
         <!-- Test dependencies -->
         <dependency>
             <groupId>org.slf4j</groupId>
@@ -72,11 +82,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-web</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>org.apache.shiro</groupId>
             <artifactId>shiro-aspectj</artifactId>
             <scope>test</scope>
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/web/ShiroUrlPathHelper.java b/support/spring/src/main/java/org/apache/shiro/spring/web/ShiroUrlPathHelper.java
new file mode 100644
index 0000000..4b5ddbd
--- /dev/null
+++ b/support/spring/src/main/java/org/apache/shiro/spring/web/ShiroUrlPathHelper.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shiro.spring.web;
+
+import org.apache.shiro.web.util.WebUtils;
+import org.springframework.web.util.UrlPathHelper;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * A Spring UrlPathHelper that uses Shiro's path resolution logic.
+ * @since 1.7.0
+ */
+public class ShiroUrlPathHelper extends UrlPathHelper {
+
+    @Override
+    public String getPathWithinApplication(HttpServletRequest request) {
+        return WebUtils.getPathWithinApplication(request);
+    }
+
+    @Override
+    public String getPathWithinServletMapping(HttpServletRequest request) {
+        return WebUtils.getPathWithinApplication(request);
+    }
+}
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/web/config/AbstractShiroWebConfiguration.java b/support/spring/src/main/java/org/apache/shiro/spring/web/config/AbstractShiroWebConfiguration.java
index ae2afb5..5ed98d8 100644
--- a/support/spring/src/main/java/org/apache/shiro/spring/web/config/AbstractShiroWebConfiguration.java
+++ b/support/spring/src/main/java/org/apache/shiro/spring/web/config/AbstractShiroWebConfiguration.java
@@ -24,6 +24,7 @@ import org.apache.shiro.mgt.SessionsSecurityManager;
 import org.apache.shiro.mgt.SubjectFactory;
 import org.apache.shiro.session.mgt.SessionManager;
 import org.apache.shiro.spring.config.AbstractShiroConfiguration;
+import org.apache.shiro.spring.web.ShiroUrlPathHelper;
 import org.apache.shiro.web.mgt.CookieRememberMeManager;
 import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
 import org.apache.shiro.web.mgt.DefaultWebSessionStorageEvaluator;
@@ -181,4 +182,8 @@ public class AbstractShiroWebConfiguration extends AbstractShiroConfiguration {
         chainDefinition.addPathDefinition("/**", "authc");
         return chainDefinition;
     }
+
+    protected ShiroUrlPathHelper shiroUrlPathHelper() {
+        return new ShiroUrlPathHelper();
+    }
 }
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroRequestMappingConfig.java b/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroRequestMappingConfig.java
new file mode 100644
index 0000000..317cb4d
--- /dev/null
+++ b/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroRequestMappingConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shiro.spring.web.config;
+
+import org.apache.shiro.spring.web.ShiroUrlPathHelper;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+
+@Configuration
+public class ShiroRequestMappingConfig {
+
+    public ShiroRequestMappingConfig(RequestMappingHandlerMapping requestMappingHandlerMapping) {
+        requestMappingHandlerMapping.setUrlPathHelper(new ShiroUrlPathHelper());
+    }
+}
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebConfiguration.java b/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebConfiguration.java
index dc57b22..952a26a 100644
--- a/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebConfiguration.java
+++ b/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebConfiguration.java
@@ -26,6 +26,7 @@ import org.apache.shiro.realm.Realm;
 import org.apache.shiro.session.mgt.SessionFactory;
 import org.apache.shiro.session.mgt.SessionManager;
 import org.apache.shiro.session.mgt.eis.SessionDAO;
+import org.apache.shiro.spring.web.ShiroUrlPathHelper;
 import org.apache.shiro.web.servlet.Cookie;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -122,4 +123,10 @@ public class ShiroWebConfiguration extends AbstractShiroWebConfiguration {
     protected ShiroFilterChainDefinition shiroFilterChainDefinition() {
         return super.shiroFilterChainDefinition();
     }
+
+    @Bean
+    @Override
+    protected ShiroUrlPathHelper shiroUrlPathHelper() {
+        return super.shiroUrlPathHelper();
+    }
 }
diff --git a/support/spring/src/test/groovy/org/apache/shiro/spring/web/ShiroUrlPathHelperTest.groovy b/support/spring/src/test/groovy/org/apache/shiro/spring/web/ShiroUrlPathHelperTest.groovy
new file mode 100644
index 0000000..08eeb79
--- /dev/null
+++ b/support/spring/src/test/groovy/org/apache/shiro/spring/web/ShiroUrlPathHelperTest.groovy
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shiro.spring.web
+
+import org.junit.Test
+import org.springframework.mock.web.MockHttpServletRequest
+import org.springframework.web.util.UrlPathHelper
+
+import static org.hamcrest.MatcherAssert.assertThat
+import static org.hamcrest.Matchers.equalTo
+
+/**
+ * Tests a couple known differences between the stock and the ShiroUrlPathHelper
+ */
+class ShiroUrlPathHelperTest {
+
+    @Test
+    void testGetPathWithinApplication() {
+        MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo/%2e%2e")
+        assertThat new UrlPathHelper().getPathWithinApplication(request), equalTo("/foo/..")
+        assertThat new ShiroUrlPathHelper().getPathWithinApplication(request), equalTo("/")
+    }
+
+    @Test
+    void testGetPathWithinServletMapping() {
+        MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo/%2e%2e")
+        assertThat new UrlPathHelper().getPathWithinServletMapping(request), equalTo("/foo/..")
+        assertThat new ShiroUrlPathHelper().getPathWithinServletMapping(request), equalTo("/")
+    }
+}
\ No newline at end of file