I am trying to write my first SOA client, and am having difficulties with the
"2-way SSL" part.
Our server runs under Weblogic, but my application is a simple Java Console app - it does not run in any container.
The server uses and requires certificates. We use trusted certificates from Godaddy.com, and we also have internal certificates.
Our sysadm gave me the server certificates, which I added to my JRE "cacerts" file using keytool. I was told that I should use Spring-WS as it would make my life easier, but I am having trouble getting it to work, as there are quite a few variations that Chap. 7 mentions, and I am not sure which one I should be using. He also created a .jks file for me personally to use for my authorization.
I would prefer to not use Spring at all, for this simple application (the SOA method is a simple "Add comment" method with no substantive return data.
I am working with MyEclipse 9.1 and am trying to use Maven4MyEclipse as well.
My question is:
Given that my authentication certs will be available via the JRE cacerts file (if I understand this correctly), the main thing I need to do is to be able to present my .jks file during the SSL handshake.
Can I do this without Spring? If so, is there a way I can simply set a System property with my .jks file so it gets handled automatically? Or do I really need to use Spring to handle the authorization part?
If the latter, how do I know which Spring security interceptor type to use? XwsSecurityInterceptor or Wss4jSecurityInterceptor?
Or another question just occurred to me. Can the .jks file also be added to the
cacerts file and have the authorization handled automatically?
Thanks,
Mitch
p.s. Believe it or not, there is apparently no existing Java client example in my organization to simply look at for a template.
For two way authentication, I have always used the followin when starting the client app:
java -Djavax.net.ssl.keyStore=myClientKeystore -Djavax.net.ssl.keyStorePassword=123456 -Djavax.net.ssl.trustStore=myTrustStore -Djavax.net.ssl.trustStorePassword=123456 -Djavax.net.debug=ssl
That is, my clients private certificate is in the "myClientKeystore" and then the server public certificate is in the "myTrustStore". The javax.net.debug=ssl will make your life easier, since it outputs some nice debug info if you can't make the SSL session to work.
That's for the SSL part.
Then I think you mix up SOA with Web Services and SOAP. SOA usually means service oriented architecture and is very high level. I think you are talking about a SOAP implementation.
If the web service is more than trivial, yes, a framework will make your life easier. Apart from Spring-ws (which I like as well), you can google for CXF and Axis2 and you will find tons of example how to write a SOAP client. But sure, you can write the web service call rather raw, if you are able to create the SOAP envelope manually (use SoapUI to generate test envelopes is a good start..).
Then, take a look at : this page, it has an example on how to make a SOAP call over HTTP without any framework at hand. Of course, since you are using SSL, you should reference a "https://" address instead.
Related
We're maintaining a Java application with a JAX-WS SOAP API for external systems running on WildFly 14 application server. The external systems currently connect using common one-way SSL. Our goal is to switch communication to mutual authentication, so two-way SSL.
Not all of the external systems can make the switch at the same time though, so simply enforcing two-way SSL is not an option. We need to migrate them step-by-step during a transition phase. That why I've been wondering: Is there a possibility to enable two-way SSL on a WildFly HTTPS interface for specific caller IPs only?
I have based my tests on the official documentation on setting up regular two-way SSL. Following these steps, every caller needs to provide a client certificate. Modifying that example configuration to use want-client-auth instead of need-client-auth softens the checks to support two-way SSL but not require it. Unfortunately that is not enough in our case, because it does not imply guarantees about whether a particular external system is consistently using two-way SSL or not. A system could send some of its requests providing a client certificate, and some without. In other words, business requires a way to say "From this day on, external system Foo may only use the API with a client certificate. All the other external systems are unaffected, for now."
To implement this - preferably without application code changes -
I've been reading the documentation of the new WildFly security module Elytron. It seems quite extensible, but details on custom components are sparse and I haven't found an extension point that sounds like it would help in my case.
The only solution approach I have right now is configuring a separate set of socket-binding and https-listener for Wildfly, similar to what is described here. That means we would have two HTTPS ports: One with one-way SSL, and another one with mandatory two-way SSL. As external systems are completing their migration steps, they switch the port used for invoking our API. Forcing them to only use the two-way SSL port from then on would require specific firewall rules, but should be possible.
So, this solution is rather simple in technical implementation but leads to overhead for re-configuring the external systems and adapting firewall rules. That's why I'd be happy about any suggestions for a solution that is more elegant, or hints how to use Elytron for that.
Thanks in advance!
I think you came to best conclusion. Elytron does not have possibility to choose SSL Context based on client parameters (What would that be? Client IP address? That can change when behind the load balancer.)
So I think only way is to have different SSLContext configured on different ports (or hostnames).
Regarding extending server. I guess SSL handshake is very early step and after that different customisation points take part. I thought about some Undertow custom handler, something similar to [1], but as I said that would be too late.
[1] http://undertow.io/undertow-docs/undertow-docs-2.0.0/index.html#redirect-handler
I've been asked to look into adding an LDAP interface to an existing Java web application - that is, to make it possible for LDAP clients to connect to the application as if it's an LDAP server. I could write code to listen on a dedicated port and implement the LDAP protocol, and hook that into the existing database... but I'd have to understand the protocol first and then there are potential security issues if I write that from the ground up (not to mention the time it could take).
What I'm looking for is a library of existing code - something that handles the ports and protocols, and lets me focus on writing just the back end. There are plenty of client-side libraries out there, as you'd expect, but I've had no luck in finding something to help with server-side development. So the question is, does anyone here know of such a library that would help with this?
Yes you will most probably find many more client implementations than server, however LDAP is a request response protocol, so with a bit of playing around you should be able to use the same classes and their serialization capabilities. Instead of sending the request you would be receiving it, and responding with the response you would otherwise expect from the client.
You could look at the Apache Directory. https://directory.apache.org/api/
It has an embedded directory server project as part of it, which claims to be extensible and embeddable in your application. https://directory.apache.org/apacheds/
So maybe that could be the answer to your needs.
Here is the situation. I have received a WSDL (and included XSD) from someone that is generated by an Apache/Tomcat server (Java). The company i do a project for, prefers .NET so i used wsdl.exe to generate a partial class and created the webservice.
Then I created a .NET client (in this case I am using VB.NET) that has a web reference to the java wsdl. This works fine. Then I change the url using code and make it point to my newly created .NET service but i cannot seem to get it to work.
Doing it the other way round, also doesnt seem to work.
Been fiddling a bit with the namespaces and the service name but can't seem to crack it. Keeps giving me an error about HTTP header unable to find . as a method. This indicates a transport problem.
I really do not want to revert to plan B, being the creation of a Java Webservice and then linking this to the .NET environment. I know this will work since you will never have to change the urls.
Any suggestions ?
So to summarise you have:
SERVER SIDE: java, WSDL: java generated
.NET client -> java server - WORKS .NET client -> .NET server -> FAILS
If thats the case this has not much to do with Java!
But I do know as I aluded to earlier that .NET servers are fussy about the soap action header.
Is there a soapAction in your WSDL?
If so, you need to send that value, but I don't know how to do this in .NET (Google would be your friend here).
If not, check out the comments in this question for how to determine the required soap action header value: stackoverflow.com/questions/2262781/soap-action-wsdl
After a bit of searching through the devine knowledge base (Google), i have managed to get this fixed.
In addition to being very carefull in specifying the portnames (the default ones are not always what is requested so you need to override it) but most importantly, i found that adding
as part of the asm class header solved my problem. Now all I need to do is find out why?
But trust me, it works...
I found the solution here
I'm creating a web-service client. I used a WSDL file to generate the client side stubs.
But now I have to authenticate to the web-service, and invoke methods.
I've checked some tutorials on how this should be done, but they always explain generating the client code and server code then having them work together.
I was wondering if all the info needed to authenticate and invoke requests is contained within the WSDL file(and thus auto generated code)? Or do I have to also have knowledge of the web-service code?
Any help appreciated.
Generally speaking, a WSDL should be all you need (assuming it's been written by someone who knows what they're doing).
A well-written WSDL should have sensible method and parameter names such that the generated client bindings are more or less self-explanatory. Through the <annotation><documentation></documentation></annotation> attribute, comments should be added to resolve any ambiguities. In other words, think about a WSDL just like a JavaDoc API page. You shouldn't need to care about what's inside the black box, just so long as you know what you need to put in and what you'll get out of it.
As for authentication mechanisms there are really two cases to consider: the web service level authentication and application server level authentication.
At an application server level (e.g. Tomcat or GlassFish), the WSDL won't give you indication of the authentication method used (because the WSDL is at a level above the application server). In this case, you can try debugging by accessing the WSDL file in a browser (or maybe try invoking the service in SoapUI) and seeing what you need to be authenticated.
At a web service level the security mechanism should be described in the WSDL. I'm not aware of any IDEs that can automatically recognise the authentication mechanism described in the WSDL and then prompt you to what you need to supply (although I only really use NetBeans). However, you should be able to work it out - either by examining the WSDL or by looking at the error messages your web service client spits out when you try and access a protected resource.
A WSDL file does not contain information on the order of invoking certain functions (if any). So, in my opinion there should always be additional documentation.
I have two application. I need to do a single signon from application a to application b.
I thinking of using web service. I wonder how do i go about that approach.
Can anyone advise?
Assuming these are web applications - you must implement some type of shared trust model between the applications.
Under no circumstance should you write your own. That is too easy to screw up and there are plenty of existing (both open and commercial) to choose from.
Here are following options:
1 - If everyone is running Windows - you could just Windows Native Authentication (aka SPNEGO)
2 - You could implement some type of SSO system. Popular systems are CAS, Oracle Access Manager, CA SiteMinder, Sun SSO and IBM Tivoli Access Manager. While CAS is open-source, the others will also allow you to implement authorization as well, while CAS only does authentication.
Finally - make sure whatever option you choose - that it integrates with your language's native authentication & authorization framework. In Java this would be JAAS. In .NET it would be the .NET security framework. For PHP/Perl - you can leverage Apache modules. The benefit is that you don't have to become a security expert and it will make it easier to use external systems for authentication & authorization without having to re-code your app.
You could use a public key authentication scheme.
Create a keypair with a public and private key (using Java's keytool, GNU GPG or a similiar tool). Use the private key to sign a piece of information (for example a username) on application A and create a link to application B that is accessible from application A and contains the signed data. Application B can then log the user on after verifying with the public key that the request indeed came from application A (which it must have if it is able to decrypt the string).
You could of course create a opposite keypair for navigating the other way as well, or you could just use the public key and keep it secret (effectively making it a shared-secret system).
If the user tries to access application B directly you could also redirect him to application A with a parameter that says he came from application B (or do a referrer check). If he is already logged on to application A create the link with the signed data and redirect to it, otherwise present him with a logon screen and redirect after logon.
Hope that helps!
You could use an existing open source product, CAS and just implement it instead of develop your own. That way you'll be able to integrate with other applications that support the same protocol. Even if you decide to implement your own instead of using their code, there are a lot of ideas presented at the web site that would be useful for you to consider.
If the applications are hosted in the same server, then you could configure it to use single sign on. For example, in Tomcat this is achieved with a Valve.
If the applications are in different environments, then a secured Web Service is a good idea. You could for example create a public - private key pair and have application b (server) authenticating application a (client) on the client certificate. This means that application a will sign all requests to application b with the client certificate. More details about the architecture are needed for a full solution.
Are you using an application server? What is the environment for your applications?
There is a standard for propagating identity using web services called Web Service Security UsernameToken Profile. Here's a quick overview. You can send username/password or various tokens such as X.509 certificate or a SAML assertion. Some application servers web services stacks will handle WSS UsernameToken Profile, JBoss, Websphere, and WebLogic. Otherwise the web service code has to handle it. This approach may be too cumbersome depending on your environment.
There is a standard for single sign-on, called SAML. Again, this may be too heavy weight for your use-case.
In Oracle land I know there is the concept of a trusted application. Basically if you have control of both applications you can set it up like so:
Application A sends Application B, 1) Application A's username and password and 2) the current user's username. Since B knows and trusts Application A it doesn't need to verify the user's credentials, since it knows application A has already done that for it.
I assume that if you have a custom application B you might be able to do something like this. If your SSO implementation supports this then you probably don't have to do a whole lot except design your web services.
Good Luck