We had the same problem in our GWT application and I found the following solution using Spring Security:
- change the redirect for authentication to a forward that the original URL with the anchor isn't lost
- when the login form is submitted, use JavaScript to retrieve the anchor and append it to the login url with the parameter 'spring-security-redirect' of Spring Security (AbstractAuthenticationTargetUrlRequestHandler.DEF AULT_TARGET_PARAMETER)
- write own SavedRequestAwareAuthenticationSuccessHandler that reads the parameter and appends the anchor again before redirecting to a saved request URL
The configuration and code looks like this:
Code:
<security:http auto-config="false" entry-point-ref="forwardingLoginUrlAuthenticationEntryPoint">
...
<security:form-login authentication-failure-url="/login.jsp?login_error=1"
authentication-success-handler-ref="userAuthenticationSuccessHandler" />
...
</security:http>
<bean id="forwardingLoginUrlAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="useForward" value="true"/>
<property name="loginFormUrl" value="/login.jsp"/>
</bean>
<bean id="userAuthenticationSuccessHandler" class="...UserAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/index.jsp"/>
</bean>
Code:
public class UserAuthenticationSuccessHandler extends
SavedRequestAwareAuthenticationSuccessHandler {
/**
* {@inheritDoc}
*/
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws ServletException, IOException {
SavedRequest savedRequest = requestCache.getRequest(request, response);
if (savedRequest == null || isAlwaysUseDefaultTargetUrl()) {
super.onAuthenticationSuccess(request, response, authentication);
return;
}
clearAuthenticationAttributes(request);
// Use the DefaultSavedRequest URL
String targetUrl = savedRequest.getRedirectUrl();
String gwtParameters = request.getParameter(getTargetUrlParameter());
if (StringUtils.hasText(gwtParameters)) {
targetUrl = targetUrl + "#" + gwtParameters;
}
getRedirectStrategy().sendRedirect(request, response, targetUrl);
}
}
Code:
<html>
<head>
<script type="text/javascript">
function setSubmitUrl(form) {
var action = "j_spring_security_check";
var hash = self.document.location.hash;
if (hash) {
var gwtAnchor = unescape(hash.substring(1));
action = action + "?spring-security-redirect=" + gwtAnchor;
}
form.action = action;
return true;
}
</script>
</head>
<body>
<form method="POST" onSubmit="return setSubmitUrl(this);">
...
</form>
</body>
</html>