The new 2.5 release of the CORS Filter for handling cross-domain requests offers improved performance. This benefits Java web servers that handle lots of traffic, particularly situations when a significant proportion of that is invalid or unauthorised CORS requests.
The improvement is achieved by using static (cached) exceptions within the filter. Here is an an informative discussion with metrics about Java exception handling and how it can be sped up.
The 2.5 release also fixes a NPE bug affecting Origin validation during configuration.
Version 2.4 of the Java CORS Filter for handling cross-domain requests has added support for automatic reconfiguration. You can change your CORS policy at runtime without having to reload your web service or application. Kudos to Alexey Zvolinsky for contributing this cool new feature.
Automatic reconfiguration is provided by a special variant of the CORS Filter. Stick the following declaration into your web.xml file to use it:
This filter variant must be configured with an external Java properties file. The filter init-param style configuration will not work here as the web.xml file may not be modified at runtime.
The configuration file will be polled for changes every 20 seconds. If a change is detected the filter will automatically reload itself with the new configuration. If the new configuration is invalid an error message will be printed to the server log and the filter will continue operating with its previous intact settings.
Up until now in order to change the out-of-the-box CORS configuration you had to add filter init-params in the web.xml descriptor of your application. A number of developers asked for alternative configuration means, such as specifying a properties file for the configuration. This is now supported.
The CORS Filter will now apply the following precedence when resolving the configuration:
Checks for an environment variable “cors.configurationFile” pointing to a properties file with the CORS configuration.
Checks for a servlet filter init-param “cors.configurationFile” pointing to a properties file with the CORS configuration.
Checks for CORS params in filter init section, applies the default values if not found.
Another important configuration change is the ability to specify a general “allow-any-request-header” policy by setting the cors.supportedHeaders to an asterisk.
Thanks to David Bellem, Stijn Cremers and Casey Lucas for initiating this new release of the CORS Filter. Also thanks to Anne van Kesteren for answering my CORS-related query on the W3C list.
The Java CORS Filter for adding Cross-Origin Resource Sharing to existing web apps received an important update to permit any URI scheme, not just the ubiquitous http:// and https:// as originally supported. This change is in line with RFC 6454 which defines the concept of web origins.
This means that now you can also service CORS requests for “custom” schemes as app://, fb:// , etc.
The new CORS Filter release should reach Maven Central later today. You can also get it from the CORS Filter Git repo at Bitbucket.
Cheers to Edraí Brosa for initiating this important change!
Opera was the last major browser to add support for handling cross-origin requests in its 12th version. The CORS protocol was devised several years ago by a W3C working group to allow for clean making of cross-domain XHR, without JSONp hacks. CORS was initially adopted by Firefox and Chrome, and was subsequently joined by the other major players, such as Microsoft’s Internet Explorer.
Does your filter take care about the sessions? For each CORS request I get a different JSESSIONID.
var xhr = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';
xhr.open('GET', url, true);
xhr.withCredentials = true;
xhr.onreadystatechange = handler;
Second, the CORS Filter must also expressly state to the browser that cookies are permitted. This is advertised during the so called “pre-flight” request that the browser makes before an actual request that may involve credentials, such as cookies. The CORS Filter ships with a default configuration where credentials, such as cookies, are flagged as allowed when responding to preflight requests. To restrict this edit the cors.supportsCredentials configuration parameter.
The Java CORS filter itself doesn’t access the cookie headers in any way, nor does it interface to the JSESSIONID.
So, to sum up, both the calling script on the browser side as well as the CORS Filter on the server side must expressly have the credentials flag enabled for cookies to pass through.
There is a snag however and it has to do with Internet Explorer. Its XDomainRequest implementation of CORS doesn’t allow cookies to be passed at all, for security reasons says Microsoft. Which is probably a good thing. So if you wish to achieve wider browser support for your cross-domain application or service you will have to use an alternative mean to cookies for storing session IDs, such as passing the token as an URL parameter.
AuthService can be used in any situation where you have to authenticate user credentials (login) over the web against an LDAP-compatible directory such as Microsoft Active Directory, Novell eDirectory or OpenLDAP.
You’re a SaaS provider and want to provide your corporate customers with a method for authenticating users against their internal directory.
Your company has applications in the cloud and wish them to use the corporate directory for user login.
You’re designing an Ajax app and want to authenticate users with a single JSON XHR. No redirection and page reloading, please!
How does it work?
AuthService is a nimble web service that sits in front of an LDAP directory and receives JSON-RPC request from web clients. It resolves the supplied usernames to valid directory entry entries (DNs) and translates between the binary LDAP protocol and HTTP/JSON.
The JSON request and response messages, what do they look like?
AuthService communicates with simple JSON messages. These follow the standard JSON-RPC 2.0 protocol.
Can you retrieve a user’s details from the directory?
Yes! In addition to checking the user’s credentials you can also configure AuthService to return a selected set of user’s directory entry attributes on auth success. This is done via the authService.userAttributes configuration setting.
Here is a sample list of attributes that can typically be retrieved:
Given name, surname, full name.
Office, home and mobile phone numbers.
Organisational details such as manager, department and authorisations / permissions.
Here is an example of such a JSON user auth response that returns selected user details:
Which directory servers is AuthService compatible with?
AuthService works with any LDAP v3 compatible directory. This includes Microsoft Active Directory, Novell eDirectory, IBM’s and Oracle’s directory services, the open source OpenLDAP, OpenDJ and ApacheDS servers.
What about installation?
AuthService is delivered as a standard Java servlet application, packaged as a WAR file and ready for immediate installation into any Java web server, such as the popular free Apache Tomcat or Jetty servers. The WAR file weighs a nimble 2.5 megabytes.
Whether the subject of the presented X.509 client certificate must match an authorised distinct name (DN).
What about price and support?
AuthService licenses come at a super affordable price. For immediate purchase and download check out the NimbusDS online shop. Attractive discounts are available if you with to distribute the software as part of your own product or SaaS offerings, for 100, thousand or even more copies.
NimbusDS, which operates out of London, UK and Bulgaria, also offers excellent integration and consulting services, with emphasis on LDAP directory design, meeting organisational objectives, web and cloud directory applications.
Online employee directory: Presents a list of company employees where by clicking on a person’s name additional details are displayed.
Resolving group membership: An important organisational feature of directories is the ability to specify groups for things like departments, permissions and mailing lists. This app lists the available groups and resolves the associated members.
User authentication: Ajax form to authenticate a user’s UID and password against their LDAP directory account.
As for the directory web service, I set up a Json2Ldap instance at CloudBees, together with an embedded in-memory LDAP directory that represents a typical corporate DIT consisting of a user base and several groups. You can view a screenshot of the directory tree to get an idea of its user and group structure. In a deployed state Json2Ldap with the in-memory directory take up 40 MB of memory which fit nicely into the free PaaS plan of CloudBees (256 MB).
The directory behind Json2Ldap can of course be any other LDAP v3 compatible server, such as Microsoft Active Directory, Novell eDirectory, OpenLDAP, OpenDJ, etc. So there’s complete flexibility here, also in terms of schema, as Json2Ldap is schema-agnostic.
How about Ajax responsiveness?
Measurements with the JSON-RPC Shell show that JSON calls to the Json2Ldap service at CloudBees are typically completed in about 150 ms. I don’t have a basis for comparison with other cloud vendors here, but I suppose responsiveness impacted by the relative datacentre location (e.g. EU vs USA) and the efficiency of the PaaS abstraction layers of CloudBees. Their PaaS is actually running on top of Amazon’s cloud infrastructure, so there may be quite many layers involved. When I compare the response time to a Json2Ldap service on the local intranet, the JSON calls here take about 15 ms to complete, which is an order of magnitude quicker. For the actual demo apps the 150 ms response time however is okay and doesn’t affect responsiveness in a noticeable way. You can of course try it out for yourself.
The next planned cloud demos will cover the other NimbusDS software products – JsonSSO and AuthService.