У меня проблема с перенаправлением безопасности Spring на страницу входа, если пользователь не аутентифицирован. Я попытался отладить код безопасности Spring, и он отлично работает (перенаправление отправлено на login.jsp), но ничего не произошло. Я пытался установить в authenticationEntryPoint, но пересылка также не работает. Похоже, переадресация и перенаправление игнорируются GAE, так как тот же код отлично работает на Tomcat.
XML:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
default-autowire="byName">
<import resource="classpath:applicationContext-security.xml"/>
<context:component-scan base-package="ru.ncideas.magazinof.gwt"/>
<aop:aspectj-autoproxy/>
<security:global-method-security pre-post-annotations="disabled" secured-annotations="enabled"
jsr250-annotations="disabled"/>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="customAuthenticationProvider">
<security:password-encoder hash="md5">
</security:password-encoder>
</security:authentication-provider>
</security:authentication-manager>
<bean class="com.gwt.ss.GwtExceptionTranslator"/>
<bean class="com.gwt.ss.GwtUsernamePasswordAuthority">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<bean name="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/>
<bean id="webExpressionVoter"
class="org.springframework.security.web.access.expression.WebExpressionVoter"/>
</list>
</property>
</bean>
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/login.jsp"/>
</bean>
<bean id="accessDeniedHandler"
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/accessDenied.jsp"/>
</bean>
<security:http
auto-config="true"
use-expressions="true"
access-decision-manager-ref="accessDecisionManager"
entry-point-ref="authenticationEntryPoint">
<security:intercept-url pattern="/**/login.jsp" access="permitAll()" requires-channel="any"/>
<security:intercept-url pattern="/App/**" access="isFullyAuthenticated()" requires-channel="any"/>
<security:intercept-url pattern="/**" access="isFullyAuthenticated()" requires-channel="any"/>
<security:form-login login-page="/login.jsp"
authentication-failure-url="/login.jsp?error=true"
default-target-url="/"
always-use-default-target="true"/>
<security:access-denied-handler ref="accessDeniedHandler"/>
<security:logout invalidate-session="true" logout-success-url="/login.jsp"/>
</security:http>
</beans>
И еще одна странная вещь - я получаю следующее сообщение об ошибке журнала на GAE:
07:54:21.111 [30085752@qtp-26953544-4] ERROR com.gwt.ss.GwtExceptionTranslator - Receive AuthorizationFailureEvent:Access is denied
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:71) ~[spring-security-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:204) ~[spring-security-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:106) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_27]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_27]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_27]
at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_27]
at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:100) ~[appengine-agentruntime.jar:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at com.gwt.ss.GwtExceptionTranslator.doFilter(GwtExceptionTranslator.java:49) ~[gwtsecurity-1.1.0.jar:1.1.0]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_27]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_27]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_27]
at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_27]
at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:100) ~[appengine-agentruntime.jar:na]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at $Proxy27.doFilter(Unknown Source) ~[na:na]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_27]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_27]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_27]
at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_27]
at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:100) ~[appengine-agentruntime.jar:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at com.gwt.ss.GwtUsernamePasswordAuthority.doFilter(GwtUsernamePasswordAuthority.java:166) ~[gwtsecurity-1.1.0.jar:1.1.0]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_27]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_27]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_27]
at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_27]
at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:100) ~[appengine-agentruntime.jar:na]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) ~[spring-aop-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at $Proxy26.doFilter(Unknown Source) ~[na:na]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.access.channel.ChannelProcessingFilter.doFilter(ChannelProcessingFilter.java:109) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168) ~[spring-security-web-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) ~[spring-web-3.0.6.RELEASE.jar:3.0.6.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) ~[spring-web-3.0.6.RELEASE.jar:3.0.6.RELEASE]
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) ~[na:na]
at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:35) ~[na:na]
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) ~[na:na]
at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:60) ~[na:na]
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) ~[na:na]
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) ~[appengine-api-1.0-sdk-1.5.5.jar:na]
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) ~[na:na]
at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:122) ~[na:na]
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) ~[na:na]
at com.google.appengine.tools.development.BackendServersFilter.doFilter(BackendServersFilter.java:97) ~[na:na]
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) ~[na:na]
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) ~[na:na]
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) ~[na:na]
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) ~[na:na]
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) ~[na:na]
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) ~[na:na]
at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:78) ~[na:na]
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) ~[na:na]
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:362) ~[na:na]
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) ~[na:na]
at org.mortbay.jetty.Server.handle(Server.java:326) ~[na:na]
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) ~[na:na]
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938) ~[na:na]
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755) ~[na:na]
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218) ~[na:na]
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) ~[na:na]
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409) ~[na:na]
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582) ~[na:na]
07:54:21.114 [30085752@qtp-26953544-4] ERROR com.gwt.ss.GwtResponseUtil - Encode GwtAuthenticationException(user is anonymous):Access is denied