I am working on an internal tool that simulates SOAP responses for different web services that our product uses. This is intended for use in local development.
The idea is to store the SOAP responses in the database as a blob data. During the mapping of a URL keys to a response, the URL keys and expected SOAP response will be stored to the database. The simulated SOAP response will be as a string body in POST request.
The SOAP response will be stored as a blob in the database along with URL keys. If the URL is /configureresponse/{responsetype}/{responsecode}/, then the values of response type and response code will be saved to the database along with the SOAP response as string.
I am building a Spring MVC application for the same. The code snippet is given below
#Controller
#RequestMapping(value = "/configureresponse/{responsetype}/{responsecode}",
method = RequestMethod.POST)
public ModelAndView configureResponse(
#PathVariable String responseType, #PathVariable String responseCode,
#RequestBody String soapResponse) {
}
How do I return a Servlet Response such as 200 OK or 403 Forbidden based on certain conditions?
Is there a way to secure the incoming XML response and the outgoing XML response? This is an internal tool, but I am not sure how to handle XML injection or any other security issues.
UPDATE: How do I secure the application against a billion laughs attack or make it more secure?
Should I be checking for XSRF vulnerability? If yes, how do I do that?
How do I handle simultaneous concurrent inputs for the same response and request?
UPDATE: How do I check if say one thread is updating the response for a given response type and response code, while the other thread is viewing the response for a given response type and response code?
How do I return a Servlet Response such as 200 OK or 403 Forbidden based on certain conditions?
There are several ways to do this. For instance, you could change your return type to a ResponseEntity<String>, which has a constructor that accepts an HttpStatus. Or, you could simply pass in an HttpServletResponse and set the response code there. Knowing Spring, there are probably 20 more valid ways to do this. I would suggest reading through the excellent Reference Guide available on their site.
Is there a way to secure the incoming XML response and the outgoing XML response? This is an internal tool, but I am not sure how to handle XML injection or any other security issues.
Not sure what you mean by "secure". If you mean transmission, then use SSL. If you mean authorization/authentication use Spring Security. If you mean something else, then I am not sure what to offer except to say I need a better explanation of what you want/need.
Should I be checking for XSRF vulnerability? If yes, how do I do that? Any link or tutorial would be welcome.
Security should be a concern, whether it's an internal app or external. Most hacks now-a-days are done by social engineering their way into the intra-net of a company. Take the recent Target breach. I believe they used the AC repair service to gain access to the building. I went to a Schmoocon talk once where a guy hired to test a companies' security actually got a job as a janitor and would plug in a Linux device he built, go mop some floors, then pick up the device which had scanned all their internal networks. So, yes, if you believe you should guard against an attack, then I would say do so.
How do I handle simultaneous concurrent inputs for the same response and request?
Not sure what you mean by this. Spring MVC typically uses session to isolate requests. If two different users request the same thing, they are two different requests for the same thing. I would suggest using some caching so that you are not hitting your DB every time, but other than that I see no problem.
Related
I am building the restful web service. For the put request, I first find the testBean with the id in the pathvariable. If it does not exist, then I create a new one. I am wondering if it is right to create a new one here, or I should throw the exception. Because id is auto increment, if I create a new TestBean, the id saved in the db is different from the one from the url path parameter.
#PutMapping("/Test/{id}")
public TestBean updateTestBean(#PathVariable long id, #RequestBody TestBean newTestBean) {
return testBeanService.getTestById(id)
.map(testBean -> {
testBean.setBRR(newTestBean.getBRR());
testBean.setModifiedDate(newTestBean.getModifiedDate());
return crewsBeanService.saveTestBean(testBean);
})
.orElseGet(() -> {
newTestBean.setId(id);
return testBeanService.saveTestBean(newTestBean);
});
}
I'd always prefer to keep PUT method idempotent. Idempotency can be explained as how many times you apply a certain "operation", the result will be the same as the first time. Since REST is just a style, it's up to you, but I will always question to me if it makes sense to keep the operation as PUT or POST.
What if the client of your service is impatient and access your PUT service multiple times while the first request is being served?. You may end up creating two users. So throwing an exception is meaningful if the ID doesn't exist.
It can be 400 or 404, I don't prefer 404 but prefer 400 because of the following reasons,
1) It confuses the client of your APIs if the resource is wrong or the ID they are using is wrong.
(You can always differentiate in your error response and provide meaningful information, but still, I don't prefer!)
2) By using 404,
you're telling the user the problem could be permanent or temporary
,for instance, say your service is not properly registered with discovery server(eureka) or is crashed, the discovery server will send 404 until you fix the problem.
By using 400,
you're asking the user to try with different input, in this case, with a different ID. This is permanent...
as you said id is auto-increment and the client cannot decide the value, so until the user fixes the problem by going back and request your POST service for a new ID, the request is "BAD" and cannot be processed.
Based on Single Responsibility Principle, you should have methods which are doing only one thing. So for your question, you need 2 methods for each request:
GET - asking the server for an object, in your case TestBean.
POST - save new objects (you don't need an id for these).
And in your front end application you could use the GET to ask the server if it have the requested object, and if not, maybe you can add a form which on submit will make the POST request with the data provided in the form fields.
PUT should only be responsible for updating a record. If the id of your bean doesn't exist, you will have an exception on your persistence layer. You can catch that exception on your API and return one of the 400's response code, such as BAD REQUEST.
For creation you should use POST, an id should not be provided in that case
This would be the RESTful way of doing this.
404 is the correct return code for a PUT to a non-existent resource, because the URL used does not address an extant resource.
If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.
If the server desires that the request be applied to a different URI, it MUST send a 301 (Moved Permanently) response; the user agent MAY then make its own decision regarding whether or not to redirect the request.
https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
I am using spring and enabled csrf with HttpSessionCsrfTokenRepository, I clearly know if the client is sending the csrf token either as _csrf parameter or X-CSRF-TOKEN header for the request spring picks up the token and validates with the token which was generated using generateToken(HttpServletRequest request)
But my question is how does spring does this internally.
My reason for this question being:
1.I have a Rest POST call which takes credentials and validates the
identity of the user. But Since I want to add a csrf token to the
rest call as a layer of security I wanted to add it in the post body
to prevent csrf token leak.
So if I know how spring security filters these tokens internally it would be helpful. I revised the spring documentation but it is mostly how we can use CSRF token in a form with hidden field or meta tags and Ajax call with a header.
And I also would like to hear any comments on my design if it is good to have the token in body( I am convinced because it would not be a simple url parameter to leak the token ) or should I have it in the header. I just dont want to lean to use header just because its simple. Looking for the best solution.
Please shed some light.
There're multiple implementations for CsrfTokenRepository in spring if you want to look into into it. for eg:
https://github.com/rwinch/spring-security/blob/master/web/src/main/java/org/springframework/security/web/csrf/HttpSessionCsrfTokenRepository.java
https://github.com/rwinch/spring-security/blob/master/web/src/main/java/org/springframework/security/web/csrf/CsrfFilter.java
https://github.com/rwinch/spring-security/tree/master/web/src/main/java/org/springframework/security/web/csrf
https://docs.spring.io/spring-security/site/docs/4.2.7.RELEASE/apidocs/org/springframework/security/web/csrf/CookieCsrfTokenRepository.html
https://docs.spring.io/spring-security/site/docs/4.2.7.RELEASE/apidocs/org/springframework/security/web/csrf/CookieCsrfTokenRepository.html
IMO its good (safer - may be?) to keep Tokens on the header because of few reasons that i can think of..
You cannot set token on a body for your GET request. You want to be consistent of all your endpoints (you may not need it today but things change really fast)
Tomorrow if you want to change your Auth model, you dont want to to change your request body. when request body changes you break the contract with clients
If you change your auth model to a authorization server, you can add proxy server (like ngnix?) before your service and lets call it auth-proxy. You can leave all security related things to this auth-proxy and it will inspect the header and do the validations for you. You don't want the proxy to look into your request body and you can focus on your business implementation
Request body is completely related to your business so you can focus on it vs dealing with security related things in your body.
Everytime you create a new Request for a new endpoint you don't want to keep adding tokens in all the requests
It's just my opinion based on my experience.
I am learning Spring security and Spring MVC, but I realized I needed to learn jsp Servlets first and general web programming in a java environment.
I have confusions surrounding the HttpServletRequest and HttpServletResponse objects and how they can be used to add headers to the request and response objects and how they relate to sessions.
As far as I understand, a cookie is a type of header just like Content-type and Accept.
The java servlet api just makes it easy to work with the header by using methods specific to the context in which the header is being used. For example:
response.setContentType(String mimeType)
response.setContentLength(int lengthInBytes)
My confusion starts here.. Cookie is not a String or int, its a object:
response.addCookie(Cookie cookie)
response.getCookies()
Since a cookie is a type of header, can't I just use something like this:
String cookieVal = response.getHeader("cookie")
I'm having difficulty understanding session management and how it relates to the HttpServletRequest and HttpServletResponse API.. What is the HttpSession object for?
HttpSession.getAttribute() // What is this getting??
HttpSession.setAttribute("Bla Bla", "valuetoset") // What is this setting?
You can read the RFC describing Cookies and the related headers, Set-Cookie and Cookie to understand what they are.
You can go through Chapter 7 of the Servlet Specification if you want to understand in detail how Cookies and Sessions are related.
You first need to understand that HTTP is a stateless protocol. This means that each request that a client makes has no relation to any previous or future requests. However, as users, we very much want some state when interacting with a web application. A bank application, for example, only wants you to be able to see and manage your transactions. A music streaming website might want to recommend some good beats based on what you've already heard.
To achieve this, the Cookie and Session concepts were introduced. Cookies are key-value pairs, but with a specific format (see the links). Sessions are server-side entities that store information (in memory or persisted) that spans multiple requests/responses between the server and the client.
The Servlet HTTP session uses a cookie with the name JSESSIONID and a value that identifies the session.
The Servlet container keeps a map (YMMV) of HttpSession objects and these identifiers. When a client first makes a request, the server creates an HttpSession object with a unique identifier and stores it in its map. It then adds a Set-Cookie header in the response. It sets the cookie's name to JSESSIONID and its value to the identifier it just created.
This is the most basic Cookie that a server uses. You can set any number of them with any information you wish. The Servlet API makes that a little simpler for you with the HttpServletResponse#addCookie(Cookie) method but you could do it yourself with the HttpServletResponse#addHeader(String, String) method.
The client receives these cookies and can store them somewhere, typically in a text file. When sending a new request to the server, it can use that cookie in the request's Cookie header to notify the server that it might have done a previous request.
When the Servlet container receives the request, it extracts the Cookie header value and tries to retrieve an HttpSession object from its map by using the key in the JSESSIONID cookie. This HttpSession object is then attached to the HttpServletRequest object that the Servlet container creates and passes to your Servlet. You can use the setAttribute(String, Object) and getAttribute(String) methods to manage state.
You are correct that cookies are managed using headers. There are TWO cookie management related headers: Cookie and Set-Cookie.
Cookie header is sent by the user agent (browser) and will be available in your HttpServletRequest object and the Set-Cookie header is appended to your HttpServletResponse object when you use methods such as addCookie(Cookie).
In Java an HttpSession is established when the first request reaches your application. The Servlet Spec implementation in your container (Jetty, Tomcat, WebSphere, etc) will create and manage the HttpSession. The browser will receive a JSESSIONID cookie which will identify this particular session in the future.
Agreeing with the answers given above, I would like to conclude that Cookie and Session are two different entities in the world of web.
Cookie
Cookie represents some brief information that's generated by server and stored on client(browser). According to HTTP mechanism, browser have to send all the cookies(that have not expired), that server had sent before to browser.
Session
HTTP is a stateless protocol. Unlike FTP and other protocol, where connection state is preserved between multiple request-response transaction, in HTTP connection is established for one request and it's closed when response for that request is satisfied. This flaw in HTTP is present, because it was designed in early days to serve static web pages only. But as web has expanded, it's now used to serve dynamic full-fledged webapps. Thus, it has become necessary to identify users. Thus, for every request served by web-server, a labeling mechanism is required which can identify user of each request. This identification of user of request(whether the request has came from same user, same machine), sessions are used.
Session can be successfully implemented only if web-server can receive any information about the user in the request. One way of making this information available to user is Cookie. Others are URL rewriting, hidden fields, etc.
session.setAttribute() will store information in current session on server side not on client side(browser).
Hope it may help you.
Ok Looks like you want to see the difference between Cookies and Headers. They have different purpose. Cookies are temporary storage of information on client side. Server set the cookies(data) on the response and once set browser send these cookies(data) with each subsequent requests till the cookie expires. But headers are used as hints to browser and server. For ex
setHeader("Content-Type", "application/json");
will inform client to prepare to see a json response in the payload. Since it is a "one time" information there is not need the browser to send that information back to the server with each new requests like cookies.
I am creating a simple RESTful web service with simple types successfully. Now I want to pass an object as argument for web service and get the object as response. My scenario is, Parse the XML message as object by using Jaxb and send the object as request for web service. After that in server side it process the requested object and generates the response xml file and send back it as object.
In URL path i give
"http://localhost:8080/SampleWS/rest/checkXML/username=visolve&password=visolve"
for simple type. But in object I don't know how to give the object reference in URL. Please help me how to solve my problem..
Regards
Bathakarai
Just define a very good-looking domain object. JAXB and JAX-RS will do the rest.
JAXB.
#XmlRootElement
class Regards {
#XmlElement
private long sincerely;
}
JAX-RS.
#Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
#POST
#Path("/sincerely")
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response sincerely(final Regards regards) {
regards.setSincerely(System.currentTimeMillis());
return Response.ok(regards).build();
}
Though you could certainly include the entire XML content in your URL, I would probably shy away from it.
Think of it this way: if you encode the XML in the URL you're potentially adding more work on both ends. Now the server and client will both need to know how to build the URL properly, and check to make sure everything lines up correctly. What if, in the future, you need to offer a JSON or YAML view of the same content? Now your URL might need to include the content-type as well. What about character-encoding?
All this to say, HTTP provides a terrific transport mechanism which already addresses these concerns. Include the XML as the entity body of the HTTP message, and use the HTTP header to identify what content-type you're sending, character-encoding, etc. This will work both ways (the server and client both can send the XML back/forth), and makes better use of HTTP.
Here's a related link which might help with some of the details. And another.
On a side note, please, please, please tell me you don't plan on sending user-credentials in plain text across an unencrypted link.
I have a RESTful web service that responds to /user/{userId} with a marshalled XML representation of a User domain object (using JAXB). What's an appropriate way of communicating back to the client additional details about their request, particularly if it doesn't return the information they're expecting? In a non-distributed Java application, you might have a catch block that deals with data access, or security exceptions. In the event that /user/{userId} doesn't return anything (e.g. the web services persistence mechanism isn't working, there is a security restriction, etc...) how do I include meaningful information in the response to the client?
I don't think DTOs are what I need because I'm not looking for different representations of a domain object. Rather, I'm looking for information about what happened during the request that may have prevented it from returning the information the client expected. Would it be appropriate to enclose the domain object within some kind of ResponseObject that holds the relevant metadata? The downside to this approach is that I'd rather not have my service layer interfaces all have ResponseObject as their return type because I may very well provide a non-RESTful implementation that doesn't have the same metadata requirements.
What's an appropriate way of communicating back to the client additional details about their request, particularly if it doesn't return the information they're expecting.
In the event that /user/{userId} doesn't return anything (e.g. the web services persistence mechanism isn't working, there is a security restriction, etc...) how do I include meaningful information in the response to the client?
This is what the HTTP Status Code is used for in a RESTful service.
To indicate that a requested userId doesn't correspond to an actual user, you can return a 404 Not Found.
To indicate an internal error within your application (such as not being able to connect to the database), you can return 500 Internal Server Error.
The option you are describing - wrapping your returns in a ResponseObject which then includes the true "response status" - sounds an awful lot like SOAP.
The beauty of REST, or at least what people claim, is that you can use the already-existing HTTP response status code to model almost all statuses of your actual response.
If it's really error situation (security problems, no DB connection or even user with provided ID not found), then just throw an Exception. Client receives fault and can behave according to information contained in it.
Which implementation do you use? In Apache CXF, for example, you can define exception handler and render XML for exception yourself, and there you are free to include any meta-info you like.
I would capture the information using exceptions, then map those exceptions to an HTTP response with the appropriate status code. You can achieve this by creating an implementation of ExceptionMapper if you're using JAX-RS, or you can subclass StatusService if you're using Restlet.
http://wikis.sun.com/display/Jersey/Overview+of+JAX-RS+1.0+Features
http://wiki.restlet.org/docs_2.0/13-restlet/27-restlet/331-restlet/202-restlet.html