This is an automated email from the ASF dual-hosted git repository. bdemers pushed a commit to branch 1.7.x in repository https://gitbox.apache.org/repos/asf/shiro.git
commit 6acaaee9bb3a27927b599c37fabaeb7dd6109403 Author: Brian Demers <[email protected]> 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 +++ .../AbstractShiroWebFilterConfiguration.java | 2 +- .../web/config/ShiroRequestMappingConfig.java | 31 +++++++++++++++ .../spring/web/config/ShiroWebConfiguration.java | 7 ++++ .../shiro/spring/web/ShiroUrlPathHelperTest.groovy | 46 ++++++++++++++++++++++ 12 files changed, 190 insertions(+), 10 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 943249e..40b3195 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/AbstractShiroWebFilterConfiguration.java b/support/spring/src/main/java/org/apache/shiro/spring/web/config/AbstractShiroWebFilterConfiguration.java index 11b961e..685d63d 100644 --- a/support/spring/src/main/java/org/apache/shiro/spring/web/config/AbstractShiroWebFilterConfiguration.java +++ b/support/spring/src/main/java/org/apache/shiro/spring/web/config/AbstractShiroWebFilterConfiguration.java @@ -40,7 +40,7 @@ public class AbstractShiroWebFilterConfiguration { @Autowired protected ShiroFilterChainDefinition shiroFilterChainDefinition; - @Autowired + @Autowired(required = false) protected Map<String, Filter> filterMap; @Value("#{ @environment['shiro.loginUrl'] ?: '/login.jsp' }") 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
