Activitats

Autenticació bàsica amb 'servlets'

L’objectiu d’aquesta activitat és aprendre els mecanismes que ens proporciona Java per autenticar els usuaris. Aquests usuaris podran accedir als servlets si tenen un rol determinat.

Es vol crear un login d’usuari que permeti o no executar un servlet. Feu aquesta activitat amb un formulari d’autenticació creat per vosaltres en comptes d’utilitzar el diàleg per defecte. Els usuaris i els seus rols han d’estar creats en el servidor Glassfish. Només s’ha de deixar executar el servlet als usuaris amb el rol admin.

Es recomana haver fet la unitat “Manteniment d’estat, autenticació i autorització amb servlets i EJB” abans de fer aquesta activitat.

La solució de l’exercici la podeu descarregar en aquest

enllaç ( 7.6 KB )
.

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):

  1. <!DOCTYPE html>
  2. <head>
  3. <title>Seguretat en els Servlets</title>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5. </head>
  6. <body>
  7. <h1>Accedir a un servlet amb seguretat.</h1>
  8. <form method="POST" action="SecureServlet">
  9. <input type="text" name="username"/>
  10. <input type="password" name="password"/>
  11. <input type="submit" value="Anar"/>
  12. </form>
  13. </body>
  14. </html>

Figura ‘Login’ del ‘servlet’ SecureLogin

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.

  1. String myUsername = request.getParameter("username");
  2. 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ó.

  1. request.login(myUsername, myPassword);

Figura Configuració dels usuaris al servidor Glassfish

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.

Figura Error en les credencials de l’usuari

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:

  1. <!DOCTYPE html>
  2. <head>
  3. <title>Seguretat en els Servlets</title>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5. </head>
  6. <body>
  7. <h1>Accedir a un servlet amb seguretat.</h1>
  8. <form method="POST" action="j_security_check">
  9. <input type="text" name="j_username"/>
  10. <input type="password" name="j_password"/>
  11. <input type="submit" value="Anar"/>
  12. </form>
  13. </body>
  14. </html>

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:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <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">
  3. <session-config>
  4. <session-timeout>
  5. 30
  6. </session-timeout>
  7. </session-config>
  8. <login-config>
  9. <auth-method>FORM</auth-method>
  10. <form-login-config>
  11. <form-login-page>/login.html</form-login-page>
  12. <form-error-page>/error.html</form-error-page>
  13. </form-login-config>
  14. </login-config>
  15. </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:

  1. <!DOCTYPE html>
  2. <head>
  3. <title>Seguretat en els Servlets</title>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5. </head>
  6. <body>
  7. <h1>Error accedint a un servlet amb seguretat.</h1>
  8. </body>
  9. </html>

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:

  1. @WebServlet(name = "SecureServletConstraint", urlPatterns = {"/SecureServletConstraint"})
  2. @ServletSecurity(
  3. httpMethodConstraints = {
  4. @HttpMethodConstraint(value = "GET", rolesAllowed = "admin"),
  5. @HttpMethodConstraint(value = "POST", rolesAllowed = "admin",
  6. transportGuarantee = ServletSecurity.TransportGuarantee.CONFIDENTIAL),
  7. }
  8. )
  9. public class SecureServletConstraint extends HttpServlet {
  10. ....
  11. }

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).

Figura ‘Login’ automàtic del ‘servlet’ amb seguretat definida mitjançant anotacions

En el cas que no tinguem les credencials correctes, el mòdul de seguretat ens mostrarà la pàgina d’error (vegeu la figura).

Figura Pàgina d’error. Credencials no vàlides

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).

Figura Execució del ‘servlet’ amb el rol d’administrador