1. Säkerhet i webb-behållaren
Webb-behållaren har några inbyggda säkerhetsfunktioner som underlättar programmeringen. I webb-behållaren behöver du t.ex. inte kontrollera att en besökare är inloggad, detta gör behållaren åt dig.
- Personligen tycker jag att webb-behållarens inbyggda inloggningsmekanism är ganska skruttig. Ofta är det bättre att skriva inloggningssystemet själv.
2. Ett första exempel
Som vanligt blir det lättare att fatta om man först tittar på ett exempel. I detta exempel ska vi se till att man måste logga in för att kunna se undersidor till mappen secure/. För att nå vårt mål ska vi utföra följande steg:
- En ny applikation programmera skapas genom att vi lägger till en mapp under CATALINA_HOME/webapps/.
- En ny mapp secure/ skapas i applikationen programmera, mappen får sökvägen CATALINA_HOME/webapps/programmera/secure/.
- tomcat-users.xml ska uppdateras. En användare olle läggs till.
- CATALINA_HOME/webapps/programmera/WEB-INF/web.xml skapas.
- Eftersom vi använder FORM som auth-method ska vi göra en loginsida och en felsida i JSP.
- Skapa en index.html-sida i secure/ som du får se om du lyckas logga in. OBS: servern skyddar alltså även .html-sidor.
- Testa att logga in som olle.
3. tomcat-users.xml
Denna fil har sökvägen CATALINA_HOME/conf/tomcat-users.xml. Vi lägger till 2 rader:
<role rolename="programmera" />
<user username="olle" password="x3h" roles="programmera"/>
|
Det viktiga här är att den nya användaren har rollen programmera som vi tidigare använt i web.xml som auth-constraint. Som tur är behöver man inte editera tomcat-users.xml för hand, det blir opraktiskt då man har ett stort antal användare.Tomcat har en admin-applikation som du kan logga in på, och där kan du lägga till och ta bort användare och roller via JSP-sidor, se
Tomcat admin .
4. web.xml
Nu är det dags att uppdatera CATALINA_HOME/webapps/programmera/WEB-INF/web.xml. Nedan visas filens innehåll:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Programmera</display-name>
<description>
This is a place for examples and tests.
</description>
<security-constraint>
<web-resource-collection>
<web-resource-name>Programmera secure area</web-resource-name>
<!-- Define the context-relative URL(s) to be protected -->
<url-pattern>/secure/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<!-- Anyone with one of the listed roles may access this area -->
<role-name>programmera</role-name>
</auth-constraint>
</security-constraint>
<!-- Default login configuration uses form-based authentication -->
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/secure/login.jsp</form-login-page>
<form-error-page>/secure/error.jsp</form-error-page>
</form-login-config>
</login-config>
</web-app>
|
Koden innebär:
- Elementet security-constraint ser till att endast de användare som har loggat in med rollen programmera kan se undersidor till secure/.
- Elementet login-config bestämmer hur man loggar in. Vi har valt FORM och därför måste vi specifiera en loginsida och en felsida.
5. Skriv JSP-sidorna
Först skriver vi en login.jsp-sida:
<HTML>
<BODY>
<H1>Login</H1>
<FORM method="post" action='<%= response.encodeURL("j_security_check") %>' >
Namn: <INPUT type="text" name="j_username">
<BR/>Lösen: <INPUT type="password" name="j_password">
<BR/><INPUT type="submit" value="Logga in">
</FORM>
</BODY>
</HTML>
|
Spara till sökvägen CATALINA_HOME/webapps/programmera/secure/login.jsp. Här finns en del viktiga saker att lägga märke till:
- I formuläret måste method sättas till post.
- I formuläret måste action sättas till j_security_check.
- I formuläret måste det finnas en input med namnet j_username.
- I formuläret måste det finnas en input med namnet j_password.
Först om dessa tre krav är uppfyllda kan man logga in på det skyddade området. Sedan skriver vi en error.jsp-sida:
<HTML>
<BODY>
<H1>Fel lösenord</H1>
<A href='<%= response.encodeURL("login.jsp") %>' >login</A>
</BODY>
</HTML>
|
Spara till sökvägen CATALINA_HOME/webapps/programmera/secure/error.jsp. Och till sist skriver vi en index.html-sida, som man får se om inloggningen lyckas:
<HTML>
<BODY>
<H1>Välkommen till Programmeras säkra område</H1>
</BODY>
</HTML>
|
Spara till sökvägen CATALINA_HOME/webapps/programmera/secure/index.html.
6. Testa applikationen
Först, starta om Tomcat för att få servern att läsa web.xml. Nu ska vi försöka titta på sidan index.html som ligger i det säkra området. Vi öppnar en webbläsare och skriver in localhost:7070/programmera/secure/index.html, men det vi får se är:
Vi har redan skapat en användare olle med lösen x3h i filen tomcat-users.xml. Om vi loggar in med fel lösenord kommer vi till felsidan:
Om vi loggar in med rätt lösenord får vi se index.html:
7. login-config
login-config bestämmer hur själva inloggningen ska gå till. Inloggningsförfarandet man väljer gäller för alla inloggningar inom webbapplikationen. Nedan listas den DTD som beskriver login-config:
<! ELEMENT login-config (auth-method?, realm-name?, form-login-config?)>
<! ELEMENT form-login-config (from-login-page, from-error-page)>
|
Vi tittar på elementens betydelse:
Element | | Obligatorisk | | Beskrivning |
auth-method | | Nej | | Någon av metoderna BASIC, DIGEST, FORM eller CLIENT-CERT. Dessa beskrivs nedan. |
realm-name | | Nej | | Detta element specifierar vilket realm-name HTTP-BASIC ska använda. Beskrivs nedan. |
form-login-config | | Nej | | Detta element krävs om man har valt FORM, här specifierar man sökvägarna till den login och fel-sida man kommer att använda. |
De olika säkerhetsmetoderna beskrivs nedan:
- BASIC: Webbläsaren visar dig ett fönster där du ska skriva namn och lösenord. Detta är den enklaste behörighetskontrollen, men inte den säkraste eftersom namn och lösenord kodas med base64, vilket lätt kan avkodas av vem som helst och därför osäkert. Protokollet HTTP används och kan alltså avlyssnas.
- DIGEST: Som BASIC men istället för base64 så krypteras namn och lösenord innan de skickas till servern. Detta ökar säkerheten markant, men tyvärr kan få webbläsare kryptera.
- FORM: Som BASIC men med egen inloggningssida och felsida.
- CLIENT-CERT: Här används HTTPS (HTTP över SSL). SSL använder RSA-kryptering med publik nyckel. Detta är det säkraste sättet att kommunicera på som finns, man kan matematiskt bevisa att RSA-kryptering inte går att knäcka med dagens datorer. RSA kräver att användaren har ett publik-nyckel-certifikat.
Nedan visas hur en BASIC-inloggning ser ut:
Som vi ser nedan kan metoderna BASIC och FORM också använda HTTPS.
8. security-constraint
security-constraint används för att koppla en viss roll till en del av en webbapplikation. I detta element kan man även specifiera att SSL ska användas för säkerhetsmetoderna BASIC och FORM. Nedan listas den DTD som besriver security-constraint:
<! ELEMENT security-constraint (display-name?, web-resource-collection+,
auth-constraint?, user-data-constraint?)>
<! ELEMENT web-resource-collection (web-resource-name, description?,
url-pattern*, http-method*)>
<! ELEMENT auth-constraint (description?, role-name*)>
<! ELEMENT user-data-constraint (description?, transport-guarantee)>
|
Vi tittar på betydelsen av de olika elementen i security-constraint:
Element | | Obligatorisk | | Beskrivning |
display-name | | Nej | | Säkerhetskravets namn. |
web-resource-collection | | Ja | | Innehåller de resurser som ska skyddas. Resurserna kan vara en eller flera mappar under applikationens root. |
auth-constraint | | Nej | | Beskriver vilka roller som har rätt att komma åt resurserna. * betyder alla roller. Om ingen roll specifieras kan ingen användare se resurserna. Man kan också bestämma vilka HTTP-metoder som ska skyddas, men default är att alla HTTP-metoder skyddas, dvs GET,POST,PUT,DELETE. |
user-data-constraint | | Nej | | Detta element har ett underelement som heter transport-guarantee. Om transport-guarantee sätts till CONFIDENTIAL eller INTEGRAL kommer data att skickas över SSL (HTTPS) om man använder BASIC eller FORM som säkerhetsmetod. CONFIDENTIAL används för att förhindra spioneri, INTEGRAL används för att se till att innehållet inte kan förändras av en tredje part under överföringen. |
Tyvärr har defaultinstallationen av Tomcat inte SSL, så man måste installera det själv, se
http://java.sun.com/webservices/docs/1.2/tutorial/doc/Security7.html .
- OBS!: Sun anser att man bör tvinga en användare över till SSL så fort denne har uppgett någon hemlig information t.ex. sitt kreditkortsnummer. Efter detta ska man bara svara på HTTPS-förfrågningar från den användaren. Om man låter användaren gå tillbaka till HTTP kan någon illvillig hacker komma åt den hemliga informationen. Hackern har avlyssnat session-ID innan användaren gick över till HTTPS, och försöker nu göra vanliga HTTP-anrop med falskt session-ID.