tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Brian McBride <bwm.topmea...@googlemail.com>
Subject interaction between .forward() and <security-constraint>
Date Sat, 04 Sep 2010 08:28:59 GMT

  Hi,

I want to implement discretionary access control in an app running in 
Tomcat - i.e. access controls on URLs served by Tomcat can be changed by 
users.  I expect to have a 1M resources each with its own ACL.  Some 
resources have 'public' access.  No authentication should be required to 
access them.  Access to some resources is constrained and does require 
authentication.  The same resource may be access controlled one minute 
and public the next.  The URL of a resource may not change when its ACL 
changes.

I have been approaching this by trying to use the built in Tomcat 
authentication and creating my own authorization filter.  The problem 
I'm hitting is that getRemoteUser is returning null.  I believe the 
reason it is returning null is that I have no <auth-constraint> element 
in my security constraint:

<security-constraint>
<display-name>Authenticate</display-name>
<web-resource-collection>
<web-resource-name>resources</web-resource-name>
<description></description>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>HEAD</http-method>
<http-method>PUT</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
</security-constraint>

Despite the fact that I have arranged for the incoming request to have 
an Authorization header (I send my own 401 responses), Tomcat does not 
process it unless the there is an <auth-constraint> that applies to the 
requested resource.  This is consistent with what the servlet spec says:

[[An authorization constraint establishes a requirement for 
authentication ...]]

I want to have no authorization constraint because some resources have 
public access and no authentication is required for access to those 
resources.

I have tried using getRequestDispatcher(...).forward(...) to forward 
requests for resources that require authentication to a different URL 
and defining a different security constraint for those URLs:

<security-constraint>
<display-name>Authenticate</display-name>
<web-resource-collection>
<web-resource-name>authenticated resources</web-resource-name>
<description></description>
<url-pattern>/authenticated/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>HEAD</http-method>
<http-method>PUT</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>REGISTERED</role-name>
</auth-constraint>
</security-constraint>

getRemoteUser() still returns null.  .forward() does not seem to be 
subject to security checks.  I have found nothing in the Servlet spec 
that tells me what the behaviour should be.

I have three questions:

1) Is there a way I can programatically cause the authentication check?

[Currently I send my own 401 response if authentication is required.   
If a call to getRemoteUser() were to cause the processing of a present 
Authorization header, if that processing had not been done already,  
that would support my approach.  I don't yet know if/how I could compute 
an appropriate challenge for the 401 responses I generate for digest 
authentication, which I would want to use preference to Basic 
authentication.]

2) Is there another way to implement discretionary access control, other 
than implementing my own authentication mechanism?  Has anyone else 
solved this problem?

3) Is Tomcat's behaviour 'correct'?  There may be good reason for the 
current interpretation of the spec, but from my point of view allowing 
.forward() to circumvent declared security constraints is questionable.

I am using Tomcat 6.0.29.  Sorry its such a long winded mail.

Brian




Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message