weblogic client certificate authentication per webapp module - servlets

i m using Weblogic 12c.
I would like to set up client certificate authentication (2-way SSL). But i do not want to enforce client certificates for the whole server. Basically, in our webapp most of the servlets should work with regular 1-way SSL (only server certificate is verified) without requiring client to provide the certificate. But for one of the servlets client certificate authentication is needed.
I have set up similar thing for Glassfish using separate module for the servlet where 2-way SSL is required with web.xml deployment descriptor with login-config element indicating CLIENT-CERT authentication type. I have also set up appropriate security constraints, roles and groups.
However this does not seem to work with Weblogic. In the admin console under SSL i see "Two Way Client Cert Behavior" with 3 possible values: "client cert not requested", "requested but not enforced" and "requested and enforced".
If i set it to "not requested", client does not present any certificates at all (even though i have the same web.xml with CLIENT-CERT which works with Glassfish). Setting to "requested and enforced" is not an option. I also tried setting to "requested but not enforced" but that's also bad since the browser will ask for client certificate even for those pages where it is not needed (most of them) and we don't want that behavior.
Basically, it seems to me that Weblogic wants to enforce 2-way SSL for the whole server, but that's not what we need, we need it only for one webapp module. Is it possible to do so?
Edit:
To clarify, i set up DefaultIdentityAsserter and created custom UserNameMapper to map client certificate to user name. The problem however that if SSL setting (described above) is set to "not requested" then client certificate is not presented at all so the server cannot authenticate and i get 401 response. And i can't use the other 2 SSL settings because then the server will ask for client certificate for all webpages and that's not what we want.

You could create 2 Network Channels. See NetworkAccessPointMBean in WLST, or Environment/Servers/yourServer/Protocols/Channels in Admin Console.
Channel 1: SSL enabled w/ one-way SSL, on a specific port
Channel 2: SSL enabled w/ two-way SSL and client cert enforced, on a specific port
Then, access your web module on the appropriate port based on your client cert requirements.
This would only require one server.

For your specific need, I would create 2 managed servers, setting up only one with 2 way SSL.
You can then deploy your applications on the appropriate managed server, depending if you want the 2 way SSL or not for it.
Then you need to add a reverse proxy in front of your WebLogic server in order to forward your user to the correct port, as you probably don't want to expose several ports.

Related

Is it possible to setup multiple SSL on one Jelastic app?

I want to ask if the configuration to have multiple SSL on one IP in Jelastic is possible with Nginx Load Balancer.
The usage is for a proxy server that will receive request from multiple custom domains.
For example:
example-proxy.com points to a Public IP address assigned to a Jelastic Jetty Application.
Now custom domains points to the Jetty Application
custom-domain-example.com CNAME www points to example-proxy.com etc.
custom-domain-example-N.org CNAME www points to example-proxy.com etc.
Is it is possible to have this kind of configuration with Jelastic?
Is this possible to be done using the existing Jelastic API? Right now what I see in the API docs is BindSSL but it seems it can only bind one, is this correct?
Yes it's possible, but you need to configure it manually (just in nginx configs) instead of using the Jelastic dashboard/API SSL feature.
The other point to remember is that because there's 1 IP per container, multiple SSL certificates can only be served via SNI. That may have implications for you depending on what browsers your users use: in most cases it's ok now (old mobile OS and Windows XP are the primary exceptions)
The BindSSL API method allows you to automatically configure one SSL certificate on the externally facing node of your environment (Nginx Load Balancer in your case). If you attempt to BindSSL multiple times you just replace the existing certificate (not add multiple certificates).
Basically this functionality was built before SNI was widely acceptable, so it was assumed 1 SSL cert. per 1 environment. You can read more about SNI to make an informed decision about whether it will suit your needs here: http://blog.layershift.com/sni-ssl-production-ready/
An alternative for your needs would be to purchase a multi-domain SSL certificate (SAN cert). This lets you contain multiple hostnames within 1 certificate. Since you mentioned that you're our customer, you can contact our SSL team for details/pricing for this option.
If you still want to use multiple SSL certs + serve them via SNI, you will probably need to use the Read and Write API methods to save the SSL certificate parts and config. file(s) on your Nginx node.
Don't forget to restart the nginx service (you can use RestartNodeById for that) after any config. changes.
EDIT: As you mentioned that your end users will have control over this process, you probably prefer to use reload instead of restart (see http://nginx.org/en/docs/beginners_guide.html#control).
You can invoke that via Jelastic API using ExecCmdById, with commandList=[{"command": "sudo service nginx reload"}]
But take care if you're allowing end users to upload their own certificates via your application - you need to ensure that what they upload is really a certificate and nothing malicious...

API Proxy SSL Assistance

I received the following question. Any help would be greatly appreciated!
What I need to be able to do is configure SSL to validate the target endpoint’s SSL certificate against the base trusted roots (typically provided by the OS and/or Java). There is no documentation that tells me how to turn on SSL certificate validation or if I add a TrustStore if it will guarantee that the SSL cert is validated against that. The only tutorial I see that is related is for SSL Client Auth, which we are not using.
Validation of backend SSL server certificates is explained on this page. Note that the page documents how to achieve mutual authentication, where the gateway would both validate the target server's SSL certificate (which you want), and send a certificate to the target as identification (which you do not want).
To validate the target's certificate, you create a truststore and upload all certificates in the trust chain for your target server. The documentation mentions only uploading the target server's certificate (which works if your target server is using a self-signed cert), but you'll want to upload the entire trust chain of certificates if you are using a non-self-signed cert. Creating and uploading to the truststore is shown in step 6 on the page above.
Then, you'll want the target endpoint configuration to look like this:
<TargetEndpoint name="default>
<HTTPTargetConnection>
<SSLInfo>
<Enabled>true</Enabled>
<ClientAuthEnabled>false</ClientAuthEnabled>
<TrustStore>myTruststore</TrustStore>
<IgnoreValidationErrors>false</IgnoreValidationErrors>
</SSLInfo>
<URL>https://myservice.com</URL>
</HTTPTargetConnection>
</TargetEndpoint>
ClientAuthEnabled=false indicates that the gateway will not send a certificate to the target.
IgnoreValidationErrors=false will cause the connection to abort if the certificate returned by the target cannot be validated using the certificates in the truststore. IgnoreValidationErrors=false is the default, so you could leave it out and it would work as desired. However, if you are having problems communicating with your target server, it may be useful during testing to set the ignore flag to true to allow communication even if the certificate fails verification (just to isolate your problem). Just be sure to set it to false in production.
The xsd schema for the SSLInfo element can be found here.

Load SSL dynamically with code

My question is so far, a purely theoretical one.
I want to make a CMS that supports multiple sites.
The question I haven't been able to figure out so far is this one:
How do I attach the ssl certificate for https protocol from the code-behind, instead of attaching it through the hosting interface or on the iis itself (the main problem is that i want a different ssl certificate for every site, instead grouping them on one certificate, which allows maximum of 5 domains, and will still say they are the same entity)
This is not solvable on ASP.NET level.
The reason is that with HTTPS requests the SSL handshake (where certificates are presented) is performed before the client sends HTTP request, from which you can learn the domain.
The only exception is server-name-indication extension in TLS, which lets the client specify the desired domain in SSL request. But this extension is not supported by many clients and it's not present in still used SSL3 protocol version. And even with this extension it's the SSL server that decides which certificate to present.
As mentioned by Eugene, administering the SSL cert is beyond the level of ASP.Net; however, you may create some form of administration routine to execute the command-line tool for IIS7 (and up) AppCmd.exe to manage the certs:
ie (shell command --security rights is important):
appcmd.exe set config -section:system.applicationHost/sites /+"[name='Default Web Site'].bindings.[protocol='https',bindingInformation='*:443:']" /commit:apphost
The System.Security.Cryptography.X509Certificates.X509Certificate namespace might also come in handy.

Choose Certificate with Smart Card Authentication IIS7 Server 2008

I am trying to set up smart card authentication for a website that I have created. Setting authentication to Windows and setting SSL to required I can get the smart card reader to pop up when they go to the web site. There are 2 credentials on the card though and only one of them is showing up as an option (the information I need is on the other credential). I asked a co worker and he said in IIS 6 there was a way to specify a location on the smart card to look for certificates. I have been researching this issue for about a week now but haven't been able to find a solution to this issue yet. Does anyone know how to do this?
IIS really only knows about certificate-based authentication, not smart-cards per se (which is really just a form of cert-based authentication). Configure your site to use certificate-based authentication, eg "Require Client Certificates" and IIS will chain the call down to Windows security, which, in turn, recognizes that among the sources for identity certificates is the smartcard reader. Depending upon your site requirements, you may also need to enable Certificate Mapping, which translates certificates into Windows account identities.
When certificates are required (or accepted) IIS will ask for a client cert in the SSL negotiation when the session is started. IIS will send a list of the Certificate Authorities it trusts to the client. The client then takes those and sees which match the list of Certificate Authorities it trusts. It then take sthe list of common entries and checks to see if it has any certs issued by a CA both sides trust. Generally, if there are none it will simply not send a cert and the request fails if the cert is required. If there is just one certificate IE will generally send that without asking the client which cert to send, but it will prompt for a PIN if required. Finally, if there are more than one certificate issued by a CA both sides trust then a dialog box will be presented to the client asking which cert to use.
In this case it sounds like perhaps the credential (certificate) you want the client to send is issued by a Certificate Authority that isn't trusted by one or both sides.

Multiple certificates for HTTPS on a software NLB'd IIS7 cluster

We're currently trying to set up a HTTPS with multiple certificates. We've had some limited success but we're getting some results I can't make any sense of...
Basically we have two servers on our NLB (10.0.51.51 and 10.0.51.52) and two IPs assigned to our NLB (10.0.51.2 and 10.0.51.4) and we have IIS listening on both of these IPs with a different wildcard certificates (To avoid giving out public IP's let's say A:443 routes to 10.0.51.2:443 and B:443 routes to 10.0.51.4:443). We also have a Cisco router using port address translation to route port 443 from two external IP's to these internal NLB IPs.
The weird thing is, this works if we request A:443 or B:443, but if you go internally on 10.0.51.51:443, 10.0.51.52:443, 10.0.51.2:443 or 10.0.51.4:443 you ALWAYS get the same SSL cert. This cert was in the past assigned to *:443 but we've made sure there's no * bindings anymore defined in IIS.
When i run "netsh http show sslcert" after trimming out all the irrelevant stuff I get:
IP:port : 0.0.0.0:443
Certificate Hash : <Removed: Cert 1>
IP:port : 10.0.51.2:446
Certificate Hash : <Removed: Cert 3 - Another site>
IP:port : 10.0.51.3:446
Certificate Hash : <Removed: Cert 3 - Another site>
IP:port : 10.0.51.4:443
Certificate Hash : <Removed: Cert 2>
Which tells me that the * binding is still in there, which is a bit weird, but I can't see why that would prevent the other from working (Or even more more strangely why the request through the router would work).
It's got me wondering whether it's actually treating the requests as the machine's IP rather than the NLB IP, but unfortunately our dev environment is only a single server which sorta reduces the amount of trial/error I can take to this (Since all I can test on is a live environment) without convincing management to buy more servers for the test environment - which is something I'm trying.
Does anyone have any idea:
Why there's a difference between internal and through the router?
Why the internal request is getting the wrong cert?
How I can remedy this so that we get the same behavior on both sides?
I ended up tracking the problem down. Leaving this as a hint for anyone else who falls in the same trap...
The problem was caused by us using a shared configuration model on our IIS servers. When setting up a HTTPS binding this appears to only actually bind it on the box you're managing it on (Leaving the other completely unbound). Since our * binding still existed it was catching it on the server we didn't do through the UI and just let pick up the shared config.
Crazy bad luck with single-affinity NLB sent us down the garden path after the router being the cause by making our internal requests go to one server and our external requests to another.
We ended up finding this by running "netsh http show sslcert > certs.txt" on both servers and diff'ing the outputs.
Going forwards our plan is to no longer use the IIS UI for SSL configuration instead following the steps below:
Install the certificates on each server.
Run a command-line binding of the SSL port "netsh http add sslcert ipport=?:? certhash=? appid=?" (ip:port is easy to work out, certhash can be copied from the "certificate hash" section of the server certificates page, appid can be copied from an existing IIS binding on the netsh http add sslcert)
Edit the IIS ApplicationHost.config file directly to add the bindings without the UI being involved.
Our understanding is this will prevent a repeat of this error.

Resources