Hành vi mặc định của bộ xử lý kênh là gửi sendRedirect (chuyển hướng tạm thời bằng mã 302). Tôi cần phải thay đổi hành vi này để chuyển hướng vĩnh viễn (301) được thực hiện thay vì chuyển hướng 302. Tôi cố gắng để làm như sau:Ghi đè ChannelProcessingFilter bằng Spring Security 3.0.5 không hoạt động
Tạo một ChannelProcessingFilter tùy chỉnh bằng cách mở rộng ChannelProcessingFilter:
public class MyChannelProcessingFilter extends ChannelProcessingFilter{ //No implementation, I needed this to just make sure that a custom filter is created and I can configure it as a custom filter in the xml file. }
Tạo một EntryPoint tùy chỉnh bằng cách mở rộng AbstractRetryEntryPoint
public class RetryWithHttpsEntryPoint extends org.springframework.security.web.access.channel.AbstractRetryEntryPoint { private PortResolver portResolver = new PortResolverImpl(); private final String scheme ="https://"; /** The standard port for the scheme (80 for http, 443 for https) */ private final int standardPort = 443; public RetryWithHttpsEntryPoint() { super("https://", 443); } @Override public void commence(HttpServletRequest request, HttpServletResponse res) throws IOException, ServletException { String queryString = request.getQueryString(); String redirectUrl = request.getRequestURI() + ((queryString == null) ? "" : ("?" + queryString)); Integer currentPort = new Integer(portResolver.getServerPort(request)); Integer redirectPort = getMappedPort(currentPort); if (redirectPort != null) { boolean includePort = redirectPort.intValue() != standardPort; redirectUrl = scheme + request.getServerName() + ((includePort) ? (":" + redirectPort) : "") + redirectUrl; } if (logger.isDebugEnabled()) { logger.debug("Redirecting to: " + redirectUrl); } res.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); res.setHeader("Location", redirectUrl); res.setHeader("Connection", "close"); } protected Integer getMappedPort(Integer mapFromPort) { return getPortMapper().lookupHttpsPort(mapFromPort); } }
Configure cùng trong tệp applicationContext-security.xml. Tôi đặt các tập tin xml hoàn chỉnh cho các bạn tham khảo (loại bỏ những phần không cần thiết. Nếu bạn yêu cầu các bộ phận khác làm cho tôi biết)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:security="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.3.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <security:http auto-config="false" entry-point-ref="authenticationProcessingFilterEntryPoint" access-decision-manager-ref="accessDecisionManager" > <security:intercept-url pattern="/activ8/protectedCheckEligibility.html**" access="user" requires-channel="https"/> <security:intercept-url pattern="/siteMap.html" access="ROLE_ANONYMOUS,user,admin" requires-channel="http"/> <security:intercept-url pattern="/privacyPolicy.html" access="ROLE_ANONYMOUS,user,admin" requires-channel="http"/> <!-- other urls configured over here --> <security:intercept-url pattern="/*.jsp" access="ROLE_ANONYMOUS,admin,user" requires-channel="https"/> <security:intercept-url pattern="/**/*.html**" access="ROLE_ANONYMOUS,user,admin" requires-channel="https"/> <security:intercept-url pattern="/fb_activities.html**" access="parent" /> <security:remember-me key="appfuseRocks" /> <security:custom-filter position="SWITCH_USER_FILTER" ref="careSwitchUserProcessingFilter"/> <security:custom-filter position="FORM_LOGIN_FILTER" ref="myCustomAuthenticationProcessingFilter"/> <!-- configured the custom channel filter over here --> <security:custom-filter position="CHANNEL_FILTER" ref="myChannelProcessingFilter"/> </security:http> <bean id="myChannelProcessingFilter" class="com.my.webapp.filter.myChannelProcessingFilter"> <property name="channelDecisionManager" ref="channelDecisionManager" /> <property name="securityMetadataSource"> <security:filter-security-metadata-source path-type="ant"> <security:intercept-url pattern="/**" access="REQUIRES_INSECURE_CHANNEL" /> </security:filter-security-metadata-source> </property> </bean> <bean id="channelDecisionManager" class="org.springframework.security.web.access.channel.ChannelDecisionManagerImpl"> <property name="channelProcessors"> <list> <ref bean="secureChannelProcessor"/> </list> </property> </bean> <bean id="secureChannelProcessor" class="org.springframework.security.web.access.channel.SecureChannelProcessor"> <property name="entryPoint" ref="secureChannelEntryPoint"/> <!-- <property name="portMapper" ref="portMapper" /> --> <property name="secureKeyword" value="REQUIRES_SECURE_CHANNEL"/> </bean> <bean id="secureChannelEntryPoint" class="com.my.webapp.filter.RetryWithHttpsEntryPoint"/> <!-- lot of other configuratons... removed --> </beans>
Tôi nhận được lỗi sau khi tôi cố gắng chạy tomcat của tôi:
ERROR 2011-12-26 21:13:21,569 [ina].[localhost].[/]]: Exception sending context initialized event to listener instance of class com.kajeet.webapp.listener.StartupListener org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Filter beans '' and 'Root bean: class [org.springframework.security.web.access.channel.ChannelProcessingFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null' have the same 'order' value. When using custom filters, please make sure the positions do not conflict with default filters. Alternatively you can disable the default filters by removing the corresponding child elements from and avoiding the use of . Offending resource: ServletContext resource [/WEB-INF/applicationContext-security.xml] at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68) at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85) at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:72) at org.springframework.security.config.http.HttpSecurityBeanDefinitionParser.checkFilterChainOrder(HttpSecurityBeanDefinitionParser.java:196) at org.springframework.security.config.http.HttpSecurityBeanDefinitionParser.parse(HttpSecurityBeanDefinitionParser.java:132) at org.springframework.security.config.SecurityNamespaceHandler.parse(SecurityNamespaceHandler.java:86) at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1335) at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1325) at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:135) at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:93) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:493) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302) at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143) at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178) at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149) at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:124) at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:93) at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130) at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:467) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:397) at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47) at com.kajeet.webapp.listener.StartupListener.contextInitialized(StartupListener.java:51) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3764) at org.apache.catalina.core.StandardContext.start(StandardContext.java:4216) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:760) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:740) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:544) at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:920) at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:883) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492) at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1138) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311) at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:120) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1022) at org.apache.catalina.core.StandardHost.start(StandardHost.java:736) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014) at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443) at org.apache.catalina.core.StandardService.start(StandardService.java:448) at org.apache.catalina.core.StandardServer.start(StandardServer.java:700) at org.apache.catalina.startup.Catalina.start(Catalina.java:552) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:295) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:433)
Tôi cũng đã ghi đè các bộ lọc khác và không phàn nàn về các bộ lọc đó. Ứng dụng này đã chạy hoàn toàn tốt trước đây. Chúng tôi đã có yêu cầu bổ sung này và do đó tôi đã thêm bộ lọc mới và chạy vào các lỗi như vậy. Phương pháp thứ hai mà tôi đã thử chỉ là cấu hình ChannelProcessingFilter mặc định trong XML, vì trong Spring 3.0, các bộ lọc được tự động gọi, tôi đã ấn tượng rằng tôi có thể cấu hình chúng trong tệp XML và mùa xuân sẽ tự động tải chúng, nhưng nó không:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.3.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<security:http auto-config="false"
entry-point-ref="authenticationProcessingFilterEntryPoint"
access-decision-manager-ref="accessDecisionManager" >
<security:intercept-url pattern="/activ8/protectedCheckEligibility.html**" access="user" requires-channel="https"/>
<security:intercept-url pattern="/siteMap.html" access="ROLE_ANONYMOUS,user,admin" requires-channel="http"/>
<security:intercept-url pattern="/privacyPolicy.html" access="ROLE_ANONYMOUS,user,admin" requires-channel="http"/>
<!-- other urls configured over here -->
<security:intercept-url pattern="/*.jsp" access="ROLE_ANONYMOUS,admin,user" requires-channel="https"/>
<security:intercept-url pattern="/**/*.html**" access="ROLE_ANONYMOUS,user,admin" requires-channel="https"/>
<security:intercept-url pattern="/fb_activities.html**" access="parent" />
<security:remember-me key="appfuseRocks" />
<security:custom-filter position="SWITCH_USER_FILTER" ref="careSwitchUserProcessingFilter"/>
<security:custom-filter position="FORM_LOGIN_FILTER" ref="myCustomAuthenticationProcessingFilter"/>
</security:http>
<bean id="channelDecisionManager" class="org.springframework.security.securechannel.ChannelDecisionManagerImpl">
<property name="channelProcessors">
<list>
<ref bean="secureChannelProcessor"/>
<ref bean="insecureChannelProcessor"/>
</list>
</property>
</bean>
<bean id="secureChannelProcessor" class="org.springframework.security.web.access.channel.SecureChannelProcessor"/>
<bean id="insecureChannelProcessor" class="org.springframework.security.web.access.channel.InsecureChannelProcessor"/>
<!-- lot of other configuratons... removed -->
</beans>
Mọi trợ giúp sẽ được đánh giá cao. Tôi không phải là một chuyên gia mùa xuân, nhưng tôi đã làm một số công việc trên nó, một con trỏ hoặc hai chắc chắn có thể giúp tôi giải quyết vấn đề này. Cảm ơn bạn trước
On nghiên cứu thêm , Tôi đã biết rằng điều này không yêu cầu mở rộng ChannelProcessingFilter, vấn đề tôi tìm thấy là SecureChannelProce ssor được initailzed hai lần, một lần với các giá trị mặc định và lần thứ hai với các giá trị tùy chỉnh là một phần của XML. Khi áp dụng các quy tắc, nó chỉ sử dụng quy tắc với giá trị mặc định. Có vẻ như tôi đang thiếu một liên kết rất nhỏ ở đâu đó. –