Apex Listener and SSL and client side certificate validation - ORDS, SODA & JSON in the Database

I am wondering if it is possible to do SSL with the new Apex Listener. I also need the ability to do client certificate validation as well. Also in conjunction with the client certificate validation I also need to be able to capture the CGI Environment variables. In the modplsql configuration you just added the following to the marvel.conf or dads.conf.
PlsqlCGIEnvironmentList SSL_CLIENT_S_DN_CN, SSL_CLIENT_S_DN_O, SSL_CLIENT_S_DN, SSL_CLIENT_CERT, SSL_CLIENT_I_DN_CN, SSL_CLIENT_S_DN_Email, SSL_CLIENT_I_DN_UID, SSL_CLIENT_I_DN
Thanks 

SSL can be configured through the host application server in which you've installed the ApEx Listener, just as with any JEE application on that server. CGI Environment variables cannot be configured with the most recent EA version of the listener, so if you need this:
1. Let Oracle know that this is important to you.
2. For the time being, stick with modplsql. 

The listener passing every header that is sent in from the client. It's a simple 3 line for loop so if it's sent from the browser, it's sent into the plsql's cgi env.
-kris 

I guess it would just be nice to get rid of the apache all together and just do a standalone OC4J. 

I'm also trying to do something similar. I would like to pass the SSL environment variables through and access from apex. You say that everything from the browser is passed through. The SSL environment var's aren't determined at the browser are they? Don't they come with mod_ssl or mod_ossl?
What I'm trying to do: Get the DN of the client's cert from an apex custom login using standalone oc4j with ssl and apex listener. Is this possible? 

I tried to combine APEX Listener with Pound (http://www.apsis.ch/pound/). It seems to work. Pound translates https to http and transforms the client's certificate into additional http headers. APEX Listener passes these headers as CGI variables, so I can extract them from pl/sql using OWA_UTIL.GET_CGI_ENV. 

So is that the issue? There is no way to get the cert info to the pl/sql unless it is passed in through http headers. My jsp can print the DN string. I wonder if I can modify the apex war, add a filter, and put that info on the request header.
Any thoughts?
Rob 

This is exactly the problem I am having too. We had a working solution with mod_plsql but since moving to the APEXListener we have really been struggling to figure out how to pass client certificate information to the plsql CGI environment. Any help would be greatly appreciated. Thanks
Jon 

I modified the apex.war and added a servlet filter to put the X509 cert info into the header and it worked like a charm. 

Can you develop this info ?? 

I was able to get Rob's solution working. Here is the general overview.
Problem: We are running the apex listener with Tomcat 5.5 with no http server on the front end. We are attempting to get mutual authentication working. Information from the clients X509 certificate (the one installed in their browser and used for mutual authentication) is not showing in owa_util.print_cgi_env. We found if we manually put the certificate variables we are interested in, into the header of the request it will work.
Solution:
- Add a java filter (http://www.oracle.com/technetwork/java/filters-137243.html)
* The basic procedure configuration is in the web.xml of the apex listener
* The code is java. It gives you access to the request
* The idea is
1. Intercept the request before it makes it to oracle
2. Read the client x509 cert in the filter and add it to the header of the request (javax.servlet.request.X509Certificate )
At this point owa_util.print_cgi_env will have access to anything you put in the filter. Just a note to further complicate the issue. If you do have apache running as well as tomcat you can modify the headers in the httpd.conf without adding this filter.
Basically there is some syntax (don't quote this) but something like:
Header add MY_VARIABLE "%{APACHE_VAR}e"
Where MY_VARIABLE is whatever you want to call the variable(this is what will show up in owa_util.print_cgi_env. And APACHE_VAR is a list of apache variables that you have access to. There is a list of the available http://httpd.apache.org/docs/2.2/mod/mod_ssl.html. Listed in the available apache variables are client cert info. Hope this helps someone get a general idea of how they can approach the problem.

Related

HTTP server: ORDS or Tomcat or Apache

Our current APEX configuration uses Oracle OHS with mod_plsql on Linux. In this situation, it is clear that the browser connects to OHS, makes a HTTP request and OHS hands that request to the APEX engine in the Oracle Database via mod_plsql which satisfies the request and returns a response back to OHS and back to the browser. When using ORDS in standalone mode, the browser connects to ORDS which uses JDBC to connect to the APEX engine in the Oracle Database which satisfies the request and returns a response back to ORDS and back to the browser. Questions: 1. When ORDS is deployed in a Apache Tomcat container, I am not sure I understand how the data flows. Who acts as the web server in this case, ORDS or the Coyote HTTP connector inside Tomcat? What component connects to the APEX engine? 2. When Apache and Kerberos are thrown into the mix as shown in Single Sign-On for APEX applications using Kerberos  same questions, what component does what exactly? Thanks
Just thinking out aloud, trying to understand the architecture.. 1. When using OHS with mod_plsql, the <Location /pls/apex> section "invokes" the mod_plsql handler by "SetHandler pls_handler" and the PlsqlDatabaseUsername/ PlsqlDatabasePassword/PlsqlDatabaseConnectString/PlsqlDefaultPage directives control how to connect to the APEX engine. Easy to understand. 2. But when the path is browser -> Apache -> ORDS -> Tomcat -> APEX engine, the "ProxyPass /apex http://localhost:8080/apex" directive takes the incoming browser request and forwards it to ORDS. But a) who is listening on port 8080, is it ORDS or Tomcat's Coyote HTTP connector and b) who connects to the APEX engine? 3. If we configure OHS to use mod_auth_kerb without using ORDS/Tomcat, how would the data flow be in that situation? Apache would receive the HTTP request from the browser and do what with it? 4. With OHS/mod_plsql, Apache is serving the HTTP requests and it is a proven work-horse used around the world so we can be certain it will handle the load. But in these other scenarios, *if* Apache just hands off the request to other servers, does that introduce a bottleneck if the other servers have a lower throughput? Thanks
2.a) Tomcat listens on 8080. By specifying /apex (or /ords, depending how you installed it) the application ORDS receives the request.b) ORDS connects to APEX using JDBC 3. If you don't want to use ORDS, then the path /pls/apex should be secured with mod_auth_kerb in OHS. There is no proxy directive needed. 4. no bottleneck there. If you want to optimize the communication between Apache and ORDS, use AJP instead of HTTP as the communication protocol.
Niels - Thanks for jumping in, appreciate it. One more question, if you don't mind. Using the SPNEGO filter in Options for Windows Native Authentication with APEX | W.P. Hill Tech seems like a quicker option to implement Windows integrated authentication with Kerberos without setting up a keytab file since it uses the concept of a trusted user (SPN). It also doesn't use Apache so there is one less moving part. Couple of questions about the SPNEGO option that I am not sure I understand...I have reached out to the author of the article as well. It says  “Because of this, we made a second “non-sso” version of the listener on the same web server”.  I am not sure I understand how to implement this. I assume we copied $CATALINA_HOME/webapps/apex.war to $CATALINA_HOME/webapps/apex-public.war and used java -jar to configure it. But as per the instructions in http://spnego.sourceforge.net/spnego_tomcat.html all the configuration appears to be “global” i.e. it would apply to *all* Tomcat webapps. So how would Tomcat know to use the SPNEGO filter for /apex but not for  /apex-public? Also, by cloning the ORDS webapp, I guess if there are any Oracle configuration changes (e.g. change to Oracle listener, password change for APEX_PUBLIC_USER), it would have to be done in both webapps, right?
The point on the SPNEGO Tomcat security is this:In Tomcat – to you apply a filter – say the Spenego filter to your web app, you would add the Spnego filter (per their documentation) to your WEB.xml, then add a filter to your WEB.xml like such:<filter-mapping><filter-name>SpnegoHttpFilter</filter-name><url-pattern>/f</url-pattern></filter-mapping>This means that any references to http://host:port/apex/f… will enforce the SPENEGO authentication.Well, what if you want to have PUBLIC pages? If I am on an internal corporate network, this may not be an issue.In some cases, we used web service style calls, and did not want the authentication. In that case, we simply setup a second listener that did not enforce authentication.The applications that needed it would either re-direct or fail authentication.Public applications would use the other listener that did not require authentication.-- Tim St.
P.S. For Kerberos style SSO, the easiest method (I think) is to use a Waffle on Tomcat hosted by a Windows server that is part of the network.Waffle - Windows & Active Directory Authentication Framework for C# and Java --Tim St.
Tim - Thanks for jumping in. Let me make sure I understand. 1. I followed the instructions on http://spnego.sourceforge.net . A SPN for the Tomcat server has not yet been  added to AD but since the default filter-mapping applies only to *.jsp I thought it wouldn't affect Tomcat as long as I don't request URLs ending in  JSP. But to my surprise, even the Tomcat homepage at http://host:8080 gives a HTTP 500 error and the logs/localhost.yyyy-mm-dd.log has the error  18-Nov-2014 09:24:30.286 SEVERE [http-nio-8080-exec-1] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [jsp] in context with path [] threw exception [GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)] with root cause java.security.GeneralSecurityException: Checksum failed Why is this? Is this just the way Tomcat works i.e. all filters should successfully initialize for Tomcat to even come up, regardless of the URL requested? 2. What is the syntax for the <url-pattern> command? Does it do regular expression matching on the full URL, including the query string? To match all APEX URLs, shouldn't it be /f?p= instead of just /f ? What about accept processing? The URL for that is /apex/wwv_flow.accept, should this be added to the spnego filter too? I didn't see any documentation on this on the SPNEGO SourceForge site 3. When you say "we simply setup a second listener that did not enforce authentication", can you clarify how you did this exactly? Did you copy apex.war to, say, apex-public.war and use http://host:port/apex-public/... to serve public content? But if the SPNEGO filter applies to the entire Tomcat instance, wouldn't it apply to this as well? Maybe this goes back to my questioin #2 above i.e. did you specify the url-pattern as /apex/f?p= so it will skip the public webapp? 4. IMHO the SPNEGO filter works very well but it appears to be very fragile, even a minor configuration error results in a HTTP 404 or HTTP 500 and troubleshooting is a pain. Is it really recommended to use this in a Production environment? 5. Yes, Waffle does look like a easy, plug-and-play solution but it doesn't work on Linux so we would need to install Tomcat/Waffle/ORDS on a Windows server. Will look into this. Thanks. Thanks
#1 is an Apache Tomcat question.  I don't know your server seutp, so any advice I have would be just guessing.  Note- don't but the filter at the HOST level, put it at the APP level.  Configuration and Capability at the host does not mean implement the filter at that level. #2 URL pattern syntax - make it whatever works for you. The ?p=xxx is parameters.  Not sure if the pattern match picks up on parameters. #3 Yes - you can simply re-name the .war file to what works for you.  It will deploy with that name.  I still like apex.war - even if oracle changed it to ORDS. #4 SPNEGO is used in several paces as a part of larger setups.  Keep in mind - Tomcat does not hold your hand.  It is brass tacks.  It will do some nice things, but you can make a mess of it.  It needs to be controlled like any code.http://www.oracle.com/technetwork/articles/idm/weblogic-sso-kerberos-1619890.html I noticed you started another thread on the subject regarding IIS.  Hopefully you get some traffic on that thread. -- Tim St.
Thanks. One last question, followup on #1. Tomcat host vs webapp config - This is something that I have still not completely grasped.  The SPNEGO documentation instructs us to put the FILTER XML fragment in $TOMCAT_HOME/conf/web.xml which is what I guess you are referring to as HOST level. What is meant by APP level? I see a file $TOMCAT_HOME/webapps/apex/WEB-INF/web.xml with one single WEB-APP tag. Is this where I stick the SPNEGO FILTER settings so they only apply to that particular path/webapp?  And if that's the case, does the url-pattern parameter still matter i.e. would the filter only kick in for all requests served by the apex webapp? [I must say, I find Tomcat setup very frustrating. As you said, it is very powerful but there are simply too many configuration options and knobs to tweak, multiple ways to achieve the same end-result, the documentation it not exactly clear and there are minor variations from version to version, sigh...]
And if I do put the filter settings in $TOMCAT_HOME/webapps/apex/WEB-INF/web.xml, where do I put the spnego-r7.jar, login.conf and krb5.conf files? Right now, they are in the $TOMCAT_HOME/lib directory, But there is no lib directory in /webapps/apex, so do I create one? I am generally uncomfortable with a hit-or-miss/trial-and-error approach like this but looks like that is the Tomcat way :-(
Tim - Another observation on your suggestion to "Note- don't but the filter at the HOST level, put it at the APP level". This makes sense, but as I found out, it can be dangerous since the default settings for Tomcat are autoDeploy=true and unpackWARs=true. So apex.war is automatically exploded and deployed. Now, I can certainly create/modify files in the apex directory tree like WEB-INF/web.xml or add .conf and .jar files in there. But if the WAR file is subsequently touched inadvertently, Tomcat will silently and automatically wipe out the apex folder and re-create it from the WAR file, as I found out to my horror. Given the dizzying number of situations that can cause automatic redeployment, not to mention Oracle releasing a new version of APEX.war being released which would blow away all our custom changes and re-create the apex directory, I would prefer to stay away from making any custom changes inside the apex directory. It may be better to put the SPNEGO filter configuration at the HOST level instead. This way when we upgrade to a new version of Tomcat (in a new directory apache-tomcat-x.y.z), we can make sure to compare the copy over any custom modifications we may have made at the Tomcat HOST level. Having said that, it appears that Tomcat 8.0 now includes built-in support for SPNEGO/Kerberos authentication. But configuring it involves setting Authenticator valve attributes on the Context element. However, by choosing the autoDeploy=true option, APEX does not have a explicit Context element defined in the META-INF/xml file so we can't really setup the SPNEGO related Context/Authenticator valve attributes :-( Your thoughts welcome, I am just trying to get up to speed with all this stuff. It is definitely not as straight-forward as it initially appeared. Thanks
This is more of a Tomcat issue, relating to how Tomcat makes this SPNEGO functionality available to web apps. If you need to, you can edit ords.war to add in the Tomcat specific deployment descriptors, before deploying the ords.war to the application server. Use something like ANT (ant.apache.org) or a bash script to unpack ords.war to a temporary location, add whatever Tomcat deployment descriptors are needed, zip up the folder into a new ords.war and deploy that. Since this is a Tomcat specific issue, any issues with this specific functionality would need to be raised with the Tomcat folks, it is not something we have used or have expertise on.
Colm - Thanks for your reply. Hmm unpacking ords.war, modifiying the web.xml to add Context and Authenticator valve settings for SPNEGO authentication and re-packing it as ords.war seems like more trouble than it is worth. I would rather use the Oracle-provided WAR as-is so there are no issues with Oracle Support and with subsequent upgrades to ORDS. Fortunately, I was able to get the SPNEGO filter working with ORDS on Tomcat and instead of using a keytab file it uses the password for the SPN pre-auth domain account in the Tomcat web.xml file so one less moving part. Thanks again.

Tomcat, LDAP, SSL, Servlet

Hi - I have already written a servlet that binds against a LDAP Server normally. Now I need to implement SSL on it. I would like to know if anyone has any code that simply binds against an LDAP Server using SSL.
I use the servlet on Tomcat to connect to the LDAP Server .. so...
1. Do I need to install JSSE alongwith Tomcat to use ssl?
2. Since the servlet acts as the Client to the LDAP Server - is it enough to simply add ssl parameters to the code (and include a cert store path)?
I would only require to know simple steps to ssl-enable my existing application ...
please help! 
I had problems getting SSL to work. The only modifications that you should need to make are in the connection.
Here is the URL.
http://forum.java.sun.com/thread.jsp?forum=51&thread=322566 
Answer is here: http://forge.novell.com/modules/xfmod/newsportal/article.php?group_id=1122&msg_id=233&group=novell.devsup.tomcat

Adding Authorization Http Header to a Request from Client

I have 2 web applications, running on Jboss and Oracle As,
in the same network. The application on Oracle As uses basic
authentication. The application running on Jboss has no authentication, basic, form or digest, but the request
is to implement an authorization against the Oracle As, so the oracle users will have also access into the jboss app.,
a sort of sigle sign on between the two servers.
I find out the solution to authenticate through the java code using
Authenticator.setDefault, ( this is my post http://forum.java.sun.com/thread.jspa?threadID=787326&tstart=0 )
but when I try to click a link to a secured page in Oracle As I still receive the basic popup asking me for user and password.
Therefore I need to add authentication information to the http request
header sent by the client running on jboss when open a secured page
from the second app, running on Oracle As.
The application on Oracle Aps uses basic authentication so I just need to add the
"Authorization: Basic <base64 string>" header. I checked with http://web-sniffer.net/ to see exactly how this header should look like.
Could anybody offer an example to demonstrate how to add the Authorization header? Thanks.

How to use  SSL Technology in JSP.

Can anybody Tell me that How to use SSL Technology in JSP ?
I am using Apache Tomcat 5.0.28 Server.
How to configure the Tomcat server so that it will access any web application supported by Tomcat via SSL ?
Thank you very much in advance. 
Deactivate the non-ssl listener port in server.xml and activate the ssl listener port (you can even give this listener the port that the non-ssl listener used). The default non-ssl listener is on port 8080 and the default ssl listener is 8443. Search for these two numbers in server.xml and (un)comment the appropriate blocks. As far as configuring the ssl certificate for tomcat, read the tomcat documentation or use google, both of which would also have answered this question just as easily. 
Thank you very much for your reply.
But deactivating the non-ssl listener port will affect my other JSP pages
(which need not be secured )or it will not affect.
What is your opinion about this ? 
Then do not do the redirect from the non-SSL port and simply activate the SSL port. Then the clients must direct their requests to the SSL port requesting https and not http, but you will still be able to do both http and https. You will probably have to add a filter for the projecs that should use https and check that it was an https request, and if not, send a redirect to the https page. 
Thank you very much for your reply.
Using Your reply
I have configured Apache-Tomcat Server correctly
can you give me one example( SOURCE CODE ) or Useful links ( For reference)
which demonstrates the HTTP over SSL ( or https ) for communication. 
If you are using tomcat or such, https looks exactly like http, because the server itself handles the SSL portion of it. You will have to give the server an SSL certificate, though. Although, I believe it comes with test certificate already, which, as long as it is not a production machine, is good enough.
You can get getRequestURL from HttpServletRequest to determine if the original request was an http or https request, for the purpose of determining whether or not it should be redirected. 
Thank you very much martin.
But I have One Question ?
It is as follows--
https looks exactly like http, because the server itself handles the SSL
means there is no chage in the code (i.e. in JSP source code)
or I have to use some special API for handelling https request.
plz Tell me which API,Classes or methods Should be Used for that.
and also tell me Useful links for SSL So that I can refer it. 
The JSP does not need to know that the request is coming over SSL. If the application must be over SSL, but the server also allows non-SSL communication, then, like I said, you need to build in a Filter that will check if the incoming request is an https or http request and redirect to the https url if the request was http. And you can do that using the method listed in the previous post. As far as setting up the SSL certificate for Tomcat to use, refer to the Tomcat Documentation that comes with the server. Other than those two things, you don't need to know anything else about SSL inorder to run an SSL application through a Tomcat server (or any other enterprise server either, for that matter), but do an internet search for SSL and maybe one or two other keywords that apply to your situation and you should find plenty that will help. 
Ok. Thank you very much.
In my project I want to read the credit card no. of
the customers i.e clients. this no. must be kept secret.That's why I am using the SSL
As you said that "The JSP does not need to know that the request is coming over SSL." That means there is no change in the Syntax.
Right ? if not please correct it.
and one thing I need to build in a Filter that will check if the incoming request is an https or http request and redirect to the https url if the request was http. means please explain this by giving Example
or Just give the code to built the filter that will check.
Ok.That's all 
String urlString = request.getPathInfo();
if (urlString.startsWiths("http://")) {
  String query = request.getQueryString();
  if (query != null) {
    query = "?" + query;
  } else {
    query = "";
  }
  response.sendRedirect(urlString + query);
}As a note, I haven't done it exactly this way myself (I have always used a server dedicated SSL or non-SSL, but not both), but this is the way it should work.
If you don't know how to make Filter at all, then try the following for more info:
http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html 
Thank you very much
You have helped me a lot.
I don't know How to make a filter at all.
and you have given a link to me but
In that link Tell me the Exact topic
where I can get the information about How to make the filter.
bcoz there are so many topics.
& there is one Doubt in my mind that Is There any change in the
JSP syntax or There is no change at all in JSP Syntax.
is it sufficient that just redirect to the https url if the request was http ? 
No change at all in the syntax. In that tutorial look under the section "Filters". 
Thank you very much masijade for your reply
Tell me the name of the sites where I can get the SSL Certificate
for testing purpose.
Also Tell me the other resources for creation of the filters
Once again thank you very much 
You can build one using keytool. Look in the Tomcat documentation section 12 SSL. Then look under the header "Prepare the Certificate Keystore" and skip the first set of boxed text and start reading with the line "To create a new keystore from scratch".
This will describe how you create your own certificate. 
Thank you very much
by Looking in the Tomcat documentation section 12 SSL.
I have created .keystore file and after that I have also created the
a local Certificate Signing Request (CSR)
I have to submit this Local certificate to the Certificate Authority.
But, Tell me the name of the sites where I can get these
free of cost .(Only for Testing the project Not for commercial Use)

programatically accessing certificate data on Sun Java Web Server

Hi - I have set up Sun Java Webserver 7.x to do client auth. When the client cert is presented to the webserver, I need to capture the data and send it to the app server using the javax.security.cert.X509Certificate class
I am not creating a webapp/war file. The webserver is the front end for a Broadvision (old school, I know) portal. I tried to create a custom authentication realm, but the webserver could not find the class file, (i assume because it is not associated with a webapp).
I know i am bucking the trend by not going the webapp route, but this seems to be a simple enough thing - i just don't know where to put the code and how to configure the webserver to see/execute the code. 
The servlet spec. documents the API to get the X509Certificate object. You do need a webapp, as java code has to live somewhere.
You could look into writing a servlet filter as another alternative. (The servlet spec. also documents that.)
Refer to [Sun Java System Web Server 7.0 Update 4 Developer's Guide to Java Web Applications|http://docs.sun.com/app/docs/doc/820-6603?l=en]
Otherwise you can write an NSAPI plugin. For more info refer [Sun Java System Web Server 7.0 Update 4 NSAPI Developer's Guide|http://docs.sun.com/app/docs/doc/820-6606?l=en|http://docs.sun.com/app/docs/doc/820-6606?l=en] 
I need to capture the data and send it to the app server using the javax.security.cert.X509Certificate classI certainly do not understand your complete problem but Web Server has the concept of filters where you can capture any data and process those. Filter needs to be written in C/C++ and java can be hooked through jni.
As mv said, easiest way is to find out if Servlet API provide similar thing. If the scope is outside of a servlet then filter/handler is the solution.
Can you elaborate more on your problem? 
more on my problem can be seen here:
[http://forums.sun.com/thread.jspa?threadID=5370956&tstart=0|http://forums.sun.com/thread.jspa?threadID=5370956&tstart=0]
the big picture is this - I have an existing Broadvision portal app (in struts) that has only used the webserver as a webserver - no code ever executes on the webserver, it is merely a gateway to the portal app code. At this point, however, I would like to capture client certificate data when it is presented to the webserver and put that data in the request object to be accessed by the portal code. I have written a servlet filter that resides in a webapp on the webserver, but it never gets executed. The initial page presented by the app has the URL http://xxx.xxx.uscg.mil/cgi-bin/ghamrick/portal/ep/home.do, so you're already in the struts app and there is no way to execute the servlet filter.
I am thinking that i might put an initial page up with links for 'Direct Login' ie login via the Broadvision app, and 'CAC Login', ie login with certificate on CAC Card. I didn't think that it would be this hard to capture cert data and provide it to the Broadvision app
Thanks for the reply - Gregg 
Hi, if you're using the reverse proxy functionallity of Web Server 7 to access your portal, then your object X509Certificate will be on a HTTP header, called proxy-auth-cert.
String clientCert = request.getHeader("proxy-auth-cert");Try this. BTW: the cert provided by this header doesn't have the header nor the footer (---- BEGIN CERTIFICATE -----, etc.).
Check this thread for more info: [http://forums.sun.com/thread.jspa?threadID=5231684|http://forums.sun.com/thread.jspa?threadID=5231684]
Edited by: j.moratilla on Mar 14, 2009 1:30 PM

Categories

Resources