<security-constraint>
item in web.xml
implements role-based security restrictions for your web application.
Its <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's an alternative to using <http-method>
: use the extension appearing in the URL.
In this case, URLs take the form:
.../Account.list
.../Account.add
.../Account.delete
.../Account.fetch?Id=45
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 a 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 a 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 |