La solució de l’exercici la podeu descarregar en aquest
.
Començarem l’activitat creant un nou projecte Maven. Aneu a File / New Project / Maven / Web Application. Canvieu el nom del fitxer index.html pel nom SecureServletLogin.html.
Aquest fitxer tindrà un formulari web on es demanarà l’usuari i la contrasenya a l’usuari. Aquestes credencials s’enviaran al servlet, que comprovarà si l’usuari té el rol d’administrador que es necessita per poder accedir-hi.
El contingut del fitxer anterior podria ser semblant a aquest (vegeu la figura):
<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <h1>Accedir a un servlet amb seguretat.
</h1> <form method="POST" action="SecureServlet"> <input type="text" name="username"/> <input type="password" name="password"/> <input type="submit" value="Anar"/>
Veiem que les credencials són enviades al servlet anomenat SecureServlet, i llavors continuarem amb la seva creació (File / New File / Web / Servlet). No cal afegir la seva configuració en el fitxer web.xml. Una vegada creat, necessitem recuperar aquests valors. Utilitzarem l’objecte request
per fer-ho.
String myUsername
= request.
getParameter("username"); String myPassword
= request.
getParameter("password");
Una vegada tenim l’usuari i la contrasenya, com comprovem que són vàlids?
Recordeu que les credencials dels usuaris s’emmagatzemen en un realm (àmbit o domini) de fitxer i que aquest l’administra el servidor Glassfish (vegeu la figura). Hem de preguntar-li al servidor si aquestes credencials són correctes. El mateix objecte request
ens permet fer aquesta acció.
request.login(myUsername, myPassword);
En el cas que l’usuari i la contrasenya no siguin vàlids, el mètode login
llençarà una excepció i es podrà informar l’usuari que les seves credencials són incorrectes (vegeu la figura). En cas contrari, continuarà l’execució del servlet normalment.
De moment, el servlet permet accedir a qualsevol usuari amb unes credencials vàlides. Amb la funció isUserInRole
, explicada en la unitat “Manteniment d’estat, autenticació i autorització amb servlets i EJB”, es pot esbrinar si l’usuari té el rol d’administrador. Es deixa a l’alumne la implementació d’aquesta part de l’exercici.
Sembla una mica estrany haver de fer un formulari ad hoc per a cada servlet que es necessiti autenticació. Java ens permet definir una pàgina que contingui el formulari que ha de mostrar cada vegada que es vulgui accedir a un servlet protegit. Per fer-lo, creeu una nova pàgina HTML i anomeneu-la login.html. El contingut de la pàgina ha de ser el següent:
<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <h1>Accedir a un servlet amb seguretat.
</h1> <form method="POST" action="j_security_check"> <input type="text" name="j_username"/> <input type="password" name="j_password"/> <input type="submit" value="Anar"/>
Si us hi fixeu, l’acció del formulari i el nom dels inputs són especials. Amb aquests noms estem indicant al mòdul de seguretat de Java que ha de comprovar l’usuari i la contrasenya amb els quals estiguin configurats al servidor web. Si les credencials són correctes ens deixarà executar el servlet; si no, ens mostrarà una pàgina d’error.
Però quin servlet ens deixarà executar?
En cap moment s’ha informat el mòdul de seguretat del servlet al qual es vol accedir. Això és perquè aquesta pàgina ens la mostrarà el mòdul de seguretat quan vulguem accedir a un servlet que tingui configurada la seguretat. En cap cas s’executarà directament.
Per configurar aquest comportament s’ha de modificar el fitxer web.xml. Si no es té aquest fitxer, s’ha de crear: File / New File / Web / Standard deployment descriptor. I afegim la configuració següent:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.html</form-login-page>
<form-error-page>/error.html</form-error-page>
</form-login-config>
</login-config>
</web-app>
Amb l’etiqueta form-login-page
definim la pàgina que té el formulari “especial” per enviar les credencials de l’usuari al mòdul de seguretat. A més a més, l’etiqueta form-error-page
defineix la pàgina que es mostrarà a l’usuari si les credencials que aporta són incorrectes. Aquesta pàgina té el següent aspecte:
<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <h1>Error accedint a un servlet amb seguretat.
</h1>
Una vegada hem acabat de definir la pàgina d’autenticació i la pàgina d’error, procedirem a la creació d’un servlet que requereix el rol admin per poder-se executar.
Crearem un nou servlet, de la mateixa manera que ho hem fet fins ara, amb el nom SecureServletConstraint.java. Aquest servlet utilitzarà les notacions Java de la classe HttpMethodConstraint
per demanar autenticació d’usuari i un rol específic per accedir als seus mètodes.
Vegeu com es defineix la seguretat amb anotacions:
@WebServlet(name = "SecureServletConstraint", urlPatterns = {"/SecureServletConstraint"})
@ServletSecurity(
httpMethodConstraints = {
@HttpMethodConstraint(value = "GET", rolesAllowed = "admin"),
@HttpMethodConstraint(value = "POST", rolesAllowed = "admin",
transportGuarantee = ServletSecurity.TransportGuarantee.CONFIDENTIAL),
}
)
public class SecureServletConstraint extends HttpServlet {
....
}
L’anotació ServletSecurity
especifica que es vol activar la seguretat per a aquest servlet i accepta l’anotació HttpMethodContraints
com a paràmetre. D’aquesta manera podem definir uns rols específics per a cadascun dels mètodes del servlet. En el nostre cas només volem que sigui l’administrador qui hi tingui accés. Els paràmetres que accepta aquesta anotació són els següents:
value
: nom del mètode HTTP.
rolesAllowed
: conjunt de rols que estan autoritzats per executar aquest mètode (el mètode definit al camp value)
transportGuarantee
: especifica la protecció que s’ha d’aplicar per a la connexió; per exemple, si s’ha d’enviar la informació amb el protocol HTTPS. Els valors són confidential
, integral
i none
.
Una vegada s’ha definit la seguretat, no cal fer res més, només intentar accedir directament al servlet, de manera que, amb el botó dret del ratolí, executarem el fitxer SercureServeltContraint.java. Si heu seguit correctament els passos accedireu al formulari web definit al fitxer login.html (vegeu la figura figura).
En el cas que no tinguem les credencials correctes, el mòdul de seguretat ens mostrarà la pàgina d’error (vegeu la figura).
En canvi, si acreditem que tenim el rol d’administrador, el mòdul de seguretat ens deixarà executar el servlet i ens retornarà la pàgina corresponent a la seva execució (vegeu la figura).