I have developed an application which contacts a Sun One web server. The Web Server has Lotus domino and SiteMinder Plugin.
Below is the URL for the application
http://HostName.example.com
After hitting the URL in the browser, the URL is redirect to webserver and a login page appears with below URL.
http://HostName.example.com:9898/SiteMinderagent/forms/login.fcc?TYPE=
33554433&REALMOID=06-1716e557-15f3-100f-b9a4-835cc8200cb3&GUID=&SMAUTHREASON=
0&METHOD=GET&SMAGENTNAME=$SM$sHjbzl4f9R%2bcSa0%2fEgnu6oUQQPMQnUgkU6Zvx5zWZpQ%
3d&TARGET=$SM$http%3a%2f%2fshivalik%2ered%2eiplanet%2ecom%3a9898%2fvalidation%
2findex%2ehtml
After logging into the application, the request is redirect using the TARGET parameter( URL is decoded in the application) from the URL Now the login doesnot work if i block the HTTP requests. As the TARGET parameter is a HTTP request, I am unable to login into the application.
Is there any way I can change the TARGET parameter to HTTPS. Can i know in which file I can change it in the WebServer. The Sun One Web Server runs Solaris OS. I have tried hard finding the solution as I think the URL is appended with Query strings like SMAGENTNAME, SMAUTHREASON, TARGET in the Servlet of the Domino.
The TARGET parameter is populated with the URL originally presented by the user - i.e. in your example http://HostName.example.com will result in the TARGET query string parameter containing the same URL plus the other parameters generated by the SiteMinder agent.
Possible solutions in your case could be to hardcode the TARGET by putting something like the following on the top of login.fcc:
#TARGET=https://hostname.example.com/
That would cause the FCC to ignore the query string parameter that is POSTed and instead will hardcode it.
Alternatively if you need to preserve the path component of the URL (e.g. http://hostname.example.com/path/to/file.html) you could add some javascript to the FCC page. The standard implementation populates TARGET into an element so you could use JavaScript to parse the value and replace http:// with https:// if required. Make sure that your Agent Configuration has single and double quotes in BadFormChars (BadFormChars=%22,%27) to prevent XSS attacks.
There is also an Agent Config parameter HttpsPort that you can use to "trick" SiteMinder into thinking you're serving HTTPS traffic out of port 80 but you will have to test for any unintended side effects.
Related
The Problem
When redirecting from a servlet using response.sendRedirect(redirect_url);, the JSESSIONID cookie is not passed by the browser to the destination. A new JSESSIONID is created for every redirect, and it is impossible to track the user.
Note: This problem is only occurring on my new server implementing https and a domain name; the session ID is properly tracked when I run the web app locally or on another server without SSL or a domain name. Edit: I have set up another site on my server without SSL, and the issue persists. This seems to narrow the issue down to having a reverse proxy Apache.
An Example
The Login servlet on my web app attempts to store the user information in a session attribute then redirects to the MyCards servlet. I am using a redirect so that the URL will display mydomain.com/MyCards instead of mydomain.com/Login. The MyCards servlet attemtps to access the session attribute but finds nothing, and therefore redirects back to the Login servlet. This worked perfectly before deploying the project on my new server with SSL and domain name.
My Setup
Ubuntu 20.04 on DigitalOcean droplet
Apache Web Server (apache2) ... I have enabled mod_sessions, not sure if that's relevant.
Tomcat 9
Reverse proxy in Apache VirtualHost to Tomcat (I can post my .conf file if requested)
A redirect in Apache VirtualHost from HTTP to HTTPS
JDK 11
Possible Solutions
Using a forward instead of a redirect. The session ID is not lost when using requestDispatcher.forward(request, response);. As I mentioned above, I want the URL to reflect the destination for an intuitive user experience, which does not occur when using a forward.
Implementing your own session cookie, as in this answer, and manually storing sessions with a map, as in this answer, which strongly advises against such a facility. Based on my understanding, doing so poses security threats to user data. Also, if the browser is not passing the JSESSIONID cookie, I don't understand why it would choose to pass the manually implemented cookie unless the SameSite attribute is set to None (also bad).
Verifying that the webapp's context.xml does not have cookies="false" configured. Done that.
Using encoded URLs with response.sendRedirect(response.encodeRedirectURL(url));. Again, for the sake of having a clean URL (which the user could bookmark or type in) is preferable, and encoding the session ID into the URL is not.
Using relative URLs instead of absolute URLs...
"A session is only maintained if the redirection is being sent on the same port, host and webapp [and protocol?]. If redirection is done within the same application, using relative paths is the best practice." I tried both redirect_url = "/MyCards" and redirect_url = "MyCards", no luck.
Possible Reasons
Perhaps I am unknowingly switching between HTTP and HTTPS, which is a change in protocol and will not preserve the session ID. Of course, my intention is to remain secure and stay exclusively in HTTPS. Edit: I have set up another site on my server without SSL, and the issue persists. This seems to narrow the issue down to having a reverse proxy Apache. When accessing the web app directly on Tomcat (i.e. with <server_ip>:8080/MyWebApp), the session is tracked properly on redirect. However when using mydomain.com, the session ID is lost on every redirect.
Something to do with naked domains.
Other?
Edit: Maybe the issue is occurring because of the way the client, Apache, and Tomcat interact via the reverse proxy. Does the proxy cause the domain/port to change on every request/response?
My Questions
Why exactly is the session ID lost when using a redirect to a relative URL to a servlet in the same web app on the same server? Shouldn't the redirect occur entirely on the server-side, preventing a new request/session from being created? Since the relative URLs (which I thought would preserve the session) did not solve the issue, does this indicate some problem with my server setup (e.g. unintentional switching between protocols)?
What is the best practice for maintaining the user session ID, even when the user has cookies disabled? Is there no way around URL encoding when cookies are disabled? Or should the app be implemented exclusively with forwards rather than redirects? If so, is there a workaround to changing the URL to reflect the destination?
Note: this is my first post, so I don't have the reputation to comment. I will edit the post with any needed information.
I design web-application based on Java servlets and I'm going to use swfupload (it is Flash component) for uploading files by users.
Problem is that Flash can not send cookie to server. So I need way to add session ID to callback url for Flash. Servlet container can do it (method HttpServletResponse.encodeUrl), but it works only if cookie disabled in browser or SessionTrackingModes is URL.
Is there any way to get URL encoded with jsessionid independently from any other settings?
I found that servlet specification requires sessionID to be encoded as path parameter (delimeted by ; (semicolon)) and its name must be "jsessionid".
So I could simply append ';jsessionid=' to URL and it should work with any servlet container.
Can we read cookies using core-java, that has been written using .NET MVC code? I have not find any help how to read cookies using core java code?
More Background Details -
Actually we have a java desktop application and we are planning to launch that java desktop application using JWS and that is working absolutely fine.
The issue is -- we ask some user related information from user on web page and launch java desktop application using JWS. Now we would like to have that information provided by user on web page in our java application.
We have write that information into cookies and how can we read that information from java code ?
Yes, you can receive cookies that have been set by another application (as long as the path value in the cookie matches). Cookies are part of the HTTP protocol and it does not matter how thay were defined. The client sends them in future requests depending on the URL path.
To access cookies in Java, have a look at getCookies() in HttpServletRequest.
update
The cookies set by your web-application that launches the Java client will have been set in the context of the browser client. Cookies are added to a HTTP response and cached by the client receiving them.
In the case that you describe you cannot access the same server-session from the Java client without trickery.
The solution I would use is to generate a unique ID in the web-app that is passed as argument to the Java client which can in turn request the values needed from the other session using a fetch of a URL using the generated ID as parameter. (This in essence connects the two HTTP sessions as being part of the same user process.)
For instance you could use a HttpURLConnection and a URL like <web-app>/data?id=<ID> to fetch/download the values as XML from your web application.
Core-java? Then try java.net.*:
A cookie is just a header line with "Set-Cookie: " before the URL content.
http://www.hccp.org/java-net-cookie-how-to.html
I have a design like that:
There is a core part runs Spring on it with REST.
There is another part which has a Tomcat Server and has just HTML files(not jsp or anything else.) So if I want to change a page at tomcat side there is no need to restart application also design and code part separated. Let's accept that I am listing users at my web side(tomcat side). Then my web side makes a GET request and response comes as JSON. PUT, DELETE and POST happens with same methodology.
I have 2 security problem at this point.
First, When a user wants to see an URL at server side how I will check authorization and authentication? And how can I limit an authorized person to get my web page with a too wget?
Second, How can I hide my REST URLs. For example if a user debugs my JavaScript code he/she will see that I am making a DELETE request to an URL with some parameters so he/she will try to do the same(or can make thousands of GET request to my core server if learns the URL)
Thanks for advices.
Firstly, why do you use Tomcat to serve static files ?
The approach I would take is this one:
use a static server to serve static files (apache, lighttpd, nginx).
This server will do authN and authZ (using an LDAP directory e.g. or any other suitable auth backend).
AuthN is done using scheme like Http Basic + SSL, Http Digest, WebID, ...
This is a solution to your 1st problem
Configure the static server to reverse proxy your app server and use the same auth rules.
URI are not "hidden", but they are no more accessible to anyone. Since the user is already authenticated to the static page, no auth should be necessary to request "rest uri".
Is there anything in the Servlet spec, Tomcat, or Wicket that will allow a webapp running behind mod_proxy to determine the non-proxied URL of the request?
We need to send out emails with links in them. I had been using the following bit of Wicket to construct URLs to specific pages in the app:
String relURL = RequestCycle.get().getRequest().getRelativePathPrefixToWicketHandler();
RequestUtils.toAbsolutePath(relURL);
Since the emails don't go back out through the proxy, of course the URLs don't get re-written, and end up looking like http://localhost/....
Right now the best I can do is to hard-code the URLs to our production server, but that's setting us up for some debugging headaches when running on dev/test machines.
Using InetAddress.getLocalHost().getHostName() isn't really a solution, since that's likely to return prod1.mydomain.com or somesuch, rather than mydomain.dom, from which the request likely originated.
As answered for the question Retain original request URL on mod_proxy redirect:
If you're running Apache >= 2.0.31 then you might try to set the
ProxyPreserveHost directive as described here .
This should pass the original Host header trough mod_proxy into your
application, and normally the request URL will be rebuild there (in
your Servlet container) using the Host header, so the schema location
should be build using the host and path infos from "before" the proxy.
Is there anything in the Servlet spec, Tomcat, or Wicket that will allow a webapp running behind mod_proxy to determine the non-proxied URL of the request?
No. If the reverse proxy doesn't put the information that you require into the message headers before passing them on, there's no way to recover it.
You need to look at the Apache Httpd documentation to figure out how to get the front-end to put the information that you need into the HTTP request headers on the way through. (It can be done. I just can't recall the details.)