Hi I have a custom web server written for a lightweight need. Now I need the HTTP users to have session support. Any guidelines would be helpful. Note that I'm not using any servlets.
Its a quite compilcated thing actually, and unless its not a homework or something, this is exactly a kind of things when you should take a step back and ask yourself "do I really need a custom web server here, maybe Jetty/Windstone (just to name a couple) should be enough" :)
Today you need session, tomorrow you'll need some security stuff and voila, you have a full custom web server :)
If you want to stick to java standards you should consider interface
HttpSession
http://docs.oracle.com/javaee/1.3/api/javax/servlet/http/HttpSession.html
Yet another source I think can help you is
Different Session management techniques
I hope this helps
Roughly that will be a Map to hold the session data. Key is the sessionid and value could be any data structure, even another Map to hold key=value pairs.
The sessionid travels as a cookie from/to the client. So you must read the cookie from the request and send a cookie on response like here http://www.rgagnon.com/javadetails/java-0092.html
If you relatively new to the topic I recommend you to read about Session Design Pattern in the Book "Applied Java Patterns"
Related
I have a sort of challenge with a development, basically I need to authorize the user to go/call to certain page/functionality using a token, those pages can be set to require authorization by demand (perhaps setting a param in a database).
The application was made with Struts 1, so what I have been thinking is just intercepting the URL using a filter, check if the request needs authorization, send the token via e-mail and redirect the user to the "insert token" page, then again intercept via filter if the referer was the token page and validate the value, if correct, then redirect to the original request...
However I can't simply recover the previous request, also the filter intercept the ServletRequest and Struts has a more detailed construction, so I can't loose the action or the form objects.
I'm not sure if this is a good approach to solve this need, if so, I need to keep the original request in memory and I'm not sure how to do that.
This is a legacy project and has a lot of pages and controllers, so it's almost imposible just going through every method doing validations.
I would accept any suggest, have a nice day! :)
EDIT
To add more context, the project has many forms made with Struts, so internally Struts map the html form to a POJO, to get them as parameters in the actions's (controllers) methods: ActionMapping and ActionForm. When I create a filter, my params are ServletRequest, ServletResponse and FilterChain objects, directly I don't have the ActionMapping or the ActionForm, but I know they are part of the request structure, so since I don't know how to get them directly, I'm trying to work with the whole request, hence the security and size issues, and also because I don't know how to store a copy of the original request while I'm doing the redirect operation
Given the amount of information Struts likes to pass around, I would be tempted to keep a session somewhere safe for the user's return. This post talks about a similar idea, though you could possibly just keep the sessions keyed by token.
Aware this idea would depend on the environment though, e.g. how quickly the user is expected to come back with the token, and the total number of users this needs to scale for.
I would have considered encrypted HTTP cookies (if your application privacy policy allows cookies).
You can store the required information for later use and expire it after a while. Also, you don't need to be concerned about session storage and scaling. Seems to me fits the bill.
Having said that, there're details that you need to consider. In particular cookie encryption.
Update
A note on big objects in cookie. Creating big HTTP header is not always a good idea. Most web servers even force a maximum on header size (see Maximum on http header values?). You need to serialize the binary data in Base64 encoding which makes it even larger.
If your objects really big (like Struts constructs) that can't fit in the HTTP header. You probably don't want to store them in your in-memory session either. You might want to consider a database backed session if feasible.
Tomcat (if this is your web container) has one JDBCStore and you can configure it. It's not great though, having a database query on each request/response.
An alternative to storing all sessions in database, is to only store that particular object in database and store its associated key in HTTP cookie. This is what I would probably do given the size of the object.
This is basically a trade-off between memory and speed. (I don't know the exact requirements of your application in terms of resources and performance).
After few days looking for a properly solution, I have decided to change the idea, instead of rewriting (in a very unsafe way) the request, I designed a two side solution, from the frontend side I intercept any request using JavaScript, I do an initial validation of the URL and then ask for the token, so finally I'm sending an additional parameter that I can get in the filter, and then after doing the validation, I can continue the original request or create a redirection.
Thank you all for the time and suggestions, I think is better explain what I did instead of leaving this topic in the air.
For a restfull service, does the noun can be omitted and discarded?
Instead of /service/customers/555/orders/111
Can / should I expose: /service/555/111 ?
Is the first option mandatory or are there several options and this is debatable?
It's totally up to you, I think the nice thing about having the nouns is that it helps you see from the URL what the service is trying to achieve.
Also taking into account that under customer you can have something like below and from the URL you can distinguish between order and quote for a customer
/service/customers/555/quote/111
/service/customers/555/order/111
One of the core aspects of REST is that URLs should be treated as opaque entities. A client should never create a URL, just use URLs that have been supplied by the server. Only the server hosting the entities needs to know something about the URL structure.
So use the URL scheme that makes most sense to you when designing the service.
Regarding the options you mentioned:
Omitting the nouns makes it hard to extend your service if e.g. you want to add products, receipts or other entities.
Having the orders below the customers surprises me (but once again, that's up to you designing the service). I'd expect something like /service/customers/555 and /service/orders/1234567.
Anyway, the RESTful customer document returned from the service should contain links to his or her orders and vice versa (plus all other relevant relationships).
To a certain degree, the "rules" for nameing RESTful endpoints should follow the same naming rules that "Clean Code" for example teaches.
Meaning: names should mean something. And they should say what they mean, and mean what they say.
Coming from there: it probably depends on the nature of that service. If you only can "serve" customers - then you could omit the customer part - because that doesn't add (much) meaningful information. But what if you later want to serve other kinds of clients?
In other words: we can't tell you what is right for your application - because that depends on the requirements / goals of your environment.
And worth noting: do not only consider todays requirements. Step back and consider those "future grow paths" that seem most likely. And then make sure that the API you are defining today will work nicely with those future extensions that are most likely to happen.
Instead of /service/customers/555/orders/111
Can / should I expose: /service/555/111 ?
The question is broad but as you use REST paths to define nested information, that has to be as much explicit as required.
If providing long paths in the URL is a problem for you, as alternative provide the contextual information in the body of the request.
I think that the short way /service/555/111 lacks consistency.
Suppose that /service/555/111 correspond to invoke the service for the customer 555 and the order 111.
You know that. But the client of the API doesn't know necessarily what the paths meaning are.
Besides, suppose now that you wish invoke the invoke the same service for the customer 555 but for the year 2018. How do that now ?
Like that :
/service/555/2018 would be error prone as you will have to add a parameter to convey the last path value and service/555/years/2018 will make your API definition inconsistent.
Clarity, simplicity and consistency matters.
According to me usage of noun is not necessary or comes under any standard,but yes it's usage helps your endpoint to be more specific and simple to understand.
So if any nomenclature is making your URL more human readable or easy to understand then that type or URL I usually prefer to create and keep things simple. It also helps your service consumer who understand the functionality of any service partially by name itself.
Please follow https://restfulapi.net/resource-naming/ for the best practices.
For a restfull service, does the noun can be omitted and discarded?
Yes. REST doesn't care what spelling you use for your resource identifiers.
URL shorteners work just fine.
Choices of spelling are dictated by local convention, they are much like variables in that sense.
Ideally, the spellings are independent of the underlying domain and data models, so that you can change the models without changing the api. Jim Webber expressed the idea this way
The web is not your domain, it's a document management system. All the HTTP verbs apply to the document management domain. URIs do NOT map onto domain objects - that violates encapsulation. Work (ex: issuing commands to the domain model) is a side effect of managing resources. In other words, the resources are part of the anti-corruption layer. You should expect to have many many more resources in your integration domain than you do business objects in your business domain.
Resources adapt your domain model for the web
That said, if you are expecting clients to discover URIs in your documentation (rather than by reading them out of well specified hypermedia responses), then its going to be a good idea to use URI spellings that follow a simple conceptual model.
I have a Java web application which stores some data in the session. The data in the session changes as the user interacts with the application (e.g. flow is managed by a controller, each controller has several form pages, on each form page some data is updated in the session and flow goes to the next form page).
The problem is that some users are opening more than one tab to the application, each tab with a different step in the flow. At this point data in the session is messed up since the tabs share the same session (app uses cookie managed sessions).
Telling the users to use different browsers to avoid sharing the same session id (e.g. one Firefox window and one IE window) is not an option since surely at some point somebody will forget to do this and instead use tabs, thus messing up their data.
Adding some verifications that detect that another flow is requested from another tab and display a message to the user saying this is not allowed is not an option either since it pisses of the users and we don't want that do we? :D
The fact is that using another tab is useful for the users because they are more efficient in what they use the application for, so I am keeping this option. But the question now is how best to manage the one session data for the more tabs?
What I thought of, was to have the controller generate a token when it starts the flow and pass this token to each form page which in turn sends it back to identify itself. If another tab requests the same controller action when there is an ongoing flow then generate another token and pass that around.
Basically, I want each flow to have a token and inside the session I won't just keep one set of data but have a set of data for each token and then match requests based on the token.
Now the problem is that this approach will need a lot of rewritings to the application and I was wondering if there is a best practice for managing such a situation or can someone suggest other approaches. I am open to ideas.
Have you encountered this situation? How did you handle it?
This is usually done by assigning a windowId for each tab/window and passing it on each request. Jsf supports this via orchestra. Spring mvc will support it in the next version.
I recently needed this for a simple case, so I implemented it myself. Took half an hour. However, my scope was very limited:
pass a windowId with each request, and return it back for the next request. The first time - generate it.
for any attribute you want to store in the session, put a Map<String, Object> where the key is the windowId
This is exactly what Seam was created to handle. In Seam there's a concept called a Conversation which basically does exactly what you are explaining. Conversations are basically are a way to divide the Session into many pieces that can expire at some timeout. You can look at the source code for org.jboss.seam.core.Manager class to see how it's actually implemented and get inspired ;)
Depending on the complexity of your application, you may want to investigate implementing tabs within your application. This gives you wholesale control over the flow, while still providing users with the functionality they want. I'd argue it's, bugwise, the most robust solution, since you won't have a dependency on the way the browser handles sessions, minimising the number of "known unknowns".
Of course, there'll be potentially a large upfront cost to this, depending on how your application is structured. Without more information about your app, you're the best placed person to decide.
You can also try to wrap your application inside Adobe Air
And then limit your web application to be only accessable from this air. By doing this you dont need to consider the web browser fragmentation and their unique behaviour.
I understood that Serializable means the data can gets convered into 1s and 0s so its availabe to be streamed to web services etc but someone told me that Serialization is also used for preventing data being sent twice if a user accidently double clicks a link for example. is this true
edit: im talking about Serializable class in java
No.
Also, webservices is a completely different area.
Yes it's true. This means serializing http request processing from the same user. In Java webapps this is usually done by synchronizing processing on the HttpSession or on an Object stored in the session acting as a mutex.
Some frameworks do this out of the box. For example Spring MVC does this in the http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/web/servlet/mvc/AbstractController.html:
synchronizeOnSession: whether the call to handleRequestInternal should be synchronized around the HttpSession, to serialize invocations from the same client. No effect if there is no HttpSession.
This solves concurrency issues in the HttpSession which is best described in the classic article by Brian Goetz Java theory and practice: Are all stateful Web applications broken?
Does the Spring Framework use (or in one of the options that it supports) encrypted cookies that store the logged in users userId in a cookie?
This is how ASP.NET authentication works, where it encrypts a value in a cookie, which is normally the userId or username.
Is that what Spring does? (I realize Spring let you choose, but is this the most common approach generally?)
I don't have the source handy to prove this, but the answer to the question is no.
Spring Security handles everything on the server side. The only cookie on the client is the one for JSESSIONID, and the security framework merely checks for the authentication/principal object in the request's session (at least under the default setup).
I don't understand why you would store any sort of authentication information in the client's cookie if you could simply store a sessionID and track authentication details and state on the server side.
Storing user ID or any kind of data the server relies upon is a terrible idea. It typically means as soon as someone figures out how your encryption works (which is only a matter of time, particularly when they have a crib as user IDs tend to be public too) they can probably compromise your system.
In case you're wondering what a "crib" is. see Cryptography FAQ (03/10: Basic Cryptology):
Cryptanalytic methods include what is
known as practical cryptanalysis'':
the enemy doesn't have to just stare
at your ciphertext until he figures
out the plaintext. For instance, he
might assumecribs''---stretches of
probable plaintext. If the crib is
correct then he might be able to
deduce the key and then decipher the
rest of the message. Or he might
exploit ``isologs''---the same
plaintext enciphered in several
cryptosystems or several keys. Thus he
might obtain solutions even when
cryptanalytic theory says he doesn't
have a chance.
Java Web apps typically just store a session ID and that session on the serverside contains such information as user ID. That's much more secure.