Category Archives: CORS

CORS Filter with improved performance

CORS FilterThe 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.

CORS Filter with automatic reconfiguration

CORS FilterVersion 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:

<filter>
	<filter-name>CORS</filter-name>
	<filter-class>com.thetransactioncompany.cors.autoreconf.AutoReconfigurableCORSFilter</filter-class>
</filter>

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.

Check out the CORS Filter docs for the complete instructions on setting up automatic reconfiguration.

CORS Filter 1.7 with more configuration options

CORS FilterThe Java servet filter for enabling CORS (cross-domain) web applications received a major upgrade today.

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:

  1. Checks for an environment variable “cors.configurationFile” pointing to a properties file with the CORS configuration.
  2. Checks for a servlet filter init-param “cors.configurationFile” pointing to a properties file with the CORS configuration.
  3. 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.

Handling of same-domain requests that carry a redundant Origin header (set by some Javascript frameworks) is fixed too.

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.

CORS Filter 1.6 supports any URI scheme

CORS FilterThe 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 finally with CORS support

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.

Today more than 85% of the browsers on the web support CORS and an increasing number of developers are starting to use the protocol, judging by downloads of our CORS Filter package which allows CORS support to be easily retrofitted to any Java web app or service. When the new Opera 12 appeared the CORS Filter was successfully tested under it.

Thanks to Joost Cassee the CORS filter is now also available on Maven.

CORS requests and cookies

CORS FilterToday I received a question regarding the Java CORS Filter and browser cookies:

Does your filter take care about the sessions? For each CORS request I get a different JSESSIONID.

My response was that in order for the Java web application or service to get at a cookie, both the CORS Filter in front of it as well as the requesting JavaScript must explicitly allow this form of credential:

First, the JavaScript initiating the XHR call must set its “withCredentials” flag to true. Otherwise the browser will not allow any cookies to be passed during the cross-domain call.

var xhr = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';

xhr.open('GET', url, true);
xhr.withCredentials = true;
xhr.onreadystatechange = handler;
xhr.send();

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.

CORS and HTTP 302 redirect responses

CORS Filter
Earlier this week a user of the CORS Filter library asked why his browser app wasn’t able to connect to his web service despite it having Cross-Origin Resource Sharing (CORS) enabled.

Investigation of the problem showed that his XHR was not landing on the CORS-enabled URL directly, but was being redirected to it through an HTTP 302 (redirect) response.

So bear in mind that the redirecting URL must also include an Access-Control-Allow-Origin header, else the browser will stop right there with its attempted cross-domain request.

Easy LDAP user authentication over the web

NimbusDS AuthServiceAuthService is a simple web service software offered by Nimbus Directory Services. It can authenticate users against any LDAP directory using a web-friendly HTTP+JSON protocol.

Where to use?

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.

AuthService authenticates users against an LDAP-compatible directory

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.

Example user authentication request:

{ 
  "method"  : "user.auth",
  "params"  : { "username" : "alice@wonder.net",
                "password" : "s3cr3t" },
  "id"      : "0001",
  "jsonrpc" : "2.0" 
}

And here is an example response indicating the supplied username and password were correct:

{ 
  "result"  : true,
  "id"      : "0001",
  "jsonrpc" : "2.0"
}

The complete AuthService web API is documented online.

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.
  • Email address.
  • 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:

{ "result"  : { "userID" : "alice",
                "name"   : "Alice Wonderland",
		"email"  : "alice@wonderland.net",
		"phone"  : "+44 711 567 8910" }
  "id"      : "0001",
  "jsonrpc" : "2.0"
}

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.

How about security?

AuthService includes a number of configuration settings for managing and protecting access to the service.

  • Whitelist of allowed client IPs / hostnames that may access the service.
  • Whether secure HTTPS is mandatory.
  • Whether clients are required to authenticate with a valid X.509 certificate issued by a trusted certificate authority (CA).
  • 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.

LDAP directory in the cloud

Json2Ldap iconJson2Ldap hit the cloud this month.

I’ve always wanted to put up an online demo for the JSON web service for LDAP directory access and this is reality now. If you visit the NimbusDS website you’ll see a new Json2Ldap demo page where you can play with three Ajax 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.

The Ajax apps were written in JavaScript and use a relatively small subset of Json2Ldap’s web API, namely the JSON requests ldap.connect, ldap.search, ldap.getEntry, ldap.simpleBind and ldap.close.

Ajax employee directory

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.

Detecting CORS support in a browser

I’m using the following JavaScript function to detect whether a browser has support for Cross-Origin Resource Sharing (CORS) XHR.

function browserSupportsCors() {

	if ("withCredentials" in new XMLHttpRequest())
		return true;	
	else if (window.XDomainRequest)
		return true;
	else
		return false;
}

The XDomainRequest object is specific to IE 8 and IE9, other browsers, including IE 10, extend the existing XMLHttpRequest.

I use this piece of code in the Json2Ldap directory Ajax demo which I posted the other day.

jQuery still has no complete and robust plugin for CORS support. I hope this situation will change soon as browser support for CORS has passed 80%.

PS July 2012: Update of the CORS detection code to handle IE 9 better.