I have made two J2EE applications where in one servlet in ProjectX is performing a sendRedirect to another servlet of ProjectY via https protocol.
Code is something like
response.sendRedirect("https://ip:8443/ProjectY/servletY?id=123");
In ProjectY,
SerletY is having code as
PrintWriter pw = response.getWriter();
pw.print("Passed id is ID = " + request.getParameter("id"));
My Query is ,
since the data sent accross the network is ideally encrypted when using https, why am I able to see the url of the browser after redirecting to ServletY as
"https://ip:8443/ProjectY/servletY?id=123"
I have hidden the parameter using POST method , but my question is , is it actually encrypting data while sending from ProjectX(which was in http) to ProjectY (which is https call) ?
Thanks for you support.!!!
What's happening
There is no POST request involved.
The user opens ProjectX' site in the browser
It will respond with a HTTP 302 response because of your response.sendRedirect.
The user's browser will take the Location of the response and open it
Thus the user's browser establishes an TLS connection to ip:8443
After the TLS channel is opened, it will send a GET /ProjectY/servletY?id=123 HTTP/1.1
ProjectY will respond over the secure TLS channel.
Observations
If you call ProjectX in step 1 via plain HTTP, then the 302 response won't be encrypted and everybody who has access to your connection can see the id.
The user's browser will always see the id because it needs to follow the redirect in step 3.
The user will see the id in the address bar because the browser will show its new location.
When calling ProjectY, the id is protected because it is only sent via the TLS channel.
Related
I am facing an issue understanding the oauth2 flow.
A user(identified by a user_id) initiates the GoogleAccounts connection in the browser.The request is passed to Servlet that sends Redirect String To Client (Javascript), which in turn redirects user to that Auth URL.
On User Consent, the response is returned to callback url (mapped to a servlet).
My Confusion here is when callback servlet is called,how do i identify to which user(user_id) does this authCode belong to?
Do i have to use state param of oAuth2 ?
Please help.
As the comments suggest, the state param is your friend. The simplest way would be to simply set state=user_id. An alternate approach would be to start a server session and store the user ID in the session object. This latter approach assumes you have a relatively simple server, or your cluster supports shared sessions.
I have the following situation that I'm still not able to manage:
I wrote a java class to read a http response from a site that receive POST parameters
I use HttpURLConnection and pass the input parameters
the result obtained is another form that redirect to another page (via HTTPS) to which I have to pass a username and a password and an hodden value. this page show the result in a target page (that is the firt url)
I made a call to this other page via HTTPS (HttpsURLConnection) and obtained a http 302 response code
I'm not able to reach the result page, since the followredirect option doesn't work when the protocol change (from http to https)
Can anyone help me please?
Hope I have succesfully explained.
Thanks in advance for support and regards.
I'm using java.net.HttpURLConnection.
I first write the body of the post request to the OutputStream associated with the URLConnection object.
After I have done that, I close the OutputStream and then call getInputStream() or getResponseCode() or getHeaderFields(). That's when I find out if the provided credentials were considered valid or not valid.
This is problematic, because I don't want to make the same post request again (and have to re-upload its contents, which could include large files) in the event that the user credentials were rejected for some reason.
Since an exception is thrown if there is an attempt to call getOutputStream() after getResponseCode() or getHeaderFields() have been called, how can I ensure that the user credentials were accepted before attempting to upload the data?
Is there a way around this or is it just the way the server is configured?
The short answer is: You can't do that.
Basic auth is stateless. When you're doing a POST/PUT the user credentials are sent as headers for that HTTP request. They are not processed until the entire operation is complete (i.e. after you've sent the data payload).
In order to do what you're talking about you'd need to write a web service that managed login and file/data uploading separately through session management, allowing you to first authenticate (returning a session token of some sort) then send the data via a separate HTTP request.
Edit to add: In reality, you could hack your way around this by simply doing a GET to something that also requires auth. If it succeeds, you know the POST will also succeed baring the credentials being invalidated server side between the two requests. I would not advise this, but it would work.
I am confused on the documentation of the javax.servlet.http.HttpSession.
It says:
Sessions are used to maintain state and user identity across multiple
page requests. A session can be maintained either by using cookies or
by URL rewriting.
Now both cookies and URL rewriting are handled by application code in server (i.e. our code).
Then it says relating to when a session is considered as new:
The server considers a session to be new until it has been joined by
the client. Until the client joins the session, the isNew method
returns true.A value of true can indicate one of these three cases:
1. the client does not yet know about the session
2. the session has not yet begun
3. the client chooses not to join the session. This case will occur if the client supports only cookies and chooses to reject any cookies
sent by the server. If the server supports URL rewriting, this case
will not commonly occur.
I am not clear on when it is considered/meant that the client has joined the session.
I mean if I don't use cookies from my web application (or URL rewriting) and I have the following:
POST from IP A to server
200 OK from server to A
POST from IP A to server
In step 3 will the session.isNew() return true or false? It is not clear to me from the doc.
Will it return false (i.e. the session is not new) and I will have to call session.invalidate() in order to create a new session?
The reason this confuses me more is because I am debugging a piece of code where the client is an HTTP application but not a web brower and I see that in step 3 the session.isNew() does not return true although there is no cookies or url rewriting in the server code.
So I can not figure out what is going out under the hood.
Any info that could help understand this?
Here is a nice example of Session Tracking
Client has joined the session means that client made subsequent request and included session id, which can be recognized by your webserver. If cookies are enabled - jsessionid will be passed with cookies, otherwise - it should be include in the URL itself - like this http://localhost:8080/bookstore1/cashier;jsessionid=c0o7fszeb1.
In JSP c:url from Core Tag Library will handle URL rewriting for you.
In case of B2B communication you have to obtain session id by yourself and include it in subsequent requests manually.
Example:
POST from IP A to server
200 OK from server to A
A obtains session id from the response
POST from IP A to server and includes obtained session id
UPDATE:
Consider reading a great article - "Web Based Session Management: Best practices in managing HTTP-based client sessions." It's a general overview of how HTTP sessions can be emulated and is not tied to Java.
I'm trying to create an android app to check my tests scores of my engineering school. In order to download the Word containing the scores, I need to login to the portal.
I thought it would be simple to do it by sending a POST request.
After bypassing the problem of the self-signed certificate (or whatever) thanks to the code on this page : Self-signed SSL acceptance on Android
I still get an 500 error while trying to send any POST request to the login page, which is here : https://e-campus.hei.fr/ERP-prod/pc_mv_login.aspx
I tried various codes from the web to send the POST data (especially How to do a HTTP Post in Android? this one). And even on a pure java app, I get a 500.
When I point the URL to another testing page, I manage to get it working, but not on https://e-campus.hei.fr/ERP-prod/pc_mv_login.aspx
Could anyone explain to me why it doesn't work or help me get rid of this error ?
EDIT:
This is what is being sent through my browser (According to chrome developper tools)
__EVENTTARGET:
__EVENTARGUMENT:
__VIEWSTATE:dDwxNDU4ODc4MDI5O3Q8O2w8aTwwPjs+O2w8dDw7bDxpPDE+O2k8Nz47aTwxMz47aTwxNT47aTwxNz47aTwxOT47PjtsPHQ8cDxwPGw8VGV4dDs+O2w8SWRlbnRpZmlhbnQgOjs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8TW90IGRlIHBhc3NlIDo7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPExhbmd1ZSA6Oz4+Oz47Oz47dDx0PDt0PGk8Mj47QDxBbmdsYWlzO0ZyYW7Dp2Fpczs+O0A8ZW47ZnI7Pj47bDxpPDE+Oz4+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8Vm91cyBuJ8OqdGVzIHBhcyBhdXRvcmlzw6kgIMOgIHZvdXMgY29ubmVjdGVyLjs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8Q29ubmVjdGVyIDo7Pj47Pjs7Pjs+Pjs+Pjs+inmhCwE9zfymuEXDXGORShkB1GI=
Username:******
Password:******
Langues:fr
Button1:Connecter :
This is the string that i send :
String parameters = "__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE="
+ URLEncoder
.encode("dDwxNDU4ODc4MDI5O3Q8O2w8aTwwPjs+O2w8dDw7bDxpPDE+O2k8Nz47aTwxMz47aTwxNT47aTwxNz47aTwxOT47PjtsPHQ8cDxwPGw8VGV4dDs+O2w8SWRlbnRpZmlhbnQgOjs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8TW90IGRlIHBhc3NlIDo7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPExhbmd1ZSA6Oz4+Oz47Oz47dDx0PDt0PGk8Mj47QDxBbmdsYWlzO0ZyYW7Dp2Fpczs+O0A8ZW47ZnI7Pj47bDxpPDE+Oz4+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8Vm91cyBuJ8OqdGVzIHBhcyBhdXRvcmlzw6kgIMOgIHZvdXMgY29ubmVjdGVyLjs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8Q29ubmVjdGVyIDo7Pj47Pjs7Pjs+Pjs+Pjs+inmhCwE9zfymuEXDXGORShkB1GI=",
"UTF-8") + "&Username="
+ URLEncoder.encode(mUsername, "UTF-8") + "&Password="
+ URLEncoder.encode(mPassword, "UTF-8")
+ "&Langues=fr&Button1="
+ URLEncoder.encode("Connecter :", "UTF-8");
HTTP error 500 just means that the server side code failed. It has a bug, for example a NullPointerException was been thrown over there. If the response body doesn't contain anything sensible (e.g. a stacktrace) so that you could learn how it is caused and so change the request accordingly, then your best bet is to contact the server admin and report about this bug in the server code and ask how to correctly perform a programmatic login.
If that is not an option for some reason, then you should doublecheck if you don't forget to send a specific cookie, header and/or parameter. Probably the server side code was expecting it, but it was null and the code was buggy and hence it totally broke with a 500. I'd suggest to use Firebug to track the entire HTTP traffic and compare it with the headers/parameters you've set. Probably you need to send a specific cookie back? Or you need to send the name=value pair of the submit button? Etcetera.
Update: you're sending the wrong __VIEWSTATE value along. The website runs on ASP.NET MVC which is a component based MVC framework (like as JSF in Java EE). It stores the component tree as "view state". You should not send a random/non-existing/invalidated view state back as paramter, but a valid one. You need to rewrite the HTTP client so that it first fires a GET request on the page with the form and then use a HTML parser (Jsoup?) to extract the value of the hidden __VIEWSTATE input field and finally fire a POST request with exactly that value (and exactly the same cookie in the request header!).
Like as in JSF, the view state is part of CSRF attack prevention. You cannot submit the form without first requesting the form from the website itself in the same session.