looking for a way to remove security token from URL - java

my web application has multiple jsp tags where the GET method is being called and security token is part of the URL.Now after the last security review we have been asked to remove security token from the URL. What are the options I have here ?What is the best approach ? Thank you in advance for any input!
jsp
<fmt:message key="label.chkNbr" />
java method
#RequestMapping(value = SORT_URL_MAPPING, method = RequestMethod.GET)
public String sortCompany(
#PathVariable("userType") String userType,
WebRequest webRequest,
#RequestParam(required = true, value = "sortFieldName") String sortFieldName,
ModelMap modelView) {
DataTableViewer<Company
> dataTableViewer = getDataTableViewer(webRequest);
dataTableViewer.toggleColumnSortOrder(sortFieldName);
initializeModelView(modelView, webRequest);
return SUCCESS_VIEW;
}

Related

Spring: Parameter conditions "loanTitle" not met for actual request parameters

Java Spring MVC. I can't open url without a parameter. I found suggestions in Internet(Spring MVC Thymeleaf Error: Parameter conditions not met for actual request parameters, http://www.baeldung.com/spring-requestmapping), but they didn't help me.
#Controller
#RequestMapping("/loans/")
public class LoanController {
#Autowired
LoanDAO loanDAO;
#GetMapping(value= "objectloan", params = {"loanTitle"})
public String index(Model theModel, HttpSession session, #RequestParam(value = "loanTitle", required = false, defaultValue = "") Optional<String> loanTitle)
{
....
}
URL works
http://localhost:8080/college/loans/objectloan?loanTitle=test
URL with error
http://localhost:8080/college/loans/objectloan
Error:
Type Status Report
Message Parameter conditions "loanTitle" not met for actual request parameters:
Description The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
Since loanTitle might not present in your query url,try to remove params = {"loanTitle"} in your controller method
#GetMapping(value= "objectloan")
public String index(Model theModel, HttpSession session, #RequestParam(value = "loanTitle", required = false, defaultValue = "") Optional<String> loanTitle)
{
....
}

How to send x-editable request to spring mvc backend?

I want to use x-editable into my page, and I learn it from this document.
The html element is here:
Click and input
And my controller is:
#RequestMapping(value = "/candidates/updateDisplayName", method = RequestMethod.POST)
public #ResponseBody String updateDisplayName(#RequestParam(value = "displayName") String displayName, HttpServletRequest request) {
System.out.println("Update display name");
System.out.println(displayName);
return "";
}
However, I got error again and again, the error message is like:
{"timestamp":1417250586743,"status":400,"error":"Bad
Request","exception":"org.springframework.web.bind.MissingServletRequestParameterException","message":"Required
String parameter 'displayName' is not
present","path":"/candidates/updateDisplayName"}
I knew that it's caused by the request parameter but not sure how to solve, could anyone help with this? Thanks a lot.
I changed the "displayName" to "name" in the #RequestParam it works, thanks for chrome developer tools, it helps me.
#RequestMapping(value = "/candidates/updateDisplayName", method = RequestMethod.POST)
public #ResponseBody String updateDisplayName(#RequestParam(value = "name") String displayName, HttpServletRequest request) {
System.out.println("Update display name");
System.out.println(displayName);
return "";
}

Spring MVC and redirect on POST sends destination file on URL

I have a very weird problem in my Spring MVC application. I am writing a login form and POSTing the data via AJAX into a Spring MVC controller that looks like this:
#Controller
public class LoginResourceController {
private static final Logger log = Logger.getLogger (LoginResourceController.class.getName());
#RequestMapping (value="/login", method = RequestMethod.POST)
public String checkAccount (HttpServletRequest httpRequest, HttpServletResponse httpResponse,
#RequestHeader (value = "User-Agent") String retrievedUserAgent,
#RequestParam("username") String username,
#RequestParam("password") String password,
#RequestParam("rememberMe") String rememberMe)
{
//Check username and password in DB, and then if OK,
return "redirect:/login/redirectToMain";
}
#RequestMapping (value = "/login/redirectToMainpage", method = RequestMethod.GET)
public String redirectControllerToMainPage (HttpServletRequest httpRequest, HttpServletResponse httpResponse)
{
return "mainPage";
}
Now, the problem is, I have the client (browser) upon redirect requesting a URL that contains the entire contents of mainPage.jsp in the URL. So it looks like:
https://localhost:8443/<!DOCTYPE html><html><head><meta charset=utf-8 /><title>Page that the subscriber sees after login</title>....
I am quite confounded by this error. Is this some servlet setting in WEB-INF/web.xml or mvc-dispatcher-servlet.xml that I need to change? I am using Spring 3.0.5.
BTW, my redirect works flawlessly for GET method controllers in the same Spring MVC application. (e.g., when I re-load the main page of my application, the redirect to the logged in mainPage.jsp above works flawlessly). Moreover, other GET methods on other jsps work correctly too (example, redirect to /login page via login.jsp via a GET of https://localhost:8443/.
I have checked the following and they didn't help: 1 2.
Try not to put the redirect in the return of the controller. This seems to either cause the full page to be rendered as the ajax response, or a redirect header is filled in with an url with the full contents of the page as a string in the response body.
As a first approach, try to make the request a normal HTTP request instead of ajax, and it should just work.
Alternativelly try to make the return body empty, and return an HTTP status code to the client. Either 200 OKif the account is OK or 401 Unauthorized:
#RequestMapping (value="/login", method = RequestMethod.POST)
public ResponseEntity checkAccount (HttpServletRequest httpRequest, HttpServletResponse httpResponse,
#RequestHeader (value = "User-Agent") String retrievedUserAgent,
#RequestParam("username") String username,
#RequestParam("password") String password,
#RequestParam("rememberMe") String rememberMe)
{
//Check username and password in DB
....
HttpStatus returnCode = null;
if(usernameAndPasswordOK) {
returnCode = HttpStatus.OK;
}
else {
returnCode = HttpStatus.UNAUTHORIZED;
}
return new ResponseEntity(returnCode);
}
And then on the client redirect with Javascript accordingly.
This was a little tricky for me to figure out, and being a web development noob doesn't help here. Anyway, #jhadesdev's answer above pointed me to the issue.
On my client, I do this:
$("#loginForm").submit(function(evt)
{
evt.preventDefault();
if (loginFormInputIsValid ())
{
$.ajax ({
type: "POST",
url: "/login",
data: $(this).serialize(),
success: function (response)
{
window.location = response;
}
});
}
}
which was the issue--you see, setting the window.location=response; caused the client (browser) to request the server for the funky URL above. I have to change my client call (this is where #jhadesdev's response helped) to make sure I don't do something so wrong.
Thanks for your time, #jhadesdev.

Persisting object data between controllers in Spring

I have an object called Request which is the main object of my portal that stores all the information of a request, the user, their form selections, etc. How to I persist all the previous information in between the different forms? In each .GET I have to set the request object, and then in each .POST, the only information that is passed to it is what is in the forms on the .GET pages. So on each page I have to have hidden fields such as
<form:input path='requestId' style='display:none' />
<form:input path='currentUserId' style='display:none' />
<form:input path="step" style='display:none' />
I need these fields, and would also like to have the rest of the fields in the request object that are not on the form without having to repeat that for each and every field in my object.
#RequestMapping(value = "/review", method = RequestMethod.GET)
public ModelAndView showCorReview(#RequestParam(value = "requestId") String requestId,
#CookieValue(value = "EMP_ID", defaultValue = "168") int userId)
{
Request request = requestManager.getRequestById(Integer.parseInt(requestId));
request.setCurrentUserId(userId);
String pageTitle = "2.1: Initiate New Service Request -- (Review)";
ModelAndView mav = new ModelAndView();
mav.setViewName("newRequest/review");
mav.addObject("title", pageTitle);
mav.addObject("request", request);
mav.addObject("cpm", userManager.getUserById(request.getCpm()).getName());
return mav;
}
#RequestMapping(value = "/review", method = RequestMethod.POST)
public String saveReview(Request request, #RequestParam(value = "commentData", required = false) String[] additionalComments)
{
if (additionalComments != null)
commentLogManager.addCommentLog(additionalComments, request);
if (request.getRejectReason() == "")
{
request.setCpm(admin.getCPM(request.getContract()).getId());
request.setCor(admin.getCOR(request.getContract()).getId());
requestManager.updateRequest(request);
}
else
{
if (request.getSubmitType().equals("return"))
{
request.setNextStep(1);
requestManager.moveRequestToStep(request);
}
}
return worksheetUrl + request.getId();
}
Alternatately I could also in the .POST do the
Request request = requestManager.getRequestById(Integer.parseInt(requestId))
Then use setters on all the form fields, but again, I would prefer the data to actually persist on it's own without explicitly calling that.
#Tim, if I understood your requirement correctly, you have a sequence of forms and you would like to transfer information from one form to the next without having to hit a database or copy over request variables from one form to another. I could support #JB Nizel's suggestion of employing HTTP Session, but you may not want to make the session "heavy"; after all, it is the next most persistent scope after application-scope.
Spring Web Flow may be the answer. Flow-scope will allow you to build up form-state as the user progresses from one form to the next. Plus you don't have to worry about form-scoped variables when the flow finishes, unlike session variables that you don't want to have lingering around.

When the validator finds form errors, the form page is redisplayed at the POST url

An item is displayed at this URL:
/item/10101
using this Controller method:
#RequestMapping(value = "/item/{itemId}", method = RequestMethod.GET)
public final String item(HttpServletRequest request, ModelMap model,
#PathVariable long itemId)
{
model = this.fillModel(itemId);
return "item";
}
The page contains a form that submits to the following method in the same controller:
#RequestMapping(value = "/process_form", method = RequestMethod.POST)
public final String processForm(HttpServletRequest request,
#ModelAttribute("foo") FooModel fooModel,
BindingResult bindResult,
ModelMap model)
{
FooModelValidator validator = new FooModelValidator();
validator.validate(FooModel, bindResult);
if (bindResult.hasErrors())
{
model = this.fillModel(fooModel.getItemId());
return "item";
}
return "account";
}
If the validator finds errors in the form, it redisplays the item but instead of displaying it at the original url:
/item/10101
it displays it at its own url:
/process_form
Is it possible to redisplay the form at the original URL?
/item/10101
(I've tried getting the referrer and redirecting to it in processForm but then all of the model contents end up displayed as URL name/value pairs:)
#RequestMapping(value = "/process_form", method = RequestMethod.POST)
public final String processForm(HttpServletRequest request,
#ModelAttribute("foo") FooModel fooModel,
BindingResult bindResult,
ModelMap model)
{
String referrer = request.getHeader("referer");
FooModelValidator validator = new FooModelValidator();
validator.validate(FooModel, bindResult);
if (bindResult.hasErrors())
{
model = this.fillModel(fooModel.getItemId());
return "redirect:" + referrer;
}
return "account";
}
Short answer: No.
What happens is a server-side redirect (forward), which is within the same request, and so the submitted values are preserved (and displayed in the form)
The url will change if you use a client-side redirect (return "redirect:item";), but in that case a new request will come and the submitted values will be lost.
But here are two options that you have:
use the same URL in the mappings for both methods and distinguish them based on request method - GET for the former, POST for the latter. This might be confusing, so document it.
find / implement flash scope for spring-mvc. There's nothing built-in. The flash scope means that values are preserved (in the session usually) for a submit and the subsequent redirect. This option includes the manual handling, by putting the submitted object in the session, and later retrieving & removing it

Categories

Resources