Authorization Layer
The authorization layer sits just above your application layer but is still on the sever. In most application systems, this is actually integrated directly with your application layer. Although this is generally accepted, it doesn't provide for as much flexibility, and it's a lot harder to code application logic and authorization in the same location. Additionally, if you go to change your authentication, you now have to worry about breaking your application layer and your authentication layer. If you build this as a separate layer, you can most likely pull all authorization directly out of a database, so you don't have to worry about changing your code just for a minor change in business logic.
If you use XML for your object representation, you can use XSLT for your authorization layer, and use some custom tags to pull out this authorization logic directly from your database. If you use an application framework such as Django or Ruby Rails, chances are you already have this layer built for you, either directly or in a third-party module. Check your specific language for how to build your own extensions for XSLT. When you can build your own extensions into your XSLT processor, not only can your filters be retrieved from a shared filesystem so that you can update them without redistributing them to each of your servers, but you can also pull the exact details about authorization from there. These XSLT filters can be used to specifically hide elements of the response XML that the user shouldn't see. The following example code assumes you've already built a function called hasAuth that takes three arguments, authorization type (read, write, delete), object type, and property name:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:app="url/to/app"> <!-- By default pass through all XML elements --> <xsl:template match="@*|node()" priority="-10"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- Object-level permissions --> <xsl:template match="/node()"> <xsl:if test="app:hasAuth('read', current())"> <xsl:copy> <xsl:apply-templates select="@*|node()" mode="property"/> </xsl:copy> </xsl:if> </xsl:template> <!-- Property-level permissions --> <xsl:template match="node()" mode="property"> <xsl:if test="app:hasAuth('read', .., current() )"> <xsl:copy> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:if> </xsl:template> </xsl:stylesheet>
The preceding example is for output from your server, but you could easily adapt this to any method you need by changing the first argument to each hasAuth call to whatever method this is filtering on. You could also easily use this as a base template and pass in the method name to the filter. This example assumes you have an input XML that looks something like the following example:
<User id="DEAD-BEAF"> <name>Foo</name> <username>foo</username> <email>someone@example.com</email> </User>
Using this example as a base, you could also build filters to operate with JSON or any other representation, but XSLT still seems to be the simplest because you can also use it to create more complex authorization systems, including a complicated group-based authentication, and it can be used to include filters within other filters. If you do need to support sending and receiving information in other formats, you can always use another filter layer on top of your application to translate between them.