Secure Java Web Services - java

I am trying to figure out which framework/API would be best for implementing my web services (Java EE). The data being passed back and forth between client and web container needs to be super-secure, and so I'm even thinking of encrypting my data before it even gets wrapped up in a SOAP (or the secure equivalent to SOAP) message, regardless of what security services the framework provides me with.
I see there is the so-called XWS-Security but it seems that it is for securing legacy JAX-RPC services. I'd like the framework to be standards-compliant (WSS/OASIS, etc.) and neither deprecated or deprecating (current; compatible with the upcoming Java 7 release, etc.).
Is JAX-WS and JAX-RS secure by default? If not, is there a compatible "secure wrapper" framework that can be used to adapt an existing JAX-WS web service to implement a secure framework?
Any thoughts or suggestions greatly appreciated!

If you just want to secure the content then use transport layer security, such as HTTPS. This will automatically encrypt WS request/responses and prevent evesdropping and malicious modification.
If you want to do any authentication/authorisation you might want to get the caller to sign the request too.

You should do two things, first secure the transport using SSL. If you control both the clients and the server then you can require 2-way SSL which would ensure that only trusted clients can connect.
Second you can implement WS security protocols. Web service security standards tend to deal with three things: Authentication, Digital Signatures and Encyption/Decyption (from the Spring-WS docs):
Authentication. This is the process of determining whether a principal is who they claim to be. In this context, a "principal" generally means a user, device or some other system which can perform an action in your application.
Digital signatures. The digital signature of a message is a piece of information based on both the document and the signer's private key. It is created through the use of a hash function and a private signing function (encrypting with the signer's private key).
Encryption and Decryption. Encryption is the process of transforming data into a form that is impossible to read without the appropriate key. It is mainly used to keep information hidden from anyone for whom it is not intended. Decryption is the reverse of encryption; it is the process of transforming of encrypted data back into an readable form.
There are a number of protocols/standards for each of these functions, and
there are a number of Java OSS projects that implement the various security protocols/standards in a reasonable, usable ways.
In particular I'd look at Sun's XWSS and APACHE WSS4J. Spring WS has implementations of both of these APIs, they also do a good job of describing the various components: http://static.springsource.org/spring-ws/sites/2.0/reference/html/security.html

Related

Password Hash validation/checking in DBMS vs. Web-app layer

I have the ability to do password hashing in the Web-app layer of my system or in the DBMS (postgresql's pgcrypto). Is there any advantage to using either or?
For more context, I will be using Amazon's AWS (EC2 and RDS).
The system has various mobile clients which contact the back-end (through one Spring/Hibernate Web App). There is no direct access to the database through these mobile clients, they all must go through the java web app.
EDIT:
Other tidbits:
HTTP basic authenication over SSL, Stateless/RESTFUL (as much as possible), using the blowfish cipher for hashing with a randomly (well.. psuedo random) generated salt.
Will the password be synchronized? (used by more than one application) If it is that will be the largest guide. I generally recommend not handling unencrypted passwords any more than you must. On the other hand screwing up password hashes is real easy to do, and hard to fix so use a library that gets security updates. Above all be simple, clean well documented code is even more important when dealing with security.

Using custom WCF username/password (UserNamePasswordValidator) authentication with Java

I've found a good example about authenticating WCF services with custom username/password (A simple WCF service with username password authentication: the things they don’t tell you). This fits what I need... partially, I guess. It uses wsHttpBinding and Message as the security mode.
The WCF service I need to build will have Java clients, and my question is if the example from the link above works with Java ("interops" well). Or should I go with basicHttpBinding, securing the connection at transport level (https)?
Thanks
WCF implements lots of Web Service protocols:
http://msdn.microsoft.com/en-us/library/ms730294
Although complicated solution is not necessary the best one.
Go ahead with basicHttpBinding and Transport security if it fits all other requirements you have.
There is good all-in-one article that describes configuration:
http://www.remondo.net/using-ssl-transport-security-wcf-basichttpbinding/
transport security will almost always be better for interoperability. Having said that username security is also pretty safe, especially if it is under ssl and not use message level certificates. Even if there are certificates it is possible to interop with the axis2 or wsit java frameworks. it may be challenging though, so if you will have many arbitrary clients and want them to interop with your service without any special guidance you may want to avoid it.
BTW basicHttp and wsHttp are both capable to do either message or transport level. basic is a little easier for interop since it does not use ws-addressing.

Making a web service, which approach?

I have made a Java EE 6 application where a user can browse a set of questions, add new questions and so on. The user can optionally log in so that he/she gets "credit" for adding the question or reporting it as bad.
Now I want to make a iPhone application where the user can do pretty much the same. So the answer is web service I assume. I have not worked with web service before but I see there are at least to alternatives: SOAP and REST.
Which one should I choose? I want the user to be able to log in from the application as well a as browse the questions in the database...pretty much many of the actions you can do on the web site.
I don't know much about the security and overhead they introduce.
Also I want the user to be able to retrieve the list of questions thorugh the web server and have the option to save it, so he/she won't need to have internet unless he/she wants to update it. Can I achieve this with both web services?
REST has less overhead than SOAP (WSDL contract, XML messages, supporting frameworks) so when the client is a mobile device REST seems more suitable. You could use JAX-RS (Jersey) to easily create REST services on the server side. The client request consists of the url structure and/or parameters like http://yourserver/questions/view/342 (to view question 342) or http://yourserver/questions/search?q=REST+vs+SOAP (to search for questions about REST vs SOAP). The response can be anything you want, but XML or JSON is pretty common.
Choosing REST means you will be leaning heavily on the HTTP protocol. For security a common approach is to use HTTP Basic authentication in combination with https. Basic authentication means you add an 'Authentication:' header to your HTTP request containing a Base64 encoded username:password pair. Note that Base64 does not encrypt anything, it just obfuscates. To avoid eavesdropping you need to use at least https meaning requests are encrypted using the server's public key. These requests can only be decrypted with the server's private key. To use https you need to set up the server with a certificate. If you want to avoid warnings about the certificate being 'untrusted' it needs to be issued by a recognized SSL certificate provider. For testing you can just generate it yourself.
Finally you asked about saving a list of questions for offline usage. This is a concern of the app, not of the service. To do this you need to store the retrieved data on the device and access that data if the device goes offline. I am not an iPhone developer, but I can imagine you could use a flat file or some lightweight database to store the data. When the device is offline, the app component that retrieves data should switch from network access to local storage access. Also some app functionalities like adding a question might need to be disabled. If you don't disable these, you would need to temporarily store any data entered by the user and send it to the server when the device comes online again. This could be a bit tricky to get right so my advice would be to leave this for later.
You can take a look at this previous SO post for some guidance. I would recommend using REST, it seems to be less messy than SOAP and Java has support available for it as shown here.
Through the use of annotations, you can simply created a facade to which users will connect. In turn, this facade will call the relevant logic which I am presuming you already have.
Well on a simple search REST vs SOAP, you will eventually get to this
There are plenty of other articles and even in-depth research papers, so it's only a matter of - do you really want to get serious with your research VS not really
Good luck!
Short answer: Yes, you can achieve that with web services.
Web services are only a facade to your system - they can expose (or not) any behavior you want to. If you have security concerns, you'll have to approach them anyway in both methods.
Personally, I'd use a RESTful approach as its usually simpler to implement and use. From Wikipedia:
A RESTful web service (also called a RESTful web API) is a simple web
service implemented using HTTP and the principles of REST. It is a
collection of resources, with four defined aspects:
the base URI for the web service, such as http://example.com/resources/
the Internet media type of the data supported by the web service. This is often JSON, >XML or YAML but can be any other valid Internet media type.
the set of operations supported by the web service using HTTP methods (e.g., GET, >PUT, POST, or DELETE).
The API must be hypertext driven.[11]
So you'd have a URL, say http://mywebsite.com/users and perform HTTP actions (GET, PUT, etc) on them. A GET request on /users/17 could return user 17, for instance, while a POST request on it would update said user.
As for login, when your users "log in" you would call a GET method that sends username:password (probably encrypted) and returns a login token. Every time the user executes an action, you would send said token with the request as an additional parameter.

Webservice Security - what is enough?

I am looking to expose a Web Service which can be called by multiple clients to retrieve transactional data. Each calling client will retrieve a different subset of data.
We are hosting the Webservice in Websphere 7 - the external webservice is essentially a proxy to the real WS running on our ESB platform.
Currently I have the following security in place:
1) WS-Security username/password sent in the header (plantext). This is authenticated against our custom repository (the repository is in-use elsewhere and has been security tested).
2) HTTPS
3) Restricting calling IPs via firewall
4) Payload data is PGP encrypted using the clients public key
Is this secure "enough"? I'm pretty sure the payload data is secure, but I'm not completely sure if the access mechanism is 100% secure? We are using what is built-in to IBM Websphere for #1.
Well, as your are using HTTPS you don't have to worry about sending the passwords in plaintext. So as long as your authentication works properly (you say the repo was security tested) this is quite secure.
Additionally you have encrypted payload using PGP, which is really secure - at least as long as all parties handle their keys with the needed care.
--> What you're describing sounds fairly solid to me, especially with the asynchronous encryption of PGP which is basically not attackable (unless you consider social engineering).
Maybe a last thought (but I guess you don't need this advice):
I don't know about Websphere, but in other application servers or ESBs (e.g. JBoss) there are some admin tools activated per default which tend to be freely accessible via the web (just google for /jmx-console ...). Make sure to secure those with passwords or deactivate them if need be.
For me it is more than enough. The only additional thing I can think about is using temporary passwords. See RSA for details.
Is the subset of data which is returned by the service linked to the authenticated client identity, or is the returned set of data determined by a parameter which gets passed in?

How to write a java web service to do remote login?

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

Categories