Stripes: How to filter request parameters from Clean URLs when applying Security Redirection

StackOverflow https://stackoverflow.com/questions/17178172

  •  01-06-2022
  •  | 
  •  

Question

I am using the StripesStuff J2EESecurityManager and the @RolesAllowed annotation.

When a user who fails the roles test hits a restricted page, our security manager class intercepts the call, gets the called URL from our ActionBeanContext class and stores it in the FlashScope, then returns a ForwardResolution to our Login page.

This process works great, except when we intercept a clean URL. In that case, when our custom ActionBeanContext class computes the last URL, it ends up including the clean-URL arguments as request parameters, so what used to be:

/api/user/1345/document/1235

becomes:

/api/user/14/document/35?user=14&document=35

which is functionally correct, but not really attractive. Since some of the pages are single page apps with anchor tags, I'd really like to keep the URLs clean.

It seems that by the time the SecurityManager has intercepted the call, the clean url parameters have been extracted and placed into the request parameters.

Is there a way for us to either intercept the call before the clean url parameters are added to the request, or alternatively is there a way to differentiate between clean url parameters and regular parameters?

Our ActionBeanContext has a .getLastUrl() function that does something like this:

StringBuilder sb = new StringBuilder();
String uri = (String) req.getAttribute("javax.servlet.forward.request_uri");
sb.append(uri);
sb.append('?');
Map<String, String[]> map 
      = new HashMap<String, String[]>(req.getParameterMap());

// Append the parameters to the URL
for (String key : map.keySet()) {
    String[] values = map.get(key);
    for (String value : values) {
        sb.append(key).append('=').append(value).append('&');
    }
}
// Remove the last '&'
sb.deleteCharAt(sb.length() - 1);

return sb.toString();

So the problem is that by the time we call getLastUrl() the parameters have been pulled out of the clean url and put into the request parameters.

How can I avoid this?

Was it helpful?

Solution 2

I solved this problem by changing the way the query string is calculated to use HttpServletRequest.getQueryString() instead of req.getParameterMap(). I think the resulting code is also much cleaner.

I think that Kishor's suggestion the change the intercepted lifecycle stage would also work and would also be cleaner (and more efficient), however I didn't experiment with that change yet.

Here is the body of my updated getLastUrl() function:

HttpServletRequest req = getRequest();
StringBuilder sb = new StringBuilder();

// Start with the URI and the path
String uri = (String) req.getAttribute("javax.servlet.forward.request_uri");
if (uri == null) {
    uri = req.getRequestURI();
}
sb.append(uri);

// Now the request parameters
if (StringUtils.isNotEmpty(req.getQueryString())) {
    sb.append('?');
    sb.append(req.getQueryString());
}

return sb.toString();

OTHER TIPS

At which life cycle stage you are trying to security manager class intercept a request. Try to intercept at life cycle stage "RequestInit" where the request is about to be handled or using @Intercepts(LifecycleStage.RequestInit). Or You can also try to put before life cycle stage "ActionBeanResolution" where action bean that is targeted by the request is determined from the URL.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top