I'm trying to implement a Rest web service with Jersey, Spring and Spring security (3.2.5).
I want the server to require the basic auth header for the request to the rest web service. If authentication succeeds, then jersey should handle the request. If it fails, I want to return an empty response with the status 403.
Currently my configuration is the following:
<bean id="myAuthenticationEntryPoint"
class="de.tuberlin.snet.baroudeur.Authentication.EntryPoint" />
<!-- HTTP basic authentication in Spring Security -->
<security:http create-session="stateless" auto-config="false"
disable-url-rewriting="true" entry-point-ref="myAuthenticationEntryPoint">
<security:intercept-url pattern="**" access="ROLE_USER" />
<security:http-basic />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="username" password="password"
authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
and my EntryPoint:
public class EntryPoint extends BasicAuthenticationEntryPoint {
public void commence(ServletRequest request, ServletResponse response,
AuthenticationException authException) throws IOException,
ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
}
}
I tried a lot of things, like custom AuthenticationFailureHandler, or custom EntryPoint but nothing has worked so far.
Thanks
Edit:
My current solution only returns a 401 response with the basic tomcat templates and the browser asks for the user credentials.
When using the debugging mode, it seems that the commence() method of my custom entry point is never called, why is that?
Related
I'm using spring security in a tomcat server. How can I change the default session timeout ?
I've tried modifying the web.xml with:
<session-config>
<session-timeout>1</session-timeout>
</session-config>
This does not seem to work.
I also read that spring boot uses the parameter server.servlet.session.timeout, but I don't use spring boot.
Keep in mind that this values is in seconds
<session-config>
<session-timeout>1</session-timeout>
</session-config>
And this value will be rounded to the minutes.
If server does not receive any requests from e.g you GUI, It will wait at least 1 min and then expire session.
Different ways to configure session timeout time(maxInactiveInterval) in spring security.
By addinng session config in web.xml
By creating implementation of HttpSessionListener and adding it to servlet context.(from munilvc's answer)
By registering your custom AuthenticationSuccessHandler in spring security configuration, and setting session maximum inactive interval
in onAuthenticationSuccess method.
This implementation has advantages
On login success, You can set different value of maxInactiveInterval for different roles/users.
On login success, you can set user object in session, hence user object can be accessed in any controller from session.
Disadvantage: You can not set session timeout for ANONYMOUS user(Un-authenticated user)
Create AuthenticationSuccessHandler Handler
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler{
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException
{
Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
if (roles.contains("ROLE_ADMIN"))
{
request.getSession(false).setMaxInactiveInterval(60);
}
else
{
request.getSession(false).setMaxInactiveInterval(120);
}
//Your login success url goes here, currently login success url="/"
response.sendRedirect(request.getContextPath());
}
}
Register success handler
In Java Config way
#Override
protected void configure(final HttpSecurity http) throws Exception
{
http
.authorizeRequests()
.antMatchers("/resources/**", "/login").permitAll()
.antMatchers("/app/admin/*").hasRole("ADMIN")
.antMatchers("/app/user/*", "/").hasAnyRole("ADMIN", "USER")
.and().exceptionHandling().accessDeniedPage("/403")
.and().formLogin()
.loginPage("/login").usernameParameter("userName")
.passwordParameter("password")
.successHandler(new MyAuthenticationSuccessHandler())
.failureUrl("/login?error=true")
.and().logout()
.logoutSuccessHandler(new CustomLogoutSuccessHandler())
.invalidateHttpSession(true)
.and().csrf().disable();
http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired=true");
}
In xml config way
<http auto-config="true" use-expressions="true" create-session="ifRequired">
<csrf disabled="true"/>
<intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/app/admin/*" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />
<intercept-url pattern="/app/user/*" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />
<access-denied-handler error-page="/403" />
<form-login
login-page="/login"
authentication-success-handler-ref="authenticationSuccessHandler"
authentication-failure-url="/login?error=true"
username-parameter="userName"
password-parameter="password" />
<logout invalidate-session="false" success-handler-ref="customLogoutSuccessHandler"/>
<session-management invalid-session-url="/login?expired=true">
<concurrency-control max-sessions="1" />
</session-management>
</http>
<beans:bean id="authenticationSuccessHandler" class="com.pvn.mvctiles.configuration.MyAuthenticationSuccessHandler" />
I have exposed some webservices in a RESTful manner. In my first form user needs to login and login credentials is sent in Authorization header in the following manner:
Authorization :Basic adajajffjfksal
Now in my security-context.xml I have secured the URL in the following way:
<http pattern="/login" create-session="stateless">
<intercept-url pattern="/**" access="ROLE_AUTHENTICATED" />
<http-basic />
</http>
After successful login I have another form from which some paramaters will be passed to the server on behalf of the User. Will session be created? Do I have to pass user credentials in Authorization header again? Will this login request be sessionless due to 'create-session="stateless"'?
This piece of security-context.xml has little sense if any
<http pattern="/login" create-session="stateless">
<intercept-url pattern="/**" access="ROLE_AUTHENTICATED" />
<http-basic />
</http>
It contains pattern="/login", so the whole block is only considered by spring security for the sole url /login. In other words it is ignored for any other urls.
It contains create-session="stateless", so it will not create any session.
The result is that if you explicitely call /login URL with proper basic authentication headers, you will be successfully authenticated and the session will immediately be closed. So you will not be authenticated for following requests.
My question is quite simple "Can have any problems when using Spring security and GWT RPC ?" .
I would like to use spring's method level security on GWT's RPC methods.For instance : at my ServiceImpl class , I used Expression-Based Access Control as below.
#PreAuthorize("hasRole('ROLE_ADMIN')")
public final String getById(Long id) {
.........
}
If un-authorize role access users trying to access page dealing with this rpc method , exception was thrown and don't redirect to my access-denied page. I have no idea why doesn't go to my access-denied page ? I got an exception at my console as
threw an unexpected exception: org.springframework.security.access.AccessDeniedException: Access is denied
I configured as this answer exactly but still getting above error.Please correct me if I am wrong "I think this problem may due to gwt's RPC" because non-rpc methods were fine and redirect to my unSecure.html . I spend about 3 days for this error . At onFailure(Throwable caught) of my asynchronous method show
500 The call failed on the server; see server log for details
I want to show my configurations .
spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:sec="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<sec:global-method-security
secured-annotations="enabled" pre-post-annotations="enabled" />
<sec:http auto-config="false" entry-point-ref="authenticateFilterEntryPoint">
<sec:access-denied-handler ref="accessDeniedHandler" />
<sec:intercept-url pattern="/login.html" />
<sec:logout logout-url="/logout.html" logout-success-url="/login.html"
invalidate-session="true" />
<sec:form-login login-page="/login.html"
login-processing-url="/login_check" authentication-failure-url="/login.html?error=1" />
<sec:session-management invalid-session-url="/login.html">
<sec:concurrency-control max-sessions="50"
error-if-maximum-exceeded="true" />
</sec:session-management>
<sec:remember-me key="mykey"
token-validity-seconds="604800" />
</sec:http>
<beans:bean id="authenticateFilterEntryPoint"
class="mypackage.common.security.SessionTimeoutEntryPoint">
<beans:property name="loginFormUrl" value="/login.html" />
</beans:bean>
<beans:bean id="accessDeniedHandler"
class="mypackage.common.security.AccessDeniedEntryPoint">
<beans:property name="errorPage" value="/unSecure.html" />
</beans:bean>
<beans:bean
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<beans:property name="defaultErrorView" value="uncaughtException" />
<beans:property name="excludedExceptions"
value="org.springframework.security.access.AccessDeniedException" />
<beans:property name="exceptionMappings">
<beans:props>
<beans:prop key=".DataAccessException">dataAccessFailure</beans:prop>
<beans:prop key=".NoSuchRequestHandlingMethodException">resourceNotFound</beans:prop>
<beans:prop key=".TypeMismatchException">resourceNotFound</beans:prop>
<beans:prop key=".MissingServletRequestParameterException">resourceNotFound</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="authenticationUserService"
class="mypackage.common.security.AuthenticationUserService" />
<sec:authentication-manager>
<sec:authentication-provider
user-service-ref="authenticationUserService">
<sec:password-encoder hash="md5" />
</sec:authentication-provider>
</sec:authentication-manager>
<beans:bean id="authLoggerListener"
class="org.springframework.security.authentication.event.LoggerListener" />
<beans:bean id="eventLoggerListener"
class="org.springframework.security.access.event.LoggerListener" />
AccessDeniedEntryPoint.java
public class AccessDeniedEntryPoint extends org.springframework.security.web.access.AccessDeniedHandlerImpl {
private static final Logger logger = LoggerFactory.getLogger(AccessDeniedEntryPoint.class);
#Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
super.handle(request, response, accessDeniedException);
}
}
SessionTimeoutEntryPoint.java
public class SessionTimeoutEntryPoint extends LoginUrlAuthenticationEntryPoint {
#Override
public final void commence(final HttpServletRequest request, final HttpServletResponse response,
final AuthenticationException authException) throws IOException, ServletException {
super.commence(request, response, authException);
}
}
So , I would like to get unSecure.html when un-authorize role users access this method. I would really appreciated any of your suggestions. Sorry for my long question. I don't want to hit my head anymore ! Thanks.
As in my last response, I used this long time ago. In my case instead of dealing always with urls I delegated into handlers.
I mean, if you want to integrate GWT-RPC with Spring-Security, the first thing that I did, was from my GWT app try to login against Spring.
So the first thing that you need to do is create a RPC-CALL (here official documentation) for login.
I found useful the annotation #RemoteServiceRelativePath("examplelogin.rpc"), so if you use it you can take advantage about the path, and then, in the spring-security.xml you can filter the request by those path (see the updated example below).
Not sure why you want to integrate GWT-RPC with Spring-Security and then you specify /login.html (should it be a rpc call, described befored instead of html? But maybe you are using your own MVP with GWT, so I am not saying that is wrong, only it surprises me :) ).
Reading your code I do not see something wrong, but in my case I have some differences:
....
<http use-expressions="true" entry-point-ref="http401UnauthorizedEntryPoint">
<intercept-url pattern="/yourProject/public.rpc" access="permitAll" />
<intercept-url pattern="/yourProject/examplelogin.rpc" access="hasRole('ROLE_ADMIN')" />
<form-login authentication-success-handler-ref="authenticationSuccessHandler"
authentication-failure-handler-ref="authenticationFailureHandler"/>
..... //logout, session-management, custom-filters....
<beans:bean id="http401UnauthorizedEntryPoint"
class="your.project.Http401UnauthorizedEntryPoint" />
<beans:bean id="authenticationSuccessHandler"
class="your.project.GWTAuthenticationSuccessHandler"/>
<beans:bean id="authenticationFailureHandler"
class="your.project.GWTAuthenticationFailureHandler"/>
</http>
....
You asked specifically about the possibility of using Spring-Security with GWT-RPC (that is the reason because in the <intercept-url> tags I place there the .rpc urls)
Note that the
The answer is yes, I have done it (three years ago, but I did :) )
I think here the keys for your problem are:
Specify the interceptor url for the RPC calls or your /login.html
Delegate on handlers like I did (be careful maybe you are doing well
and the error is in other part, but at least I did like in the example and it
worked).
Sorry for not showing you directly the error, I hope this answers will help.
Thanks.
I have implemented spring-security in my application, my spring-security.xml has following form-login tag.
<form-login login-page="/login.htm" default-target-url="/dashboard.htm"
authentication-failure-url="/login.htm?error=true"
authentication-success-handler-ref="authenticationSuccessHandler" />
I want to login from /login.htm and after successful authetication I want user to hit dashboard.htm. Everythig is working fine except for the fact that after successfull authetication it doesn't hit /dashboard.htm but hits the context..but if I manually type dashboard.htm in url then everything works fine...Yes..I have the implementation of authticationSuccessHandler.
Try removing the default-target-url attribute and add the following:
<b:bean id="authenticationSuccessHandler" class="com.example.CustomSimpleURLAuthenticationSuccessHandler">
<b:property name="defaultTargetUrl" value="/dashboard.htm"/>
</b:bean>
<beans:bean id="loginSuccessHandler" class="com.example.LoginSuccessHandler">
<beans:property name="defaultTargetUrl" value="/security/success"/>
<beans:property name="alwaysUseDefaultTargetUrl" value="true"/>
</beans:bean>
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
request.getSession().setMaxInactiveInterval(60 * 60); //one hour
System.out.println("Session set up for 60min");
super.onAuthenticationSuccess(request, response, authentication);
}
}
I use this suggestion from the question spring is not redirecting to default target url?. I tried this and it is working.
<form-login login-page="/login.htm"
default-target-url="/dashboard.htm"
always-use-default-target="true"/>
As you can see in the image, there is some kind of bad design (IMO It always redirect to the default-target-url).
When you go to the login form from a forbidden resource, it will redirect you to that URL and not going thru the default-target-url
http://i.stack.imgur.com/fj9ou.png
I have a spring 3 application with the configurations given below. When any user tries to access a page and he/she isn't logged in, I get an Access is Denied exception with an ugly stack trace. How do I handle this exception and not let it dump out a stack trace. I implemented my own access-denied-handler but that doesn't get invoked.
Based on the type of the requested resource, I would like to show custom error messages or pages. Here is my spring configuration.
How do I get Spring to invoke my access-denied-handler . Here is my spring configuration
<security:http auto-config='true'>
<security:intercept-url pattern="/static/**" filters="none"/>
<security:intercept-url pattern="/login" filters="none"/>
<security:intercept-url pattern="/**" access="ROLE_USER" />
<security:form-login login-page="/index"
default-target-url="/home" always-use-default-target="true"
authentication-success-handler-ref="AuthenticationSuccessHandler"
login-processing-url="/j_spring_security_check"
authentication-failure-url="/index?error=true"/>
<security:remember-me key="myLongSecretCookieKey" token-validity-seconds="1296000"
data-source-ref="jdbcDataSource" user-service-ref="AppUserDetailsService" />
<security:access-denied-handler ref="myAccessDeniedHandler" />
</security:http>
<bean id="myAccessDeniedHandler"
class="web.exceptions.handlers.AccessDeniedExceptionHandler">
<property name="errorPage" value="/public/403.htm" />
</bean>
The custom class for handling this exception is given below
public class AccessDeniedExceptionHandler implements AccessDeniedHandler
{
private String errorPage;
#Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException arg2) throws IOException, ServletException {
response.sendRedirect(errorPage);
}
public void setErrorPage(String errorPage) {
if ((errorPage != null) && !errorPage.startsWith("/")) {
throw new IllegalArgumentException("errorPage must begin with '/'");
}
this.errorPage = errorPage;
}
}
When I run this application, this is the error that I get. I am only pasting a part of the stacktrace and the Spring Debug logs.
20:39:46,173 DEBUG AffirmativeBased:53 - Voter: org.springframework.security.access.vote.RoleVoter#5b7da0d1, returned: -1
20:39:46,173 DEBUG AffirmativeBased:53 - Voter: org.springframework.security.access.vote.AuthenticatedVoter#14c92844, returned: 0
20:39:46,178 DEBUG ExceptionTranslationFilter:154 - Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:71)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:204)
How do I fix this problem? Firstly, I want to stop spring from Throwing that exception. If it still throws it, I want to handle it and not raise any flags.
Update: I have attached a part of my web.xml as well.
<!-- Hibernate filter configuration -->
<filter>
<filter-name>HibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--Dispatcher Servlet -->
<servlet>
<servlet-name>rowz</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
In your configuration You require the user to be always authenticated when entering any URL on Your site:
<security:intercept-url pattern="/**" access="ROLE_USER" />
I think You should allow the user to be unauthenticated when entering the login page:
<security:intercept-url pattern="/your-login-page-url" access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/your-login-process-url" access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/your-login-failure-url" access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/**" access="ROLE_USER" />
If You use URL's like: /login/start, /login/error and /login/failure You can have:
<security:intercept-url pattern="/login/**" access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/**" access="ROLE_USER" />
Update:
Having this configuration should make the framework to redirect all unauthenticated (anonymous) users to login page, and all authenticated to AccessDeniedHandler. The AccessDeniedException is one of the core parts of the framework and ignoring it is not a good idea. It's hard to help more if You only provide parts of Your Spring Security configuration.
Be sure to read the JavaDoc for ExceptionTranslationFilter for detailed explanation of what exceptions are thrown by the framework, why and how are the handled by default.
If possible, try removing as many custom parts You added, like AuthenticationSuccessHandler, RememberMeAuthenticationFilter and AccessDeniedHandler and see if the problem pesist? Try to get the minimal congiuration and add new features step by step to see where the error comes from.
One important thing that You don't mention in Your question is what is the result of this error message? Do You get HTTP 500? Or HTTP 403? Or do You get redirected to login page?
If, as You mentioned in the question, the user is unauthenticated and he/she gets redirected to login page, than that's how it's intended to work. It looks like You get the error message logged by ExceptionTranslationFilter:172 only because You have DEBUG level set to Spring Security classes. If so, than that's also how it's intended to work, and if You don't want the error logged, than simply rise the logging level for Spring Secyruty classes.
Update 2:
The patterns with filters="none" must match the login-page, login-processing-url and authentication-failure-ur attributes set in <security:form-login /> to skip all SpringSecurity checks on pages that display the login page and process the logging in.
<security:http auto-config='true'>
<security:intercept-url pattern="/static/**" filters="none"/>
<security:intercept-url pattern="/index" filters="none"/>
<security:intercept-url pattern="/j_spring_security_check" filters="none"/>
<security:intercept-url pattern="/**" access="ROLE_USER" />
<security:form-login login-page="/index"
default-target-url="/home" always-use-default-target="true"
authentication-success-handler-ref="AuthenticationSuccessHandler"
login-processing-url="/j_spring_security_check"
authentication-failure-url="/index?error=true"/>
<security:remember-me key="myLongSecretCookieKey" token-validity-seconds="1296000"
data-source-ref="jdbcDataSource" user-service-ref="AppUserDetailsService" />
<security:access-denied-handler ref="myAccessDeniedHandler" />
</security:http>
AccessDeniedHandler is invoked when user is logged in and there is no permissions to resource (source here). If you want to handle request for login page when user is not logged in, just configure in security-context:
<http ... entry-point-ref="customAuthenticationEntryPoint">
And define customAuthenticationEntryPoint:
<beans:bean id="customAuthenticationEntryPoint" class="pl.wsiadamy.webapp.controller.util.CustomAuthenticationEntryPoint">
</beans:bean>
TIP, don't try to fight with ExceptionTranslationFilter.
I have tried to override org.springframework.security.web.access.ExceptionTranslationFilter, without effects:
<beans:bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
<beans:property name="authenticationEntryPoint" ref="customAuthenticationEntryPoint"/>
<beans:property name="accessDeniedHandler" ref="accessDeniedHandler"/>
</beans:bean>
<beans:bean id="accessDeniedHandler"
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<beans:property name="errorPage" value="/accessDenied.htm"/>
</beans:bean>
The ref="customAuthenticationEntryPoint" just didn't invoked.
I have added Spring Access denied page in follwing way:
Spring Frame Work: 3.1
Spring Security: 3.1, Java 1.5+
Entry in *-security.xml:
<security:access-denied-handler error-page="/<My Any error page controller name>" />
Example:
<security:access-denied-handler error-page="/accessDeniedPage.htm" />
Error page will always start with "/"
Entry for controller:
#Controller
public class RedirectAccessDenied {
#RequestMapping(value = "/accessDeniedPage.htm", method = RequestMethod.GET)
public String redirectAccessDenied(Model model) throws IOException, ServletException {
System.out.println("############### Redirect Access Denied Handler!");
return "403";
}
}
Here 403 is my JSP name.
Spring Security uses an AuthenticationEntryPoint object to decide what to do when a user requires authentication. You can create your own AuthenticationEntryPoint bean ( see javadoc ), and then set the entryPoint attribute in the http element:
<http entry-point-ref="entryPointBean" .... />
However, by default, the form-login element creates a LoginUrlAuthenticationEntryPoint which redirects all of your unauthenticated users to the login page, so you shouldn't have to do this yourself. In fact, the log you posted claims it is forwarding the user to the authentication entry point: "Access is denied (user is anonymous); redirecting to authentication entry point".
I wonder if the problem is that you turned off the filter chain for the login url. Instead of setting filters to none, which means spring security is bypassed entirely, try keeping the filters on but allowing unrestricted access like this:
<security:intercept-url pattern="/login" access="permitAll" />
If that still doesn't help, please post the rest of the log so we can see what happens after the request is transferred to the entry point.
Programmatically solution:
#Order(1)
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//
// ...
//
#Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandlerImpl() {
#Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
super.handle(request, response, accessDeniedException);
accessDeniedException.printStackTrace();
}
});
//
// ...
//
}
}
Can you check your web.xml is supporting forward request?
errorPage is a FORWARD request and mostly in web.xml we support REDIRECTS only. Just a thought else your code looks ok to me.
Edited
A different point of view and This is been taken from working code only.
Have a look at Authenticated Voter class
Disable the annotations
<global-method-security pre-post-annotations="disabled"
secured-annotations="disabled" access-decision-manager-ref="accessDecisionManager">
</global-method-security>
bypassing filters
<http auto-config="true" use-expressions="true"
access-decision-manager-ref="accessDecisionManager"
access-denied-page="/accessDenied">
<intercept-url pattern="/appsecurity/login.jsp" filters="none" />
<intercept-url pattern="/changePassword" filters="none" />
<intercept-url pattern="/pageNotFound" filters="none" />
<intercept-url pattern="/accessDenied" filters="none" />
<intercept-url pattern="/forgotPassword" filters="none" />
<intercept-url pattern="/**" filters="none" />
<form-login login-processing-url="/j_spring_security_check"
default-target-url="/home" login-page="/loginDetails"
authentication-failure-handler-ref="authenticationExceptionHandler"
authentication-failure-url="/?login_error=t" />
<logout logout-url="/j_spring_security_logout"
invalidate-session="true" logout-success-url="/" />
<remember-me />
<!-- Uncomment to limit the number of sessions a user can have -->
<session-management invalid-session-url="/">
<concurrency-control max-sessions="1"
error-if-maximum-exceeded="true" />
</session-management>
</http>
custom Decision Voter
<bean id="customVoter" class="xyz.appsecurity.helper.CustomDecisionVoter" />
Access Decision Manager
<!-- Define AccessDesisionManager as UnanimousBased -->
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased">
<property name="decisionVoters">
<list>
<ref bean="customVoter" />
<!-- <bean class="org.springframework.security.access.vote.RoleVoter"
/> -->
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</property>
</bean>
Authentiation Exception Handler
<bean id="authenticationExceptionHandler"
class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
<property name="exceptionMappings">
<props>
<!-- /error.jsp -->
<prop
key="org.springframework.security.authentication.BadCredentialsException">/?login_error=t</prop>
<!-- /getnewpassword.jsp -->
<prop
key="org.springframework.security.authentication.CredentialsExpiredException">/changePassword</prop>
<!-- /lockedoutpage.jsp -->
<prop key="org.springframework.security.authentication.LockedException">/?login_error=t</prop>
<!-- /unauthorizeduser.jsp -->
<prop
key="org.springframework.security.authentication.DisabledException">/?login_error=t</prop>
</props>
</property>
</bean>
It looks like spring tries to redirect users who have not logged in to the login page, which is "/index", but that itself is a protected url.
The other possibility is, it tries to display /public/403.html, but that is again protected by security configuration.
Can you add the following entries and try?
<security:intercept-url pattern="/login" filters="none" />
<security:intercept-url pattern="/public/**" filters="none" />