Use extensions for fine-grained security

The <security-constraint> item in web.xml implements role-based security restrictions for your web application. It's <http-method> attribute lets you to specify POST, GET and so on, to restrict what kind of action is taken.

However, there's a big problem with this technique: browsers typically implement only POST and GET; they typically don't implement PUT and DELETE. This means that <http-method> is not very useful, in practice, for implementing fine-grained security constraints.

(It's important to note that the role-based security restrictions defined by the servlet specification do nothing for restrictions based on ownership of data, such as seen in many public web sites. Such restrictions prevent one user from editing items created by some other user, for example.)

There is an alternative to using <http-method>: use the extension appearing in the URL. In this case, URLs take the form:

When thinking of security, it's natural to think in terms of nouns and verbs:

In the above example, Account is the noun, while the extension (.list, .add, and so on) is the verb. With this style, any degree of granularity for security constraints can be implemented. One can mix and match the nouns and the verbs independently of each other, in a natural way.

Example 1
Only a manager can perform this specific delete operation :

<security-constraint>
 <web-resource-collection>
  <web-resource-name>Deleting Members</web-resource-name>
  <url-pattern>/main/member/MemberAction.delete</url-pattern>
 </web-resource-collection>
 <auth-constraint>
  <role-name>manager</role-name>
 </auth-constraint>
</security-constraint>

Example 2

A reader can read, but not write to the database :

<security-constraint>
 <web-resource-collection>
  <web-resource-name>View Operations</web-resource-name>
  <url-pattern>*.list</url-pattern>
  <url-pattern>*.fetch</url-pattern>
 </web-resource-collection>
 <auth-constraint>
  <role-name>reader</role-name>
 </auth-constraint>
</security-constraint>

Example 3

An editor can both read and write to a database :

<security-constraint>
 <web-resource-collection>
  <web-resource-name>Edit Operations</web-resource-name>
  <url-pattern>*.list</url-pattern>
  <url-pattern>*.fetch</url-pattern>
  <url-pattern>*.add</url-pattern>
  <url-pattern>*.change</url-pattern>
  <url-pattern>*.delete</url-pattern>
  <url-pattern>*.fetchForChange</url-pattern>
 </web-resource-collection>
 <auth-constraint>
  <role-name>editor</role-name>
 </auth-constraint>
</security-constraint>

Example 4

Only an webmaster can access URLs starting with /webmaster/* :

<security-constraint>
 <web-resource-collection>
  <web-resource-name>Webmaster</web-resource-name>
  <url-pattern>/webmaster/*</url-pattern>
 </web-resource-collection>
 <auth-constraint>
  <role-name>webmaster</role-name>
 </auth-constraint>
</security-constraint>

Example 5

Only an megawebmaster can access /webmaster/Logs.delete :

<security-constraint>
 <web-resource-collection>
  <web-resource-name>Log Deletion</web-resource-name>
  <url-pattern>/webmaster/Logs.delete</url-pattern>
 </web-resource-collection>
 <auth-constraint>
  <role-name>megawebmaster</role-name>
 </auth-constraint>
</security-constraint>

Here's a table showing whether access is granted in various cases, given the above constraints:

For User With Role(s) Accessing URL Allow Access?
editor ../Account.list Y
editor ../Account.delete Y
reader ../Account.list Y
reader ../Account.delete N
editor /main/member/MemberAction.delete N
reader, manager /main/member/MemberAction.delete Y
reader /webmaster/Logs.list N
webmaster /webmaster/Logs.list Y
webmaster /webmaster/Logs.delete N


Would you use this technique?
Yes   No   Undecided   
© 2014 Hirondelle Systems | Source Code | Contact | License | RSS
Individual code snippets can be used under this BSD license - Last updated on September 21, 2013.
Over 2,000,000 unique IPs last year - Built with WEB4J.
- In Memoriam : Bill Dirani -