Phase 1: I succesfully confirm the user password in a web form using HttpClient and HttpPost.
In this case, the code I receive from the server is 200OK.
Phase 2: Now, let's say the user will attempt to confirm his password again. But he can't do that,
because the initial URL won't exist anymore, so he will be redirected to the login page.
Here's a bit of a difficulty: in this case, server responds again with 200OK, not a redirect code.
How can I differentiate between the first phase and the second?
I tried
serverResponse.getStatusLine().getStatusCode();
and
serverResponse.getLastHeader("Location").getValue();
without luck, as there's no real redirect happening from the server point of view.
I thought about getting the response content and parsing it as html, but I believe that's not a good solution.
I also thought about storing in a boolean SharedPreference the confirmation action, but then there's the case when the user has multiple devices.
Another possible solution is to hide the confirm password fragment, once the user confirms his password.
What do you think it would be a good way to differentiate between phases or to prevent phase 2?
I appreciate any idea.
Thank you.
Related
I have a Wicket 8.6 application. Currently, when logging in to the application, mostly (does not always happen) the user has to login twice. After the first login (after entering the credentials and clicking the submit button) a white page appears saying "If you see this, it means that both javascript and meta-refresh are not support by your browser configuration. Please click this link to continue to the original destination." This is the BrowserInfoPage. After a few seconds the user is redirected to the login page again where he/she has to enter his/her credentials again and press the login button. This time, the user logs in successfully. My question is, how do I prevent that the user hast to enter his/her credentials twice.
From my research I know that it has something to do with the collection of extended browser info. In the init method of my WicketApplication class, I had the following code:
getRequestCycleSettings().setGatherExtendedBrowserInfo(true);
However, I already commented out this code several month ago. For some reason, the described effect occurs for every new deploy now. Maybe a newly added package in the application is the reason for it. I don't know. Is there a possibility to prevent this second login maybe by creating a customized bowser info page which forwards the login? Please point me in the right direction. Thanks.
After some research, I came up with a work around. It is probably not very efficient but it works for me so far. In my custom Session class which inherits from AuthenticatedWebSession, I added the following code.
#Override
protected WebPage newBrowserInfoPage() {
final Request request = RequestCycle.get().getRequest();
if(request.getUrl().toString().contains("LoginPage")) {
if(!isSignedIn()) {
signIn(username, password);
}
PageParametersEncoder encoder = new PageParametersEncoder();
PageParameters parameters = encoder.decodePageParameters(request.getUrl());
String url = parameters != null && parameters.get("originUrl") !=null && !parameters.get("originUrl").isNull() && !parameters.get("originUrl").isEmpty()?
parameters.get("originUrl").toString("pages/home"):"pages/home";
String finalUrl=url.startsWith("pages/")?url.substring("pages/".length()):url;
throw new RedirectToUrlException(finalUrl);
}
return super.newBrowserInfoPage();
}
Some explanation to the code. As mentioned in the question, I want to prevent the user from logging in multiple times. Thus, I check if the request comes from the LoginPage and perform my work around only in that case.
During my implementation, I realized, that the method newBrowserInfoPage is called in the process when I call session.signIn(username,password); on my LoginPage. In this signIn process the authenticate method of my custom Session is called but the signedIn flag in the AuthenticatedWebSession is not changed (keeps false on successfull authentication). Is this a bug? Thus, I have to login again to set the flag to true.
Finally, I read the URL of the LoginPage where I have stored the target URL and forward the user to the target URL.
I am aware this is probably not the best approach but it is the only solution I came up with. If someone has a better idea, I am happy to hear it.
Using Spring 4.2.9
Web-Flow: My web-flow has three pages page-1, page-2 and error-Page
Scenario: User clicks on a link in the email, my back-end code consumes the link and user lands on a page-1(the link in the address bar now is different than what the user clicked on), the user does the required stuff on page-1 and clicks continue button and lands on page-2.
What I need when the user is on page-2:
User presses browser back button they should go to error-Page.
The user had copied the link when they were on page-1 and open a new tab and paste the page-1 link, they should land on error-page.
It's a quite common problem. A simple google search gave some possible solutions. Did you tried them? If yes, then update the question with more specifics on the issue. If not, here are a couple of links:
How to Detect Browser Back Button event - Cross Browser
Solution to browser back button click event handling
You can achieve this by configuring a Spring MVC filter (or interceptor). There you can check if the request is GET and it contains the url that you want to block. If true, you can redirect that request to the error or access denied page.
To prevent the user from resetting values when going back with the browser back button you can put a variable in the conversationScope, variables in this scope are not reverted to their previous state when you use the back button. You can this way set a variable when they reach part 2 and check for it when you load part 1, but for this to work part 1 and part 2 need to be in the same flow.
To prevent the users from using a link again, if they are authenticated users you can save a flag in the database that say they have finished the flow and simply look at the database when loading part 1 and throw an exception if the user shouldn't have access. If they are unauthenticated users (like when doing surveys), give each users a token in the url (the token should be random enough that it cannot be brute forced easily) and store it in your database, when part 1 load check that the token is in the database and when your flow is done remove the token from the database.
If you can't do any of this, you can use cookies, just send a cookie to the user when they arrive on part 2, their browser will automatically send it on any new request so if you see it on part 1 you can throw an exception. But users will be able to delete their cookies to circumvent the protection.
Changing page-2 to end-state solved the problem. The solution was mentioned in "The Definitive Guide to Spring Web Flow".
Thank you all for your help.
I do have a sensitive user input entered by user. When user submits the page, it will sent to second server (https) (to which sending this sensitive data is fine) through javascript form submit. After that server process some, it will be returned to main server(https) with that sensitive input.
Problem here is, I cant bind this input to beans deployed in my server (as my server is not compliance certified). So when second server posts the values back, it is getting lost as it is not bonded. It may be really bad situation, but this is what happens.
Please help. Thanks in advance.
You could put the value in session scoped variable.
I am making a module for a server software that is allowing support for facebook.
The problem is with the callback URL. If one client start the authorization proccess, then another client starts the proccess at the same time, or before the first user finish. How could I check what user finished first?
I need a way to check what client's callback I'm getting. One solution would be to lock other from register until the first one has finished, but I don't want to do that. Is there another way? I have thought about including ?client=clientid at the end of the callback, but I heard facebook only allows the exact url specified in the app on facebook.
UPDATE
It didn't work to add client="clientid" to the callback. Any other ideas?
After some more searchig I figured facebook will allow a parameter: state. (thanks to #jacob https://stackoverflow.com/a/6470835/1104307)
So I just did ?state=clientId.
For anyone using scribe the code is this:
service.getAuthorizationUrl(null) + "&state=" + clientId;
I think there is no problem on adding and GET parameter like client=clientID. Facebook will redirect you to the URL you have specified and using the REQUEST parameters you can check who completed the request. The problem exist if you have specified URL as http://yoursite.com and pass redirect to http://some-sub-domain.yoursite.com or entirely different location.
if you are using the server-side flow then the oauth 2 flow will be:
redirect user to facebook
facebook then rediects the user to your specified callback
your server uses something like curl to get the access token
your server does some more curl to get maybe more user data or update the user's data
my recommendation would be to set a session cookie in step 1 and simultaneously store this session id on your server. then the session cookie will automatically be sent to the callback url in step 2 and you can identify the session in the database this way.
this will work for all service providers (google, twitter, linkedin, etc) and is the preferred way of maintaining session continuity.
I have a jsp page in my project where user fills up the details for creating an account.
when a user enters username and clicks on the check button, the button looks in the database if the same name exists or not(it is able to check because of the servlet code).
If username exists it shows not available.
Now the problem is even if username is not available when user clicks on sumbit button with existing username the details get saved. how to correct this?
(I'm nt able to post image otherwise it would have been more clear.)
Just add an if-else block to your servlet, something like this:
if (usernameExists) {
showError();
} else {
saveUser();
}
Do not do this:
if (usernameExists) {
showError();
}
saveUser();
I'd also add an UNIQUE constraint on the username column in the DB so that your DAO throws an SQLException or like.
See also:
Our Servlets wiki page - contains a basic Hello world example with server-side validation
First, you serlvet accepting the HTTP POST must validate the data sent to it, when the user clicks a button, if the receiver doesn't validate the information then bad data will get into your system regardless of what you do in the JSP.
Some people send raw HTTP POST messages from time to time just for fun (I don't know why :) ) to see if bad data can get into poorly written web applications.
Once the servlet accepting the POST rejects bad data, you can have it redirect back to the offending web page, filled out with the information that was sent in the bad request, perhaps highlighting the offending field or fields.
Later on, if you have the time, you can write up a bunch of javascript to pre-check the fields and deactivate the submit button. This saves the back end servlet the bother of receiving so many bad requests; however, you cannot use such a technique to avoid fixing the back end servlet. There's too many ways your servlet could get the POST message that don't involve your specific javascript code working.