Toon posts:

[Java/J2EE] Filters, excluding URL pattern?

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik vroeg me af of het mogelijk is om op een of andere manier te specificeren dat een bepaald URL pattern uitgesloten moet worden voor filtering in een J2EE omgeving.

Ik heb nu een filter die alle jsp's filters (*.jsp) en een servlet die gemapped staat op uitzondering.jsp.

Nu wil ik graag dat uitzondering.jsp wordt gekozen boven *.jsp. Dit werkt wel met servlets onderling. Daar geldt de regel dat de meest specificieke naam gekozen wordt, maar bij filters is dat precies andersom.

Ik heb het wel opgelost door in mijn filter code op te nemen die checked op de requestURI en dan meteen een chain.doFilter te doen. Dit werkt, en de servlet die op uitzondering.jsp staat gemapped wordt dan ook correct aangesproken. Echter, ik vind deze oplossing verre van mooi.

Weet iemand een mooiere oplossing waarbij ik alleen dingen in web.xml specificeer?

  • Glabbeek
  • Registratie: Februari 2001
  • Laatst online: 12-02 11:54

Glabbeek

Dat dus.

Dit is een leuke. Ik dacht eerst 'Dat moet toch gewoon kunnen?', maar het is toch een stuk lastiger dan ik dacht.

De <url-pattern> kan maar 3 soorten values bevatten, te weten:
• /foo/*
• /foo
• *.foo

Hierdoor kan je dus niet een bepaalde url uitsluiten. Na veel uitproberen en zoeken blijkt dat sommige application servers naast <url-pattern> ook een <url-regexp> kennen. Daarmee kan je vast wel een reguliere expressie gebruiken die op alle jsp's valideert behalve exception.jsp.

Helaas is het me na veel zoeken niet duidelijk geworden welke application servers de <url-regexp> wel accepteren en welke niet. Ik gebruik hier IBM WebSphere Application Server V5.0 en die lijkt het niet te ondersteunen. Aangezien WAS gebaseerd is op Tomcat verwacht ik dat die het ook niet zal ondersteunen, maar dat heb ik niet uitgeprobeerd.

Als je trouwens in Google zoekt op 'servlet filter url-pattern exception' komen een paar hits naar voren waarin aangegeven wordt dat exceptions niet mogelijk zijn. Deze hits wijzen echter allemaal naar dezelfde vraag en hetzelfde antwoord, wat ooit op een forum of op Usenet is geplaatst, niet naar officiele documentatie.

Ik ben dus bang dat de oplossing die je nu gebruikt (in het servlet filter coderen dat hij bij bepaalde uri's niets moet uitvoeren) de enige oplossing is. Ik ben het zeker met je eens dat het geen mooie oplossing is, want als je later ook andere uri's wilt uitzonderen moet de code aangepast worden.

edit:


Hmm, ik heb toch nog een ideetje: Je kan natuurlijk de URL waarop de het filter niet mag vuren ook als contextparameter in de web.xml plaatsen (als voorbeeld gebruik ik hier even de URL '/servlet1')

code:
1
2
3
4
    <context-param>
        <param-name>filterexception</param-name>
        <param-value>Servlet1</param-value>
    </context-param>


Dan kan je in je servlet deze waarde ophalen en bekijken of de requestURI hieraan gelijk is. Dan is de URI waarop je filter niet mag vuren toch nog configureerbaar in de web.xml.

Een voorbeeldje van de code die filtert op de context-param 'filterexception':

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    public void doFilter(
        ServletRequest req,
        ServletResponse resp,
        FilterChain chain)
        throws ServletException, IOException {
        try {
            ServletContext context = this.config.getServletContext();

            String filterException =
                context.getInitParameter("filterexception");
            HttpServletRequest httpReq = (HttpServletRequest) req;

            PrintWriter out = resp.getWriter();
            if (!(httpReq.getRequestURI().endsWith(filterException))) {
                out.println("The filter should be called<br>");
            } else {
                out.println("The filter shouldn&acute;t be called<br>");
            }

        } catch (IOException ex) {
            ex.printStackTrace();
        }
        chain.doFilter(req, resp);
    }


Ik hoop dat je hier wat aan hebt. Ik heb in ieder geval weer een leuk avondje uitzoeken en programmeren achter de rug :)

[ Voor 40% gewijzigd door Glabbeek op 30-09-2004 23:06 ]

En zo is het maar net.


Verwijderd

Topicstarter
Glabbeek schreef op 30 september 2004 @ 22:58:
Dit is een leuke. Ik dacht eerst 'Dat moet toch gewoon kunnen?', maar het is toch een stuk lastiger dan ik dacht.
Precies wat ik ook dacht. Dat moet toch gewoon kunnen? Het is helemaal geen rare gedachte, en lijkt me iets wat wel vaker voorkomt.
Als je trouwens in Google zoekt op 'servlet filter url-pattern exception' komen een paar hits naar voren waarin aangegeven wordt dat exceptions niet mogelijk zijn.
Bijna dezelfde keywords als ik ook gebruikte :)
Ik ben het zeker met je eens dat het geen mooie oplossing is, want als je later ook andere uri's wilt uitzonderen moet de code aangepast worden.
Inderdaad, plus dat het in veel gevallen helemaal geen logische functie is van een filter zelf om hardcoded bepaalde URI's uit te zonderen. Als ik bijvoorbeeld een universeel access controll filter maakt, dan hoeft dat filter niets te weten van URI's die ik toevallig wil uitzonderen.
Hmm, ik heb toch nog een ideetje: Je kan natuurlijk de URL waarop de het filter niet mag vuren ook als contextparameter in de web.xml plaatsen (als voorbeeld gebruik ik hier even de URL '/servlet1')
Dat is inderdaad een heel goed idee! :) Mischien dat idee nog een stapje verder uitbouwen, een superclass voor al je filters maken die de uitzonderings code zelf bevat met een functie die een boolean terug geeft of de subclass filter wel door moet gaan of niet.
Java:
1
2
3
4
5
6
7
8
...
            if (!(httpReq.getRequestURI().endsWith(filterException))) {
                out.println("The filter should be called<br>");
            } else {
                out.println("The filter shouldn&acute;t be called<br>");
            }

...
Waarom eigenlijk endsWith? Is dat omdat een resource met een / kan beginnen en soms niet?

Omdat het in mijn geval om een security filter gaat moet ik heel voorzichtig te werk gaan zodat mensen niet een gat kunnen gebruiken door de naam van een niet beschermde resource achter de naam van een beschermde te plakken.

Natuurlijk zal het zo'n vaart niet lopen want requestURI geeft niet de query string erbij, dus weinig kwaad zal het niet kunnen. Bv als a.jsp beschermt is en b.jsp niet, dan zal een gebruiker met een request als a.jspb.jsp wel door de beveiliging komen, maar vervolgens op een not found stuiten.
Ik hoop dat je hier wat aan hebt.
Zeker, het is een goed idee. Nog een stapje verder kun je ook zelf reguliere expressies gaan gebruiken. Ik blijf het echter raar vinden dat zoiets niet in de standaard zit.
Ik heb in ieder geval weer een leuk avondje uitzoeken en programmeren achter de rug :)
Dat is toch ook weer wat waart ;)

  • Glabbeek
  • Registratie: Februari 2001
  • Laatst online: 12-02 11:54

Glabbeek

Dat dus.

De endsWith gebruik ik omdat de getRequestURI bij mij '/demoServlet/Servlet1' terug geeft in ik alleen 'Servlet1' in de contextparam value had gezet. It's as simple as that :)

Ik ben het zeker met je eens dat je zou verwachten dat dit standaard mogelijk is.

[ Voor 11% gewijzigd door Glabbeek op 30-09-2004 23:49 ]

En zo is het maar net.