Autentizace pomocí filtrů – princip filtrů
V tomto článku si povíme něco bližšího o filtrech. Vysvětlíme si, co je to filtr, jak jej vytvořit a jak jej nastavit v souboru web.xml. Tyto znalosti budeme potřebovat, až budeme vytvářet filtry pro náš autentizační mechanismus.
Filtr
Při každém příchodu HTTP požadavku je vytvořena instance typu HttpServletRequest, která před tím, než bude dána k dispozici servletu, může projít posloupností filtrů, které mohou instanci modifikovat, nahradit za jinou, nebo dokonce i přesměrovat jinému servletu.
Filtr je instance třídy, která implementuje rozhraní Filter. Rozhraní má tři metody:
public void init(FilterConfig filterConfig) throws ServletException
– metoda je zavolána při inicializaci filtru. Slouží k nastavení filtru. Parametr metody nám slouží hlavně k získání konfiguračních údajů.public void destroy()
– metoda je zavolána při likvidaci filtru.public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException
– metoda provádí samotnou činnost filtru. Je-li nastaven filtr na nějaký servlet, bude vždy při požadavku na servlet zavolána právě tato metoda. Jako parametry obdrží HTTP požadavek (HttpServletRequest
), HTTP odpověď (HttpServletResponse
) a „následovníka“ v řetězci filtrů (FilterChain
).
Jak jsem se již zmínil, požadavky a odpovědi mohou projít řetězcem filtrů. Proto každý filtr má jako třetí parametr následovníka v řetězci filtrů. Jestliže již není žádný další filtr v řetězci filtrů, bude požadavek předán požadovanému servletu. Třída implementující rozhraní FilterChain
má metodu public void doFilter(ServletRequest request, ServletResponse response) throws java.io.IOException, ServletException
, jejíž zavolání předá požadavek a odpověď dalšímu následovníku v řetězci. Předání požadavku a odpovědi následovníkovi musíme zajistit v metodě doFilter
sami.
Nastavení filtru
Pro každý servlet (nebo obecně pro jakýkoli zdroj, který lze požadovat) lze nastavit filtr. Filtr se nastavuje v konfiguračním souboru web.xml pomocí elementů filter
a filter-mapping
. Pravidla pro umístění elementů v dokumentu jsou dána jeho DTD.
Element filter
Element filter
slouží k definici filtru. Na základě tohoto elementu bude vytvořena instance filtru. Jak je vidět z DTD, element může obsahovat několik potomků. Nejvýznamnější jsou ty povinné:
filter-name
– jednoznačný identifikátor filtru.filter-class
– název java třídy filtru. Filtr bude instancí této třídy.
Dále je dobré vědět o elementu init-param
. Element specifikuje parametry, které mají být předány filtru při jeho inicializaci. Elementů init-param
může být v elementu filter
libovolný (i nulový) počet. Element init-param
má dva povinné potomky:
param-name
– jméno parametru. Jméno parametru musí být v rámci jednoho filtru jednoznačné.param-value
– hodnota parametru.
Rozhraní FilterConfig
Zmínil jsem se o rozhraní FilterConfig. Instance třídy implementující rozhraní FilterConfig
je parametrem metody init
třídy filtru. Parametr typu FilterConfig
je předán filtru při inicializaci. Objekt obsahuje informace o konfiguraci filtru v souboru web.xml. Rozhraní má metody:
public java.lang.String getFilterName()
– vrací jméno filtru dané obsahem elementufilter-name
.public ServletContext getServletContext()
– vrátí „aplikaci“, ve které filtr běží.public java.lang.String getInitParameter(java.lang.String name)
– vrátí hodnotu parametru (obsah elementuparam-value
). Parametrem metody je název elementu, který je dán obsahem elementuparam-name
.public java.util.Enumeration getInitParameterNames()
– vrátí výčet jmen všech parametrů filtru. (Vrátí obsahy elementuparam-name
všech elementůinit-param
daného filtru.)
Element filter-mapping
Máme tedy inicializován filtr. Nyní ještě musíme určit, na jaké zdroje má být filtr aplikován. K tomu slouží element filter-mapping
. Povinnými potomky jsou:
filter-name
– jméno filtru, který má být aplikován. Obsah elementu musí být shodný s obsahem stejnojmenného elementu v elementufilter
.url-pattern
neboservlet-name
– určuje masku nebo konkrétní servlet, na který má být filtr aplikován. Elementfilter-mapping
musí obsahovat právě jeden z těchto elementů.
Příklad
Vytvoříme si jednoduchý filtr, který zjistí, jestli je HTTP požadavek typu POST. Jestliže ne, nepropustí požadavek k požadovanému zdroji. Jestliže ano, propustí požadavek a na konec vygenerované stránky vloží nějakou poznámku. U požadavku, který je propouštěn dál, vytvoří nový atribut.
O praktickém využití tohoto filtru by se dalo dost pochybovat. Jedná se jen o ukázkový příklad, na němž chci demonstrovat, že filtr může měnit požadavek, může měnit odpověď, nemusí požadavek propustit dále a podobně.
Metoda doFilter třídy ExampleFilter
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException
{
HttpServletRequest hrequest = (HttpServletRequest)request;
HttpServletResponse hresponse = (HttpServletResponse)response;
response.setCharacterEncoding(„windows-1250“);
java.io.PrintWriter out = response.getWriter();
if („POST“.equals(hrequest.getMethod()))
{
// Nastavím atribut
hrequest.setAttribute(„nazev“, „hodnota“);
// Pustím požadavek dále
chain.doFilter(hrequest, hresponse);
// Modifikuji odpověď
out.println(„<!– Požadavek i odpověď prošly filtrem. –>“);
}
else
{ // Požadavek nepropouštím dále, rovnou vytvořím odpověď
out.println(„<!DOCTYPE HTML PUBLIC \“-//W3C//DTD HTML 4.0 Transitional//EN\“>“);
out.println(„<html><head><meta http-equiv=\“Content-Type\“ content=\“text/html; charset=windows-1250\“>“);
out.println(„<title>Vítejte</title></head><body><p>Požadavek není zaslán metodou POST.</p></body></html>“);
}
}
Konfigurace filtru
Vytvoříme si dvě instance filtru. Podle masky nastavíme každou instanci na jinou oblast a obě instance dohromady na třetí oblast. Část souboru web.xml týkající se filtrů bude vypadat takto:
<filter>
<filter-name>instance1</filter-name>
<filter-class>example.ExampleFilter</filter-class>
</filter>
<filter>
<filter-name>instance2</filter-name>
<filter-class>example.ExampleFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>instance1</filter-name>
<url-pattern>/1/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>instance2</filter-name>
<url-pattern>/2/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>instance1</filter-name>
<url-pattern>/3/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>instance2</filter-name>
<url-pattern>/3/*</url-pattern>
</filter-mapping>
K dispozici je vám kompletní zdrojový text společně s ukázkovou aplikací, abyste si filtr mohli sami otestovat.
Mohlo by vás také zajímat
-
Od iPhonu po Android: Ultra HDR přináší nový standard fotografií
1. listopadu 2024 -
inPage AI: Jak na generování obsahu
18. července 2024 -
Členská sekce: 4 důvody proč ji mít na svém webu
12. března 2024
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024