is it possible to maintaining conversation during redirect to external url?
I started paypal transaction with CDI conversation bean and next there is faces redirect to paypal page when I log in and doing payment and next paypal returning to my page and I want to have the same instance of my backing bean to remember details which I sent to paypal.
When paypal redirects back to my page, he appends to url transaction token and payer ID but I don't have any information about quantity of products which user bought. So I want to remember the quantity from before redirect. Now, after paypal returns to my site I call method doExpressCheckout and I want to pass quantity and other transaction details because I can set entirely different details than before the transaction and there is possible strange situation when customer accept on paypal page that buying some products for 10$, but I set 100$ after paypal redirects again to my page and customer will have no idea how much he paid.
I don't know why that this happens.
I use SOAP api.
Yes, you can resume your conversation from an external redirect. Just include the cid=nnn in the return URL you pass to PayPal. For example:
returnUrl = "http://myip/myapp/return.seam?cid=" + Conversation.instance().getId();
details.setReturnURL(returnUrl);
...
As the 2 minute default for conversation timeout is rather limited, you will eventually want to increase the conversation timeout before placing the call to PayPal:
Conversation.instance().setTimeout(900000); // 15 minutes
However, doing this is not necessarily a good idea as it keeps data around for potentially a long time, and you need to keep the session cookie as well for this scheme to work (so you must increase the session timeout as well if necessary).
A better strategy would be to keep the transaction data persistently (db or disk), associate a randomly generated ID to the data and retrieve it on return from PayPal. This way you don't need to keep the conversation in memory.
When paypal redirects back to my page, he appends to url transaction
token and payer ID but I don't have any information about quantity of
products which user bought.
You can append the pre conversation id to the url you pass to Paypal as the return url. This way the conversation id will be passed back together with the above parameters and seam will know to restore the prepayment conversation with all the data.
Related
Just like between two servlet there is a payment gateway , servlet1 response goes to servlet2 and from servlet2 it redirected to servlet3 I need to combine the response of servlet1 and servlet3 for generating output.
Its somthing like we are using a payment gateway between two servlet and generating response by combining both servlet response, Please help
I'm not sure I 100% understand your question. For payments, you usually create a token/reference and store that in a DB on the first request/session. Later, after the user pays, the payment gateway will do a HTTP POST to your service, and one of the parameters will be that token/reference. Now you just need to validate the id/token and mark whatever you need as paid.
Try to avoid storing data in the session for any payment related data, as the node where the payment is taking place might go down for any reason while the client is paying... and you don't want him/her complaining that the money is gone, but he didn't get the product/service.
Edit
You have a few options about how to notify the customer. The more traditional answer is (and this works fine for low volumes of transactions):
Customer starts a payment, so the server creates and stores a transaction reference.
Customer is sent to the PSP site.
The customer completes the payment on the device.
The device finds out the payment is 'complete' and starts polling the server with the payment reference.
(time passes)
server receives the async notification from the PSP with the outcome of the transaction (and the payment reference). The server updates the transaction on the DB.
(the device is still polling)... pools once more and finds the outcome of it.
Job done
There are a few more advanced techniques, like async requests, but I would say to not use them unless you are already using them somewhere else in your application OR you have a considerable volume of transactions.
You can add the response of servlet1 to the session and get it in session2
Servlet1:
HttpSession session = request.getSession();
session.setAttribute("sessionResponse", object);
Servlet2:
Object value = request.getSession().getAttribute("sessionResponse");
In our JAVA web application we maintain users' session in a database table active_sessions. And we do not allow multiple sessions per user. what it means is, if you are already logged in with a particular user account, you cannot open a new session with the same account. In case somebody does, we display error 'User already has an active session'. When user clicks on Logout his entry from table active_sessions is removed. But in case where user closes the window without logging out his entry remains in the table active_sessions. So any attempt to login in future results in an error 'User already has an active session'. Any tips on how to destroy user session in database in case he closes the browser window without logging out.
Edit: After reading all the posts it seems there is no clean way to restrict single session per user.
Use the 'onbeforeonload' JavaScript event which can perform an AJAX call to your server to delete the entry. This event will however be executed each time the page is unloaded so if you don't have a SPA then you'll need to ignore the event for href and such.
Agree with Almas however that your approach is dangerous in the sense that it is not possible to enforce this 100%. E.g. if the user kills the browser process then even this JS event would not be published.
Furthermore, a user can simply use another browser to bypass your 'protection'.
In the server side users HTTP session is normally invalided after a certain period of idle time. You can implement http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpSessionListener.html and register it in web.xml to receive notifications about session create/destroy etc. In your listener implementation you could delete the table entry on session destroy event.
The basic thing about HTTP is that it is request/response protocol.
i.e. Things are changed/accessed only by making a request to the server. This 'limitation' makes your requirement interesting. There can be two workarounds for this:-
Poll the server at a repeated interval through an AJAX call. As long as you application keeps getting the polling AJAX request you can assume that the window is open.
Use javascript (window.onunload ) to fire an event to destroy user session when the browser is closed.
Using onuload
Status: Waiting for comprehensive answers with code examples concerning dao, service, controller, view.
With spring 3 + hibernate 4, in a service, dao, controller, view (mvc scenario), like http://www.cavalr.com/blog/Spring_3_and_Annotation_Based_Hibernate_4_Example ,
where is the good place to have authentications before doing something. e.g
Occasions:
Is user logged in? (first check by session , then by data base username password match)
session made? getting previous session on every transaction and authenticating if no session has made.
More authentications for every transaction e.g:
get some value or boolean from database, check if its true (e.g can this user add more users), then proceed.
Does user have permissions? and if authentication fails, how to respond to user?
Ways to respond:
a. Redirect to error page (dont like that though)
b. redirect to the same page with an error message (ok)
c. Do all with ajax, (most preferred) dont reload or redirect page, just authentication by
session and or
database
send error message on the same page by ajax.
proceed if authentication succeeds.
Where to put the logic? in dao, service, controller?
What options do I have?
Can some one give a sample code? I have googled but found irrelevent examples.
I know one solution is spring security, but what do you think? and is there a sample code for it that covers all my questions?
Example scenario:
my scenarios is like this. a user comes and a db query tels/lists the borads he has access to. when he enters a board. the boxes privileges are lists and only readable boxes are shown to him. then same with tasks. each of them has create/read/update/delete permision and that is known/fetched at the time when the user acts for one. e.g tries to create/read/update/delete a board/box/task.
now there are millions of boxes / tasks. loading permissions for each might be insane?
I do not understand how to and where to do the authentication and authorization. daos, services,controllers, and then sending the problems to views as error messages. One dao may call another, one service may call another dao(s) and / or service. all or most may give authorization failures. how to pass the failure strings to view placing them accordingly?
Thanks!
How does play validate a cookie?
I noticed that after I restarted the server I was still logged in even though I
don't presist any session data in the database.
I also noticed
that I could set the date on the server to be larger that the exipry
date of the cookie and still I was logged in.
I logged out
(saved the cookie to a text file) and the browser lost the cookie. Then I
recreated the cookie from the text file and I was logged in again.
The cookie looks like this:
PLAY_SESSION=e6443c88da7xxxxxxxxxxxxxxxxxxxxxxxxxxxxx-userid%3A1
// My logout code
def logout() = Action {
Ok("").withNewSession
}
From the documentation
Discarding the whole session
There is special operation that discards the whole session:
Ok("Bye").withNewSession
You didn't specify how do you authenticate users, so I just guess, that you;re using simple sample which is... simple.
It uses user's id to identify the user, and check if signed session cookie wasn't manipulated, therefore if you'll recreate the cookie with proper signature it will be valid still.
You should create some area for session's keys on the server side ie. in DB or in memory cache (Which will be faster than DB). Its key should be randomly generated (and preferebly quite long) for each successful login action, and should also contain data for identifying user, expiration date etc. Next you should put this random sess_key to the Play's session instead email address of logged user or id of his row in DB, and after logout and/or expiration date it should be removed. In such case even if you'll loose the cookie after logout it will be impossible to login properly with non-esixting sess_key.
AFAIR standard memory cache will be purged at every restart of the application, to make sure that all sess_keys from DB will be removed as well you can use Global object and truncate the table in onStart(...) method.
I found the answer reading the documentation more carefully and combining different parts.
There is no technical timeout for the Session. It expires when the
user closes the web browser. If you need a functional timeout for a
specific application, just store a timestamp into the user Session and
use it however your application needs (e.g. for a maximum session
duration, maximum inactivity duration, etc.).
It’s important to understand that Session and Flash data are not
stored by the server but are added to each subsequent HTTP request,
using the cookie mechanism. This means that the data size is very
limited (up to 4 KB) and that you can only store string values.
So that was what i feared that if the cookie get lost anyone can log in to the server for all future.
What I have to do to secure this is to add a self-made timestamp authorization (save a timestamp in the cookie and validate sever side)
We have a spring security application with a pretty standard setup. Currently we only allow 1 session per principal, rejecting additional logins by the same principal until the first session is logged out or expired (maximumSessions=1, excpeptionIfMaximumExceeded=true).
I'd like to change this so that when a principal logs in a second time with a currently active login on another session the first session is invalidated/replaced. This is easily accomplished using the provided spring security concurrent session control strategy but I am having trouble figuring out how to alert the user. When a user's session is replaced the session is invalidated by the logout handler. The next request will get a redirect to the login page with a error code on the query string. However, if the request which gets this redirect is an image or other non-programatic call I'm unable to handle this.
It seems like I need to put the user into an inbetween state, where they have a session but it is expired and they need to log back in if they didn't mean to replace their original session. However I don't see a good way to do this.
Is there an example of a setup like this somewhere?
Have you thought of working out a polling mechanism in javascript to alert the user when their session is about to be invalidated? This way they will know that their session isnt valid and possibly have a chance to refresh it in case they have partially filled out forms or text areas.
This can also work from the login side. You can add a step after login if they have another session active and have them verify they want to invalidate it.
It seems that an in between step isnt necessary because, generally,authentication should be boolean. Either they are authenticated or they arent. The inbetween zone might be tougher to handle all cases for.