Protect direct access of AJAX based URL - ajax

We have a page where User can come and create his ID. So any unauthorized user can come and create his ID.
Problem is this page is having some AJAX calls for validation which checks if ID format which user is entering on screen is correct or not.
An attacker can note down the AJAX based URL through Browser-> Inspect Element and can choke our server calling it multiple times through some attacking tools.
Please note AJAX based URL is hitting to a web service which in my opinion is doing resource intensive operation(i.e domain is correct or not, user already exist or not?).
I am using Spring MVC as web application framework. Can I protect direct access of URL (ajax) for an unauthorized user?

You can't hide the URL of the web-service if it's being requested by AJAX (XmlHTTPrequest).
You'd be best to implement server-side "throttling" (google it!) on the webserver that serves your web-service. If a particular IP makes too many requests, or some overall threshhold of requests is passed -- you return a web-service exception that asks the user to try again later.
In the case of a DDOS, then you'll need to deal with that at the network routing level.

I have a similar requirement, of protecting my Ajax Resources - Not to be called from the Browser Addressbar, but via a AJAX request, basically a XMLHTTPRequest.
Wrote a AjaxOnlyFilter which looks for the URL Mappings in a array of Strings, and if matches, checks presence of the "X-Requested-With" header.
If header not present OR value not matching to value "XMLHttpRequest", then invoke forward on requestDispatcher to error page or set 400 status.
private String[] mappings = { "/model", "/records" , "/update" , "/insert", "/delete"};
public boolean urlContainsMappingsFromAJAXList(String url)
{
for(int i =0; i < mappings.length; i++)
{
if(url.contains(mappings[i]))
{
return true;
}
}
return false;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
StringBuffer requestURL = httpServletRequest.getRequestURL();
if(urlContainsMappingsFromAJAXList(requestURL.toString())){
String requestedWithHeader = httpServletRequest.getHeader("X-Requested-With");
//if X-Requested-With header is not XMLHttpRequest
if(requestedWithHeader==null || (!requestedWithHeader.equalsIgnoreCase("xmlhttprequest"))){
LOGGER.debug("Not a AJAX request, redirection to error page");
httpServletRequest.getRequestDispatcher("error404.jsp").forward(request, response);
return;
}
//else continue with filter chain
}
//else continue with filter chain
// pass the request along the filter chain
filterChain.doFilter(request, response);
}

Related

How to Differentiate whether the request is un-authenticate or session time out [duplicate]

Case 1: Log out : Once we log out, if one tries to access previous, it must automatically redirect to login.jsp
Case 2: Session expired : If session expires when user is still logged in, it must try to automatically redirect to sessionExpired.jsp when previous page is accessed.
How to differentiate ? I am currently invalidating session when logging out.
On login, set a cookie with a long expiry (> 24 hours). Remove this cookie at logout time by setting the maxage to 0.
You can have check for any non-logged in user (i.e. invalid session id).
If the cookie does not exist, redirect him to login.jsp
If the cookie exists, it means his session expired so redirect him to session-expired.jsp
You can test expired sessions by checking if HttpServletRequest#getRequestedSessionId() doesn't return null (which means that the client has sent a session cookie and thus assumes that the session is still valid) and HttpServletRequest#isRequestedSessionIdValid() returns false (which means that the session has been expired at the server side).
In a nut:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
response.sendRedirect(request.getContextPath() + "/sessionexpired.jsp");
} else if (session == null || session.getAttribute("user") == null) {
response.sendRedirect(request.getContextPath() + "/login.jsp");
} else {
chain.doFilter(request, response);
}
}
No need to hassle with extra cookies. Map this Filter on an url-pattern covering the protected pages (and thus excluding the sessionexpired and login pages!).
Don't forget to disable page caching by the browser on the protected pages, otherwise the webbrowser will load them from the cache when you're going back in the browser history, instead of sending a new request to the server. You can achieve this by doing the following in the same filter, before Chain#doFilter() call.
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
If it were me I would clear the session on log out and create a bool in it called HasLoggedOut then set this to true. Then if this bool exists in session you know they logged out, if it doesn't then the session has either timed out or the user never logged in at all.
As you still cant differentiate between timed out and not logged in I normally make the decision that if they request an authenticated page I will just send them to session timeout page which also doubles as a login page that says something like
"Oops, we don't know who you are, either your session has timed out or you have not yet logged in please login below"
This then caters for both scenarios

How to redirect from spring ajax controller?

I have a controller with #ResponseBody annotation. What I want to do is if this user doesn't exists process user's Id and return a json object. If exists redirect to user page with userInfo. Below code gives ajax error. Is there any way to redirect to user page with userInfo?
#RequestMapping(value = "/user/userInfo", method = {RequestMethod.GET})
#ResponseBody
public String getUserInfo(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) {
if(...){
.....//ajax return
}else{
modelMap.addAttribute("userInfo", userInfoFromDB);
return "user/user.jsp";
}
}
Well, this method is annotated with #ResponseBody. That means that the String return value will be the body of the response. So here you are just returning "user/user.jsp" to caller.
As you have full access to the response, you can always explicitely do a redirect with response.sendRedirect(...);. It is even possible to explicitely ask Spring to pass userInfoFromDB as a RedirectAttribute through the flash. You can see more details on that in this other answer from me (this latter is for an interceptor, but can be used the same from a controller). You would have to return null to tell spring that the controller code have fully processed the response. Here it will be:
...
}else{
Map<String, Object> flash = RequestContextUtils.getOutputFlashMap(request);
flash.put("userInfo", userInfoFromDB);
response.redirect(request.getContextPath() + "/user/user.jsp");
return null;
}
...
The problem is that the client side expects a string response that will not arrive and must be prepared to that. If it is not, you will get an error client side. The alternative would then be not to redirect but pass a special string containing the next URL:
...
}else{
Map<String, Object> flash = RequestContextUtils.getOutputFlashMap(request);
flash.put("userInfo", userInfoFromDB); // prepare the redirect attribute
return "SPECIAL_STRING_FOR_REDIRECT:" + request.getContextPath() + "/user/user.jsp");
}
and let the javascript client code to process that response and ask for the next page.

Invalid XSRF token at /oauth/token

Complete code for a Spring OAuth2 implementation of Multi-Factor Authentication has been uploaded to a file sharing site at this link. Instructions are given below to recreate the current problem on any computer in only a few minutes.
**CURRENT PROBLEM:**
Most of the authentication algorithm works correctly. The program does not break until the very end of the control flow shown below. Specifically, an `Invalid CSRF token found for http://localhost:9999/uaa/oauth/token` error is being thrown at the end of the **SECOND PASS** below. The app in the link above was developed by adding a custom `OAuth2RequestFactory`, `TwoFactorAuthenticationFilter` and `TwoFactorAuthenticationController` to the `authserver` app of this Spring Boot OAuth2 GitHub sample. **What specific changes need to be made to the code below in order to resolve this CSRF token error and enable 2-factor authentication?**
My research leads me to suspect that the `CustomOAuth2RequestFactory` (API at this link) might be the place to configure a solution because it defines ways for managing `AuthorizationRequest`s and `TokenRequest`s.
**This section of the official OAuth2 spec indicates that the `state` parameter of the request made to the authorization endpoint is the place where the `csrf` token is added.**
Also, the code in the link uses the Authorization Code Grant Type described at this link to the official spec, which would mean that Step C in the flow does not update the `csrf` code, thus triggering the error in Step D. (You can view the entire flow including Step C and Step D in the official spec.)
**CONTROL FLOW SURROUNDING THE CURRENT ERROR:**
The current error is being thrown during the **SECOND PASS** through `TwoFactorAuthenticationFilter` in the flowchart below. Everything works as intended until the control flow gets into the **SECOND PASS**.
The following flowchart illustrates the control flow of the two factor authentication process that is employed by the code in the downloadable app.
Specifically, the Firefox `HTTP` Headers for the sequence of `POST`s and `GET`s show that the same `XSRF` cookie is sent with every request in the sequence. The `XSRF` token values do not cause a problem until after the `POST /secure/two_factor_authentication`, which triggers server processing at the `/oauth/authorize` and `/oauth/token` endpoints, with `/oauth/token` throwing the `Invalid CSRF token found for http://localhost:9999/uaa/oauth/token` error.
To understand the relationship between the above control flow chart and the `/oauth/authorize` and `/oauth/token` endpoints, you can compare the above flowchart side by side with the chart for the single factor flow at the official spec in a separate browser window. The **SECOND PASS** above simply runs through the steps from the one-factor official spec a second time, but with greater permissions during the **SECOND PASS**.
**WHAT THE LOGS SAY:**
The HTTP Request and Response Headers indicate that:
1.) A POST to `9999/login` with the correct `username` and `password` submitted results in a redirect to `9999/authorize?client_id=acme&redirect_uri=/login&response_type=code&state=sGXQ4v` followed by a `GET 9999/secure/two_factor_authenticated`. One XSRF token remains constant across these exchanges.
2.) A POST to `9999/secure/two_factor_authentication` with the correct pin code sends the same `XSRF` token, and gets successfully re-directed to `POST 9999/oauth/authorize` and makes it into `TwoFactorAuthenticationFilter.doFilterInternal()` and proceeds to `request 9999/oauth/token`, but `9999/oauth/token` rejects the request because the same old XSRF token does not match a new `XSRF` token value, which was apparently created during the **FIRST PASS**.
One obvious difference between `1.)` and `2.)` is that the second `request 9999/oauth/authorize` in `2.)` does not contain the url parameters which are included in the first request to `9999/authorize?client_id=acme&redirect_uri=/login&response_type=code&state=sGXQ4v` in `1.)`, and also defined in the official spec. But it is not clear if this is causing the problem.
Also, it is not clear how to access the parameters to send a fully formed request from the `TwoFactorAuthenticationController.POST`. I did a SYSO of the `parameters` `Map` in the `HttpServletRequest` for the `POST 9999/secure/two_factor_authentication` controller method, and all it contains are the `pinVal` and `_csrf` variables.
You can read all the HTTP Headers and Spring Boot logs at a file sharing site by clicking on this link.
**A FAILED APPROACH:**
I tried #RobWinch's approach to a similar problem in the Spring Security 3.2 environment, but the approach does not seem to apply to the context of Spring OAuth2. Specifically, when the following `XSRF` update code block is uncommented in the `TwoFactorAuthenticationFilter` code shown below, the downstream request headers do show a different/new `XSRF` token value, but the same error is thrown.
if(AuthenticationUtil.hasAuthority(ROLE_TWO_FACTOR_AUTHENTICATED)){
CsrfToken token = (CsrfToken) request.getAttribute("_csrf");
response.setHeader("XSRF-TOKEN"/*"X-CSRF-TOKEN"*/, token.getToken());
}
**This indicates that the `XSRF` configuration needs to be updated in a way that `/oauth/authorize` and `/oauth/token` are able to talk with each other and with the client and resource apps to successfully manage the `XSRF` token values.** Perhaps the `CustomOAuth2RequestFactory` is what needs to be changed to accomplish this. But how?
**RELEVANT CODE:**
The code for `CustomOAuth2RequestFactory` is:
public class CustomOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
public static final String SAVED_AUTHORIZATION_REQUEST_SESSION_ATTRIBUTE_NAME = "savedAuthorizationRequest";
public CustomOAuth2RequestFactory(ClientDetailsService clientDetailsService) {
super(clientDetailsService);
}
#Override
public AuthorizationRequest createAuthorizationRequest(Map authorizationParameters) {
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpSession session = attr.getRequest().getSession(false);
if (session != null) {
AuthorizationRequest authorizationRequest = (AuthorizationRequest) session.getAttribute(SAVED_AUTHORIZATION_REQUEST_SESSION_ATTRIBUTE_NAME);
if (authorizationRequest != null) {
session.removeAttribute(SAVED_AUTHORIZATION_REQUEST_SESSION_ATTRIBUTE_NAME);
return authorizationRequest;
}
}
return super.createAuthorizationRequest(authorizationParameters);
}
}
The code for `TwoFactorAuthenticationFilter` is:
//This class is added per: https://stackoverflow.com/questions/30319666/two-factor-authentication-with-spring-security-oauth2
/**
* Stores the oauth authorizationRequest in the session so that it can
* later be picked by the {#link com.example.CustomOAuth2RequestFactory}
* to continue with the authoriztion flow.
*/
public class TwoFactorAuthenticationFilter extends OncePerRequestFilter {
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
private OAuth2RequestFactory oAuth2RequestFactory;
//These next two are added as a test to avoid the compilation errors that happened when they were not defined.
public static final String ROLE_TWO_FACTOR_AUTHENTICATED = "ROLE_TWO_FACTOR_AUTHENTICATED";
public static final String ROLE_TWO_FACTOR_AUTHENTICATION_ENABLED = "ROLE_TWO_FACTOR_AUTHENTICATION_ENABLED";
#Autowired
public void setClientDetailsService(ClientDetailsService clientDetailsService) {
oAuth2RequestFactory = new DefaultOAuth2RequestFactory(clientDetailsService);
}
private boolean twoFactorAuthenticationEnabled(Collection authorities) {
System.out.println(">>>>>>>>>>> List of authorities includes: ");
for (GrantedAuthority authority : authorities) {
System.out.println("auth: "+authority.getAuthority() );
}
return authorities.stream().anyMatch(
authority -> ROLE_TWO_FACTOR_AUTHENTICATION_ENABLED.equals(authority.getAuthority())
);
}
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("------------------ INSIDE TwoFactorAuthenticationFilter.doFilterInternal() ------------------------");
// Check if the user hasn't done the two factor authentication.
if (AuthenticationUtil.isAuthenticated() && !AuthenticationUtil.hasAuthority(ROLE_TWO_FACTOR_AUTHENTICATED)) {
System.out.println("++++++++++++++++++++++++ AUTHENTICATED BUT NOT TWO FACTOR +++++++++++++++++++++++++");
AuthorizationRequest authorizationRequest = oAuth2RequestFactory.createAuthorizationRequest(paramsFromRequest(request));
/* Check if the client's authorities (authorizationRequest.getAuthorities()) or the user's ones
require two factor authenticatoin. */
System.out.println("======================== twoFactorAuthenticationEnabled(authorizationRequest.getAuthorities()) is: " + twoFactorAuthenticationEnabled(authorizationRequest.getAuthorities()) );
System.out.println("======================== twoFactorAuthenticationEnabled(SecurityContextHolder.getContext().getAuthentication().getAuthorities()) is: " + twoFactorAuthenticationEnabled(SecurityContextHolder.getContext().getAuthentication().getAuthorities()) );
if (twoFactorAuthenticationEnabled(authorizationRequest.getAuthorities()) ||
twoFactorAuthenticationEnabled(SecurityContextHolder.getContext().getAuthentication().getAuthorities())) {
// Save the authorizationRequest in the session. This allows the CustomOAuth2RequestFactory
// to return this saved request to the AuthenticationEndpoint after the user successfully
// did the two factor authentication.
request.getSession().setAttribute(CustomOAuth2RequestFactory.SAVED_AUTHORIZATION_REQUEST_SESSION_ATTRIBUTE_NAME, authorizationRequest);
// redirect the the page where the user needs to enter the two factor authentiation code
redirectStrategy.sendRedirect(request, response,
ServletUriComponentsBuilder.fromCurrentContextPath()
.path(TwoFactorAuthenticationController.PATH)
.toUriString());
return;
}
}
//THE NEXT "IF" BLOCK DOES NOT RESOLVE THE ERROR WHEN UNCOMMENTED
//if(AuthenticationUtil.hasAuthority(ROLE_TWO_FACTOR_AUTHENTICATED)){
// CsrfToken token = (CsrfToken) request.getAttribute("_csrf");
// this is the value of the token to be included as either a header or an HTTP parameter
// response.setHeader("XSRF-TOKEN", token.getToken());
//}
filterChain.doFilter(request, response);
}
private Map paramsFromRequest(HttpServletRequest request) {
Map params = new HashMap();
for (Entry entry : request.getParameterMap().entrySet()) {
params.put(entry.getKey(), entry.getValue()[0]);
}
return params;
}
}
**RE-CREATING THE PROBLEM ON YOUR COMPUTER:**
You can recreate the problem on any computer in only a few minutes by following these simple steps:
1.) Download the zipped version of the app from a file sharing site by clicking on this link.
2.) Unzip the app by typing: `tar -zxvf oauth2.tar(2).gz`
3.) launch the `authserver` app by navigating to `oauth2/authserver` and then typing `mvn spring-boot:run`.
4.) launch the `resource` app by navigating to `oauth2/resource` and then typing `mvn spring-boot:run`
5.) launch the `ui` app by navigating to `oauth2/ui` and then typing `mvn spring-boot:run`
6.) Open a web browser and navigate to `http : // localhost : 8080`
7.) Click `Login` and then enter `Frodo` as the user and `MyRing` as the password, and click to submit.
8.) Enter `5309` as the `Pin Code` and click submit. **This will trigger the error shown above.**
You can view the complete source code by:
a.) importing the maven projects into your IDE, or by
b.) navigating within the unzipped directories and opening with a text editor.
You can read all the HTTP Headers and Spring Boot logs at a file sharing site by clicking on this link.
One idea that popped to my head:
If session fixation is activated, a new session is created after the user authenticated successfully (see SessionFixationProtectionStrategy). This will also of course create a new csrf token if you use the default HttpSessionCsrfTokenRepository. Since you're mentioning the XSRF-TOKEN header I assume you use some JavaScript frontend. I could imagine that the original csrf token that was used for the login is stored and reused afterwards - which would not work because this csrf token is not valid anymore.
You may try disabling session fixation (http.sessionManagement().sessionFixation().none() or <session-management session-fixation-protection="none"/>) or re-get the current CSRF token after login.
Your CustomOAuth2RequestFactory is putting the previous request in-place of the current request. However, you are not updating the XSRF token in the old request when you make this switch. Here is what I would suggest for the updated CustomOAuth2Request:
#Override
public AuthorizationRequest createAuthorizationRequest(Map<String, String> authorizationParameters) {
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpSession session = attr.getRequest().getSession(false);
if (session != null) {
AuthorizationRequest authorizationRequest = (AuthorizationRequest) session.getAttribute(SAVED_AUTHORIZATION_REQUEST_SESSION_ATTRIBUTE_NAME);
if (authorizationRequest != null) {
session.removeAttribute(SAVED_AUTHORIZATION_REQUEST_SESSION_ATTRIBUTE_NAME);
//UPDATE THE STATE VARIABLE WITH THE NEW TOKEN. THIS PART IS NEW
CsrfToken csrf = (CsrfToken) attr.getRequest().getAttribute(CsrfToken.class.getName());
String attrToken = csrf.getToken();
authorizationRequest.setState(attrToken);
return authorizationRequest;
}
}
return super.createAuthorizationRequest(authorizationParameters);
}
I am revisiting this because my initial answer draft got downvoted. This version is further along the same path, which I believe is the right avenue of approach.

How exactly Spring MVC handle cookie?

I am studying how Spring handle cookie on a tutorial and I have some doubts.
In this example there is this CookieControllerExample that perform some cookie operation when are performed.
#Controller
public class CookieControllerExample {
#RequestMapping(value = "/readcookie", method=RequestMethod.GET)
public ModelAndView readCookie(#CookieValue(value = "URL") String URL, HttpServletRequest request,
HttpServletResponse response) {
System.out.println("CookieControllerExample readcookie is called");
return new ModelAndView("/cookie/cookieView", "cookieValue", URL);
}
#RequestMapping(value = "/writecookie", method=RequestMethod.GET)
public String writeCookie(HttpServletRequest request,
HttpServletResponse response) {
System.out.println("CookieControllerExample writeCookie is called");
Cookie cookie = new Cookie("URL", request.getRequestURL().toString());
response.addCookie(cookie);
return "/cookie/cookieView";
}
#RequestMapping(value = "/readAllCookies", method=RequestMethod.GET)
public ModelAndView readAllCookies(HttpServletRequest request) {
System.out.println("CookieControllerExample readAllCookies is called");
Cookie[] cookies = request.getCookies();
System.out.println("All Cookies in your browsers");
String cookiesStr = "";
for(Cookie cookie : cookies){
System.out.println(cookie.getName() + " : " + cookie.getValue());
cookiesStr += cookie.getName() + " : " + cookie.getValue() + "<br/>";
}
return new ModelAndView("/cookie/cookieView", "cookieValue", cookiesStr);
}
}
From what I have understand the first method (readcookie()) read the content of a coockie named URL stored inside my computer.
The second method (writecookie()) create a cookie named URL and store it on my computer.
And the third method read the contet of all the cookies stored on my computer.
I have 2 doubts:
1) I know that cookies are textual file. Where exactly are stored?
2) Why the **writeCookie() method, after create a new cookie, add it to the response? How can I examinate the cookie stored on my system?
response.addCookie(cookie);
I think that it could depend by the fact that the response come back to the user browser and it retrieve the cookie from this response and create a textual file somewhere on my system. Is it true or am I missing something?
You asked:
1) I know that cookies are textual file. Where exactly are stored?
The cookies are stored by the clients browser, somewhere at the clients machine. - The exact location depends on the browser
2) Why the **writeCookie() method, after create a new cookie, add it to the response? How can I examinate the cookie stored on my system?
As I told in answer for question 1), the cookie is stored at client side. So it's values need to be send to the client (in the header of the http-response). And that is the reason why the cookie (object) is added to the http response.
I strongly recommend you to read the wikipedia article about Http Cookies. And do not get confused by mixing cookies and sessions (sessions are often implement with a session-tracking-cookie, but its data resist on the server side.)

Redirect to the page containing # (hash) sign after login

I am using Spring Security and wondering how can I implement redirection after succesfull login to the source page if that page contains # (hash) sign.
Right now I use always-use-default-target="false" and it works fine on URL kind of: /path/to/page/.
But when the URL become to #/path/to/page it doesn't make any redirections.
Is there any way to fix it?
Here is the solution I used at the end:
$(document).ready(function(){
$('#auth-form').submit(function() {
var el = $(this);
var hash = window.location.hash;
if (hash) el.prop('action', el.prop('action') + '#' + unescape(hash.substring(1)));
return true;
});
});
This snippet addes the hash to authorization form's action attribute and Spring redirect you to the URL of kind: #/path/to/page without any problem.
Maybe this is the old question, but during my recent research in this topic, I found that the problem is common and still exists (especially in case of modern AngularJS front-end apps with back-end security). I'd like to share my solution with you.
On the login page, e.g., /login.html, put following code before the </body> tag:
<script type="text/javascript">
var hash = window.location.hash;
document.cookie="hashPart=" + window.btoa(hash);
</script>
Note (1): btoa() function works in IE >= 10 (http://www.w3schools.com/jsref/met_win_btoa.asp), for older browsers use jQuery equivalent.
Note (2): The encryption of the # part of URL is necessary as it may contain special characters, which are not allowed to be stored in cookie value string.
From the server side you have to modify onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) method of class implementing AuthenticationSuccessHandler interface.
In my case, I simply extend the SavedRequestAwareAuthenticationSuccessHandler class and override the onAuthenticationSuccess method using its original code. Then I obtain the hashPart cookie value from the request, decode it and add to resolved redirect URL. My code fragment below:
#Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws ServletException, IOException {
// ... copy/paste original implementation here, until ...
// Use the DefaultSavedRequest URL
String targetUrl = savedRequest.getRedirectUrl();
for (Cookie cookie : req.getCookies()) {
if (cookie.getName().equals("hashPart")) {
targetUrl += new String(Base64Utils.decodeFromString(cookie.getValue()));
cookie.setMaxAge(0); // clear cookie as no longer needed
response.addCookie(cookie);
break;
}
}
getRedirectStrategy().sendRedirect(request, response, targetUrl);
}
Finally, just inject your success handler class to your Spring Security configuration, as described in: https://stackoverflow.com/a/21100458/3076403
I'm looking forward to your comments or other solutions to this problem.

Resources