Re: blocking access using filter (fwd)

2001-11-15 Thread Richard Troy

Date: Wed, 17 Oct 2001 16:41:33 -0700 (PDT)
From: Craig R. McClanahan [EMAIL PROTECTED]
Reply-To: [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Subject: Re: blocking access using filter



On Wed, 17 Oct 2001, Taavi Tiirik wrote:

 Date: Wed, 17 Oct 2001 22:47:53 +0200
 From: Taavi Tiirik [EMAIL PROTECTED]
 Reply-To: [EMAIL PROTECTED]
 To: [EMAIL PROTECTED]
 Subject: blocking access using filter

 Hey,

 I need more sophisticated access control for certain
 documents than JDBCRealm provides. These documents
 reside in separate directory tree and they are
 served by standalone tomcat 4. I have mapped an
 'access control filter' to listen to all requests to
 this directory. Filter should behave like this:

 1. If user is not logged in or if the session has
 timed out then it should open login page and after
 successful login it should try to access the very
 same request (ie. the same document).

 / I am using getRemoteUser() to determine if user
 is logged in. /

 2. Filter performs a database lookup and decides if
 given user can access this document.

 / This step is easy and I can live with extra
 overhead needed for database query. /

 3. If user does not have rights to access this
 document then filter should send error 404 (no such
 document).

 / This can be achieved using:
   response.sendError( HttpServletResponse.SC_NOT_FOUND ); /

 4. Do nothing... ie. user will get this document.

 / 'do nothing' actually means calling next filter in
   chain like this:
   chain.doFilter( request, response ); /


That's a pretty impressive amount of learning-by-doing!


 I have figured out all steps but the very first one.
 What should I do in filter in order to make tomcat
 to use it's standard authentication mechanism
 (JDBCRealm, form based login in my case) so
 the user could log in and still get required document?


What you've got so far doesn't really correspond to JDBCRealm, which is
just a way to tell Tomcat how to look up users.

I don't quite see why you need to modify the standard form-based login
mechanisms, either.  Can't you just use the standard form based login for
triggering authentication?  This would be as simple as a security
constraint that looks like this:

  security-constraint
web-resource-collection
  web-resource-nameThe Entire Webapp/web-resource-name
  url-pattern /* /url-pattern
/web-resource-collection
auth-constraint
  role-name * /role-name
/auth-constraint
  /security-constraint

The /* URL pattern means that every single URL inside this webapp is
protected by the constraint.  The * in role names mean that it doesn't
matter what role(s) the user has -- every request requires an
authenticated user.  Therefore, by the time your filter is invoked,
getRemoteUser() will return the username you are looking for, and you can
impose any *additional* constraints that you need to.

Form based login already does the rest of what your step (1) includes - it
remembers the page that the user asks for (if it switches them to the
login screen), and automatically replays it once authentication is done.

If you really did want to modify the Tomcat authenticator, you would need
to turn this filter into an implementation of the
org.apache.catalina.Valve interface, which is conceptually pretty
similar to a Filter.  Valves (including the standard one used for
authentication) are invoked before the Filters (and the ultimate servlet)
belonging to your web application are invoked.

 Please, any help is appreciated. I will happily donate
 this filter back to the group if I get it working and
 if there is interest.

 thanks in advance,
 Taavi



Craig



--
To unsubscribe:   mailto:[EMAIL PROTECTED]
For additional commands: mailto:[EMAIL PROTECTED]
Troubles with the list: mailto:[EMAIL PROTECTED]




RE: blocking access using filter (fwd)

2001-11-15 Thread Richard Troy

Date: Thu, 18 Oct 2001 11:58:34 +0200
From: Taavi Tiirik [EMAIL PROTECTED]
Reply-To: [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Subject: RE: blocking access using filter

Thanks, Craig!

  1. If user is not logged in or if the session has
  timed out then it should open login page and after
  successful login it should try to access the very
  same request (ie. the same document).

 I don't quite see why you need to modify the standard
 form-based login mechanisms, either.  Can't you just use
 the standard form based login for triggering authentication?

No, I did not want to modify standard login mechanism by
any means :-). I simply had this (wrong) impression that
filters get called before checking security constraints.
How stupid of me :-). Creating security constraint like
you suggested covered the first step and now I have this
filter purring like a kitten.

Just in case anybody is interested... this is what I did.
doFilter looks like this:

public void doFilter (
ServletRequest request,
ServletResponse response,
FilterChain chain
)
throws IOException, ServletException
{
HttpServletRequest httpRequest = null;
HttpServletResponse httpResponse = null;

if( request instanceof HttpServletRequest )
httpRequest = (HttpServletRequest)request;

if( response instanceof HttpServletResponse )
httpResponse = (HttpServletResponse)response;

boolean authorized = false;
String user = httpRequest.getRemoteUser();

// Is this really necessary? Could it be that requests
// other than HttpServletRequest are passed to
// this filter? Can they be harmful by any means?
// Or should I let them through?
if( httpRequest == null || httpResponse == null || user == null
){
httpResponse.sendError( HttpServletResponse.SC_NOT_FOUND
);
return;
}

try {
// At this point we have user name in 'user' and request
URI
// in 'requestURI'. Make sure that this user has rights
to
// get this document and set authorized to true, if
(s)he has.

authorized = ...

} catch( Exception e ){
}

if( !authorized ){
httpResponse.sendError( HttpServletResponse.SC_NOT_FOUND
);
return;
}

// Pass control on to the next filter
chain.doFilter( request, response );
}

with best wishes,
Taavi



--
To unsubscribe:   mailto:[EMAIL PROTECTED]
For additional commands: mailto:[EMAIL PROTECTED]
Troubles with the list: mailto:[EMAIL PROTECTED]




RE: blocking access using filter

2001-10-18 Thread Taavi Tiirik

Thanks, Craig!

  1. If user is not logged in or if the session has
  timed out then it should open login page and after
  successful login it should try to access the very
  same request (ie. the same document).

 I don't quite see why you need to modify the standard
 form-based login mechanisms, either.  Can't you just use
 the standard form based login for triggering authentication?

No, I did not want to modify standard login mechanism by
any means :-). I simply had this (wrong) impression that
filters get called before checking security constraints.
How stupid of me :-). Creating security constraint like
you suggested covered the first step and now I have this
filter purring like a kitten.

Just in case anybody is interested... this is what I did.
doFilter looks like this:

public void doFilter (
ServletRequest request,
ServletResponse response,
FilterChain chain
)
throws IOException, ServletException
{
HttpServletRequest httpRequest = null;
HttpServletResponse httpResponse = null;

if( request instanceof HttpServletRequest )
httpRequest = (HttpServletRequest)request;

if( response instanceof HttpServletResponse )
httpResponse = (HttpServletResponse)response;

boolean authorized = false;
String user = httpRequest.getRemoteUser();

// Is this really necessary? Could it be that requests
// other than HttpServletRequest are passed to
// this filter? Can they be harmful by any means?
// Or should I let them through?
if( httpRequest == null || httpResponse == null || user == null
){
httpResponse.sendError( HttpServletResponse.SC_NOT_FOUND
);
return;
}

try {
// At this point we have user name in 'user' and request
URI
// in 'requestURI'. Make sure that this user has rights
to
// get this document and set authorized to true, if
(s)he has.

authorized = ...

} catch( Exception e ){
}

if( !authorized ){
httpResponse.sendError( HttpServletResponse.SC_NOT_FOUND
);
return;
}

// Pass control on to the next filter
chain.doFilter( request, response );
}

with best wishes,
Taavi