You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Leo Donahue <do...@gmail.com> on 2015/06/25 22:11:56 UTC

Filter behaviour

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException

Assuming you have only a single Filter configured in web.xml

Assuming you have logic in a doFilter that checks the value of a boolean.
If the boolean is true, then assume you send a http status code back and
use a "return" in the if condition.

example:

        if (someConditionIsTrue)
        {
            HttpServletResponse httpResponse = (HttpServletResponse)
response;
            httpResponse.sendError(HttpServletResponse.WHATEVER_YOU_CHOOSE);
            return;
        }

        chain.doFilter(request, response);


My question is:

If the chain is placed inside an else, which would not run if the condition
is true, does that violate the Filter in any way?  In other words, if one
does not call chain.doFilter within a doFilter method, should one expect
something bad?

What I'm really saying without saying it is, whether I call chain.doFilter
in or out of an "else", on Tomcat I get the sendError status that I expect,
but not from other containers.  I realize that statement is moot on this
list, but I thought I would share it.

Are there any conditions in which Tomcat will decide what to do on its own,
related to sendError, when it can't figure it out from code?

Leo


Using CATALINA_BASE:   "C:\apache-tomcat\apache-tomcat-7.0.62"
Using CATALINA_HOME:   "C:\apache-tomcat\apache-tomcat-7.0.62"
Using CATALINA_TMPDIR: "C:\apache-tomcat\apache-tomcat-7.0.62\temp"
Using JRE_HOME:        "C:\Program Files (x86)\Java\jdk1.7.0_67"
Using CLASSPATH:
"C:\apache-tomcat\apache-tomcat-7.0.62\bin\bootstrap.jar;C:\apache-tomcat\apache-tomcat-7.0.62\bin\tomcat-juli.jar"
Server version: Apache Tomcat/7.0.62
Server built:   May 7 2015 17:14:55 UTC
Server number:  7.0.62.0
OS Name:        Windows 7
OS Version:     6.1
Architecture:   x86
JVM Version:    1.7.0_67-b01
JVM Vendor:     Oracle Corporation

Re: Filter behaviour

Posted by Konstantin Kolinko <kn...@gmail.com>.
>>
>> > The scenario I'm working on is a web service.  The web service has
>> > three filters, in order they are:  throttle filter, authentication
>> > filter, logging filter.
>> >
>> > If a user is not authenticated, the following code "should" break
>> > out of the filter chain and redirect the user to a custom 403.  It
>> > works nice on Tomcat.
>> >
>> > HttpServletResponse httpResponse = (HttpServletResponse) response;
>> >
>> > httpResponse.sendError(HttpServletResponse.HttpServletResponse.SC_FORB
>> IDDEN);
>> >
>> >
>> return;
>> >
>> > What I'm seeing on other containers is that I get a NPE where the
>> > Service class is trying to do something with the authenticated
>> > user, which is null. I realize this is not an "other containers"
>> > forum, but I was just curious what the expected behaviour *should*
>> > be.
>>
>> If you have other stuff going on -- like custom error pages -- you
>> might find that more of your own code is running than you expect. See
>> Konstantin's response. It's terse, but I think he's likely getting to
>> the root of your problem.
>>
>> - -chris
>>
>
> Gentlemen,
>
> Thank you for the assistance.
>
> I still don't know what was causing my issue on said other container with
> respect to sendError and custom error-page elements, but...
>
> This works fine and was really what I was after, a simple custom 403
> message, no html:
>
>     public void doFilter(ServletRequest request, ServletResponse response,
> FilterChain chain) throws IOException, ServletException
>     {
>         boolean iAmNotAuthorized = true;
>
>         if (iAmNotAuthorized)
>         {
>             // generate the HTTP Servlet Response for a 403 status code
>             HttpServletResponse httpResponse = (HttpServletResponse)
> response;
>             //httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
>             httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
>             httpResponse.setHeader("WWW-Authenticate", "Basic");

"WWW-Authenticate" header is usually used with 401 response.

It is unusual to use it with 403 one, though the spec does not forbid
it. (I am not sure how browsers react here, though)

http://tools.ietf.org/html/rfc7235#section-4.1

>             httpResponse.getOutputStream().print("blah, blah, blah");
>
>             // return from the doFilter method
>             return;
>         }
>
>         chain.doFilter(request, response);
>
>     }
>

Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Filter behaviour

Posted by Leo Donahue <do...@gmail.com>.
On Fri, Jun 26, 2015 at 11:09 AM, Christopher Schultz <
chris@christopherschultz.net> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> Leo,
>
> >
> > If I use a return statement to break out of a filter, what should
> > happen? Will the next filter run?
>
> No. The Filter is responsible for calling the next filter in the
> chain. If you don't, the target servlet will never be called.
>
> > Shouldn't a return statement in a filter, especially one that
> > comes right after a sendError call, send the error and direct the
> > user to the page configured for such errors?
>
> Yes.
>
> > The scenario I'm working on is a web service.  The web service has
> > three filters, in order they are:  throttle filter, authentication
> > filter, logging filter.
> >
> > If a user is not authenticated, the following code "should" break
> > out of the filter chain and redirect the user to a custom 403.  It
> > works nice on Tomcat.
> >
> > HttpServletResponse httpResponse = (HttpServletResponse) response;
> >
> > httpResponse.sendError(HttpServletResponse.HttpServletResponse.SC_FORB
> IDDEN);
> >
> >
> return;
> >
> > What I'm seeing on other containers is that I get a NPE where the
> > Service class is trying to do something with the authenticated
> > user, which is null. I realize this is not an "other containers"
> > forum, but I was just curious what the expected behaviour *should*
> > be.
>
> If you have other stuff going on -- like custom error pages -- you
> might find that more of your own code is running than you expect. See
> Konstantin's response. It's terse, but I think he's likely getting to
> the root of your problem.
>
> - -chris
>

Gentlemen,

Thank you for the assistance.

I still don't know what was causing my issue on said other container with
respect to sendError and custom error-page elements, but...

This works fine and was really what I was after, a simple custom 403
message, no html:

    public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
    {
        boolean iAmNotAuthorized = true;

        if (iAmNotAuthorized)
        {
            // generate the HTTP Servlet Response for a 403 status code
            HttpServletResponse httpResponse = (HttpServletResponse)
response;
            //httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
            httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
            httpResponse.setHeader("WWW-Authenticate", "Basic");
            httpResponse.getOutputStream().print("blah, blah, blah");

            // return from the doFilter method
            return;
        }

        chain.doFilter(request, response);

    }

leo

Re: Filter behaviour

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Leo,

On 6/26/15 10:38 AM, Leo Donahue wrote:
> On Fri, Jun 26, 2015 at 1:42 AM, André Warnier <aw...@ice-sa.com>
> wrote:
> 
>> 
>> I must admit that your question above was a bit difficult to
>> follow, in terms of if/then/else/unless, particularly late at
>> night.
> 
> 
> Yes, you are right.  Sorry about that.  I was trying to walk the
> line between saying too much and not enough and so it came out all
> gibberish.
> 
> 
>> And the last paragraph made me think that perhaps the Tomcat logo
>> might lead you to personalise things a bit more than is really
>> healthy. (Or else I want to have a look at that code, because the
>> Tomcat developers must be even smarter that I thought).
>> 
>> But if your question in the end boils down to : *must* a filter 
>> necessarily call the next filter/webapp in the chain, then the
>> answer is in the Servlet Specification. E.g. Servlet Spec v 3.0
>> final, Chapt 6 Filtering, Section 6.2 Main concepts, item 4 : 
>> "The filter *may* invoke the next entity in the filter chain".. 
>> It even adds : "Alternatively, the filter chain can block the
>> request by not making the call to invoke the next entity, leaving
>> the filter responsible for filling out the response object."
>> 
>> (What you need to do then still, is to insure that you do indeed
>> generate a valid response, whether it's an error or not.  That's
>> maybe the point where different containers may react slightly
>> differently.).
>> 
> 
> If I use a return statement to break out of a filter, what should
> happen? Will the next filter run?

No. The Filter is responsible for calling the next filter in the
chain. If you don't, the target servlet will never be called.

> Shouldn't a return statement in a filter, especially one that
> comes right after a sendError call, send the error and direct the
> user to the page configured for such errors?

Yes.

> The scenario I'm working on is a web service.  The web service has
> three filters, in order they are:  throttle filter, authentication
> filter, logging filter.
> 
> If a user is not authenticated, the following code "should" break
> out of the filter chain and redirect the user to a custom 403.  It
> works nice on Tomcat.
> 
> HttpServletResponse httpResponse = (HttpServletResponse) response;
> 
> httpResponse.sendError(HttpServletResponse.HttpServletResponse.SC_FORB
IDDEN);
>
> 
return;
> 
> What I'm seeing on other containers is that I get a NPE where the
> Service class is trying to do something with the authenticated
> user, which is null. I realize this is not an "other containers"
> forum, but I was just curious what the expected behaviour *should*
> be.

If you have other stuff going on -- like custom error pages -- you
might find that more of your own code is running than you expect. See
Konstantin's response. It's terse, but I think he's likely getting to
the root of your problem.

- -chris
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org

iQIcBAEBCAAGBQJVjXlRAAoJEBzwKT+lPKRYKbIP/1qu3FTeXTe/npc0b8V+A6rQ
NQ25s9gd/d1araILYRPViDS56k7hFGHLO82OBuJ+LPAIK4fn0wWM3fSbIw8VRAac
nksimpXVYIjW6d7Q5im1osoBO7WBJJBfRRa+RsjvtbxSaWaYbtxW08irdH7gKBud
HsitX1w2s252NUFyt6G37sPMtXTlNMyMVPgXJTq8iwnR7BR/bzFw514E1zEd9AX+
98+MNP90044KqHDy33zWnYPU3aGR54uw6H+BfSDst4lSGWyVPzpo054WKsQuQEFu
zglgB97iC78RLUbA2VaGo3K4CTQioAXEo25wn4jw/ls1fCMpCxWJTCivHHVutwnp
B7q8qPtBx1mrLr+orGmkAPuNoVyLOGOhbsVY4P50iCXWN8aIGzc0uBE9D4rv919f
iQgHHMaJajEmjuLNoJM15Kj2bc/oUvSCWyOEXMZGQuVN8FOAs2SLoeyuHXAfhzum
9MAiMhK1g4s16CqNWYtkG3ePcvAthaNB8ZOI7nNjOxa8Hr4PuET/Ram1MoX23d4g
EuENlsj6DaIo0CGAWZv5Il3j6G4jUkjGyQFYU7xZN3ilBppmZN3h2xx6ZOReXNFd
iq7KHbjfQSLEyjuCIV02I/VOAwKqJnU30T8aAcx93ftFzUxg6ixZD1zfEUwMlhvg
JUn7r/FNXThidonZbGg4
=P26m
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Filter behaviour

Posted by Leo Donahue <do...@gmail.com>.
On Fri, Jun 26, 2015 at 1:42 AM, André Warnier <aw...@ice-sa.com> wrote:

>
> I must admit that your question above was a bit difficult to follow, in
> terms of if/then/else/unless, particularly late at night.


Yes, you are right.  Sorry about that.  I was trying to walk the line
between saying too much and not enough and so it came out all gibberish.


> And the last paragraph made me think that perhaps the Tomcat logo might
> lead you to personalise things a bit more than is really healthy.
> (Or else I want to have a look at that code, because the Tomcat developers
> must be even smarter that I thought).
>
> But if your question in the end boils down to : *must* a filter
> necessarily call the next filter/webapp in the chain, then the answer is in
> the Servlet Specification.
> E.g. Servlet Spec v 3.0 final, Chapt 6 Filtering, Section 6.2 Main
> concepts, item 4 :
> "The filter *may* invoke the next entity in the filter chain"..
> It even adds : "Alternatively, the filter chain can block the request by
> not making the call to invoke the next entity, leaving the filter
> responsible for filling out the response object."
>
> (What you need to do then still, is to insure that you do indeed generate
> a valid response, whether it's an error or not.  That's maybe the point
> where different containers may react slightly differently.).
>

If I use a return statement to break out of a filter, what should happen?
Will the next filter run?  Shouldn't a return statement in a filter,
especially one that comes right after a sendError call, send the error and
direct the user to the page configured for such errors?

The scenario I'm working on is a web service.  The web service has three
filters, in order they are:  throttle filter, authentication filter,
logging filter.

If a user is not authenticated, the following code "should" break out of
the filter chain and redirect the user to a custom 403.  It works nice on
Tomcat.

            HttpServletResponse httpResponse = (HttpServletResponse)
response;

httpResponse.sendError(HttpServletResponse.HttpServletResponse.SC_FORBIDDEN);
            return;

What I'm seeing on other containers is that I get a NPE where the Service
class is trying to do something with the authenticated user, which is null.
I realize this is not an "other containers" forum, but I was just curious
what the expected behaviour *should* be.

Leo

Re: Filter behaviour

Posted by André Warnier <aw...@ice-sa.com>.
Leo Donahue wrote:
> public void doFilter(ServletRequest request, ServletResponse response,
> FilterChain chain) throws IOException, ServletException
> 
> Assuming you have only a single Filter configured in web.xml
> 
> Assuming you have logic in a doFilter that checks the value of a boolean.
> If the boolean is true, then assume you send a http status code back and
> use a "return" in the if condition.
> 
> example:
> 
>         if (someConditionIsTrue)
>         {
>             HttpServletResponse httpResponse = (HttpServletResponse)
> response;
>             httpResponse.sendError(HttpServletResponse.WHATEVER_YOU_CHOOSE);
>             return;
>         }
> 
>         chain.doFilter(request, response);
> 
> 
> My question is:
> 
> If the chain is placed inside an else, which would not run if the condition
> is true, does that violate the Filter in any way?  In other words, if one
> does not call chain.doFilter within a doFilter method, should one expect
> something bad?
> 
> What I'm really saying without saying it is, whether I call chain.doFilter
> in or out of an "else", on Tomcat I get the sendError status that I expect,
> but not from other containers.  I realize that statement is moot on this
> list, but I thought I would share it.
> 
> Are there any conditions in which Tomcat will decide what to do on its own,
> related to sendError, when it can't figure it out from code?
> 
> Leo
> 
> 
> Using CATALINA_BASE:   "C:\apache-tomcat\apache-tomcat-7.0.62"
> Using CATALINA_HOME:   "C:\apache-tomcat\apache-tomcat-7.0.62"
> Using CATALINA_TMPDIR: "C:\apache-tomcat\apache-tomcat-7.0.62\temp"
> Using JRE_HOME:        "C:\Program Files (x86)\Java\jdk1.7.0_67"
> Using CLASSPATH:
> "C:\apache-tomcat\apache-tomcat-7.0.62\bin\bootstrap.jar;C:\apache-tomcat\apache-tomcat-7.0.62\bin\tomcat-juli.jar"
> Server version: Apache Tomcat/7.0.62
> Server built:   May 7 2015 17:14:55 UTC
> Server number:  7.0.62.0
> OS Name:        Windows 7
> OS Version:     6.1
> Architecture:   x86
> JVM Version:    1.7.0_67-b01
> JVM Vendor:     Oracle Corporation
> 

I must admit that your question above was a bit difficult to follow, in terms of 
if/then/else/unless, particularly late at night.  And the last paragraph made me think 
that perhaps the Tomcat logo might lead you to personalise things a bit more than is 
really healthy.
(Or else I want to have a look at that code, because the Tomcat developers must be even 
smarter that I thought).

But if your question in the end boils down to : *must* a filter necessarily call the next 
filter/webapp in the chain, then the answer is in the Servlet Specification.
E.g. Servlet Spec v 3.0 final, Chapt 6 Filtering, Section 6.2 Main concepts, item 4 :
"The filter *may* invoke the next entity in the filter chain"..
It even adds : "Alternatively, the filter chain can block the request by not making the 
call to invoke the next entity, leaving the filter responsible for filling out the 
response object."

(What you need to do then still, is to insure that you do indeed generate a valid 
response, whether it's an error or not.  That's maybe the point where different containers 
may react slightly differently.).



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Filter behaviour

Posted by Konstantin Kolinko <kn...@gmail.com>.
2015-06-25 23:11 GMT+03:00 Leo Donahue <do...@gmail.com>:
> public void doFilter(ServletRequest request, ServletResponse response,
> FilterChain chain) throws IOException, ServletException
>
> Assuming you have only a single Filter configured in web.xml
>
> Assuming you have logic in a doFilter that checks the value of a boolean.
> If the boolean is true, then assume you send a http status code back and
> use a "return" in the if condition.
>
> example:
>
>         if (someConditionIsTrue)
>         {
>             HttpServletResponse httpResponse = (HttpServletResponse)
> response;
>             httpResponse.sendError(HttpServletResponse.WHATEVER_YOU_CHOOSE);
>             return;
>         }
>
>         chain.doFilter(request, response);
>
>
> My question is:
>
> If the chain is placed inside an else, which would not run if the condition
> is true, does that violate the Filter in any way?  In other words, if one
> does not call chain.doFilter within a doFilter method, should one expect
> something bad?
>
> What I'm really saying without saying it is, whether I call chain.doFilter
> in or out of an "else", on Tomcat I get the sendError status that I expect,
> but not from other containers.  I realize that statement is moot on this
> list, but I thought I would share it.
>
> Are there any conditions in which Tomcat will decide what to do on its own,
> related to sendError, when it can't figure it out from code?
>
> Leo
>
>
> Using CATALINA_BASE:   "C:\apache-tomcat\apache-tomcat-7.0.62"
> Using CATALINA_HOME:   "C:\apache-tomcat\apache-tomcat-7.0.62"
> Using CATALINA_TMPDIR: "C:\apache-tomcat\apache-tomcat-7.0.62\temp"
> Using JRE_HOME:        "C:\Program Files (x86)\Java\jdk1.7.0_67"
> Using CLASSPATH:
> "C:\apache-tomcat\apache-tomcat-7.0.62\bin\bootstrap.jar;C:\apache-tomcat\apache-tomcat-7.0.62\bin\tomcat-juli.jar"
> Server version: Apache Tomcat/7.0.62
> Server built:   May 7 2015 17:14:55 UTC
> Server number:  7.0.62.0
> OS Name:        Windows 7
> OS Version:     6.1
> Architecture:   x86
> JVM Version:    1.7.0_67-b01
> JVM Vendor:     Oracle Corporation


1. A Filter can generate the response by itself. There is no need to
call the chain.

An example in Tomcat:
org.apache.catalina.filters.RemoteAddrFilter
org.apache.catalina.filters.RequestFilter#process(...)

2. There are several types of dispatch defined in Servlet specification.
See e.g. javax.servlet.DispatcherType enumeration.

Usually a Filter is configured to serve 'REQUEST' dispatches. Thus an
'ERROR' dispatch (triggered by sendError()) bypasses the filter.

Read about filters in the Servlet specification.

Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org