Newsgroup: it.comp.java
Titolo: Servlet, queste sconosciute

Ciao a tutti, da circa due settimane mi sono avvicinato al mondo delle 
servlet...
Quello che volevo fare era un form per autenticarsi: i dati venivano mandati 
a una servlet che andava a leggere in un file di properties: se login e 
password coincidevano con quelli immessi nella form avevi la possibilità di 
modificare le credenziali mediante un'altra form generata da una seconda 
servlet. Quindi entrava in gioco una terza servlet che scriveva le modifiche
Il codice e' il seguente(lo spezzetto):
--------------------------------------------FORM 
HTML:index.html-------------------------------
<html>
<body>
<form method="POST" action="triack.ciao">
Login:<input type="text" name="Login"><br>
Password:<input type="password" name="Password"><br>
<input type="submit" value="ok">
</form>
</body>
</html>
-------------------------------------------------------Servlet che verifica 
le credenziali----------------------------
 package triack;
import java.io.*;
import java.util.*;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class ApplicativoWeb extends HttpServlet
{
 public void doPost(HttpServletRequest request,HttpServletResponse response) 
throws IOException, ServletException
 {
//Apro il file di properties in cui sono state immagazzinate nome utente e 
password(la prima volta settate a mano)
FileInputStream myfile2=new 
FileInputStream(getServletContext().getRealPath("/")+"/fileproperties.txt");
Properties prova2=new Properties();
prova2.load(myfile2);
//Controllo se nome utente e password immessi coincidono con quelli del file 
di properties
if(prova2.getProperty("Login").equals(request.getParameter("Login"))&&(prova2.getProperty("Password").equals(request.getParameter("Password"))))
  {
   myfile2.close();
   HttpSession session=request.getSession();
   session.setAttribute("autenticato","si");
    ServletContext context=this.getServletContext();
   //Forwardo alla seconda servlet
   RequestDispatcher 
dispatcher=context.getNamedDispatcher("ModificaCredenziali");
   dispatcher.include(request,response);
   dispatcher.forward(request,response);
  }
  else
  {
   myfile2.close();
   PrintWriter pw=response.getWriter();
   response.setContentType("text/html");
   pw.write("<html>");
   pw.write("<body>");
   pw.write("<h1>Credenziali non corrette! </h1>");
   pw.write("</body>");
   pw.write("</html>");
  }
 }
}
------------------------------------------------Servlet che permette di 
modificare le credenziali------------------------------------------------
package triack;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ModificaCredenziali extends HttpServlet
{
 public void doPost(HttpServletRequest request,HttpServletResponse response) 
throws IOException
 {
  PrintWriter pw=response.getWriter();
  //Controllo che l'utente sia passato dalla prima servlet mediante la 
verifica dell'attributo di sessione
  if(request.getSession().getAttribute("autenticato")==null)
  {
   pw.write("<html>");
   pw.write("<body>");
   pw.write("<h1>Non ti sei autenticato!</h1>");
   pw.write("</body>");
   pw.write("</html>");
  }
  else
  {
   request.getSession().setAttribute("autenticato","si");
   pw.write("<html>");
   pw.write("<body>");
   pw.write("<h1>Ti sei autenticato!</h1>");
   pw.write("<h3>ModificaCredenziali</h3>");
   pw.write("<form method='POST' action='scrivi.ciao'>");
   pw.write("Login:<input type='text' name='Login' />");
   pw.write("<br>Password:<input type='password' name='Password' />");
   pw.write("<br><input type='submit'/>"); //mediante la pressione di questo 
tasto passo il tutto alla III servlet
   pw.write("</form>");
   pw.write("</body>");
   pw.write("</html>");
  }
 }
}
-------------------------------------------Servlet che scrive nomeutente e 
password nel file di properties----------------------------------------
package triack;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ScriviCredenziali extends HttpServlet
{
 public void doPost(HttpServletRequest request,HttpServletResponse response) 
throws IOException
 {
//Controllo dell'attributo di sessione
if(request.getSession().getAttribute("autenticato")==null)
  {
   PrintWriter pw=response.getWriter();
   pw.write("<html>");
   pw.write("<body>");
   pw.write("<h1>Credenziali non modificate!</h1>");
   pw.write("</body>");
   pw.write("</html>");
  }
  else
  {
   PrintWriter pw=response.getWriter();
   pw.write("<html>");
   pw.write("<body>");
   pw.write("<h1>Credenziali Modificate!</h1>");
   pw.write("</body>");
   pw.write("</html>");
   //Scrivo nome utente e password nel file di properties
   FileOutputStream myfile2=new 
FileOutputStream(getServletContext().getRealPath("/")+"/fileproperties.txt");
   Properties prova2=new Properties();
   prova2.setProperty("Login",request.getParameter("Login"));
   prova2.setProperty("Password",request.getParameter("Password"));
   prova2.store(myfile2,"");
   request.getSession().setAttribute("autenticato",null);
  }
}
}
----------------------------------------------------------------------------------
Il file web.xml e' corretto e quindi non lo allego(se avete avuto la 
pazienza di leggere fin qui senza saltare grazie (^___^) )
La struttura della servlet e' corretta(WEB-INF, ecc..)
Il codice funziona(in parte): l'utente si logga tramite la form html, che 
manda il tutto alla prima servlet che verifica che nome utente e password 
siano uguali a quelli del file di properties:in caso affermativo forwarda la 
richiesta alla seconda servlet che controlla che l'attributo di sessione 
autenticato sia settato:in caso affermativo crea un'altra form in cui noi 
possiamo cambiare nome utente e password: il tutto quindi passa alla terza 
servlet che controlla che l'attributo di sessione autenticato sia settato e 
quindi in caso affermativo scrive le modifiche nel file.
Per testare la robustezza dell' "applicativo" ho provato a scrivermi una 
form html simile a quella presente nella seconda servlet che puntasse 
direttamente alla terza servlet(senza quindi passare per la prima e seconda 
servlet):quello che mi aspettavo era che l'applicativo rifiutasse la 
richiesta di aggiornamento.
Il codice non funziona nel seguente caso: io utente mi loggo correttamente e 
la prima servlet mi forwarda alla seconda.(dove c'è il form per inserire i 
dati) Quindi apro con lo stesso browser(internet explorer 6)(in un'altra 
finestra) la form html che punta direttamente alla terza servlet: inserisco 
dei dati e le modifiche vengono accettate quando non dovrebbero.
E' come se l'attributo session venisse rilevato anche in questo secondo 
caso.
Qualcuno mi può aiutare?
Grazie in anticipo per le risposte e scusatemi per tutto quel codice ma non 
riesco proprio a venirne a capo
Stefano
Grazie 

 Qualcuno mi può aiutare?
Non mi è chiaro cosa consideri problematico; non sei veramente esposto a
problemi di sicurezza (più del normale) perché, appunto, devi lanciare
un'altra finestra dello stesso browser.
In questo caso specifico, il problema potrebbe essere che l'utente apre
un altra finestra, la lascia sullo sfondo e se la dimentica, cambia la
password dalla prima finestra e dopo un po' vede la seconda finestra,
dice fra sè e sè "ma non l'avevo cambiata?" e la ricambia con un
risultato imprevedibile (nel senso che poi magari non ricorda cosa aveva
messo).
Questo problema puoi evitarlo chiedendo anche di confermare la password
corrente.
In generale, se vuoi evitare che la stessa operazione venga eseguita da
due finestre, devi aggiungere un parametro univoco che impedisca una
doppia esecuzione.
Ciao.


Eppure io avevo provato a fare questa servlet di esempio:
-------------------------------------------------------------------------------------
package src;
import java.io.*;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class CiaoMondo extends HttpServlet
{
 public void doGet(HttpServletRequest request,HttpServletResponse response) 
throws IOException
 {
  // Dichiaro una session e una servlet context
  HttpSession session=request.getSession();
  ServletContext context = this.getServletContext(); //Statistiche sull'uso 
dell'applicazione
  Integer i=(Integer) session.getAttribute("colore");
  if(i==null) i=0;
  Integer i2=(Integer) context.getAttribute("colore");
  if(i2==null) i2=0;
  //Setto gli attributi della session e della context
  session.setAttribute("colore",i+1);
  context.setAttribute("colore",++i2);
  PrintWriter ps=response.getWriter(); //Setto come rispondere al browser
  ps.write("<html>");
  ps.write("<body>");
  ps.write("<h1>Ciao Mondo!</h1>");
  ps.write("<h3>Hai invocato la pagine per 
"+session.getAttribute("colore")+" volte!</h3>");
  ps.write("<h3> Browser che hai aperto= "+context.getAttribute("colore"));
  ps.write("</body>");
  ps.write("</html>");
 }
}
--------------------------------------------------------------------------------
In cui tutto funziona come dovrebbe: se apro due finestre di IE6 l'attributo 
session vale 1 per ciascuna delle due
finestre mentre l'attributo context vale 2 come dovrebbe
C'è qualcosa che ho tralasciato? 


Puoi usare anche IE ma senza fare CTRL+N