[RISOLTO] Login personalizzato in JSP

Area di discussione libera.

Moderatore: Staff

Regole del forum
1) Rispettare le idee altrui.
2) Evitare le offese dirette.
3) Leggere attentamente le risposte ricevute
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
hashbang
Packager
Packager
Messaggi: 2021
Iscritto il: ven 4 giu 2010, 10:27
Nome Cognome: Luca De Pandis
Distribuzione: macOS/OpenBSD
Località: Lecce/Bergamo

[RISOLTO] Login personalizzato in JSP

Messaggio da hashbang »

Salve ragazzi,

ho un problema. Sto preparando un progetto per l'esame di progettazione software e, dopo aver realizzato la parte in Java, sto sviluppando l'interfaccia in JSP.
Quando inserisco i dati nel form di login, esso invia i valori in login.jsp, che, a sua volta, reindirizza, a seconda delle credenziali immesse, o a docente_loggato.jsp oppure a beneficiario_loggato.jsp.
Il che non sarebbe un problema, se non fosse per il fatto che, quando login.jsp manda un response.sendRedirect(./beneficiario_loggato.jsp) (o response.sendRedirect(./docente_loggato.jsp)), i valori di username e password vengono cancellati.
Di conseguenza, Tomcat rimanda un errore 500, in quanto i valori di ritorno dei metodi p.getNome() e p.getCognome() (dove p è l'oggetto che si riferisce alla classe Persona) sono nulli, poichè, avendo perso username e password, non riesce ad eseguire una query corretta al database per ottenere i valori richiesti dai metodi richiamati.

C'è un modo per ridirezionare il login alle due pagine su citate, senza perdere i valori passati a username e password?

Grazie
Ultima modifica di hashbang il gio 12 apr 2012, 20:29, modificato 1 volta in totale.

ilmich
Master
Master
Messaggi: 1645
Iscritto il: lun 16 lug 2007, 17:39
Slackware: 15.0 64bit
Kernel: 5.15.27
Desktop: kde
Località: Roma

Re: Login personalizzato in JSP

Messaggio da ilmich »

E' normale che sia cosi visto che il protocollo http è stateless per definizione.. quindi non vi è un meccanismo automatico per mantere informazioni tra una chiamata e l'altra.
Per ovviare a questo, devi sfruttare i meccanismi messi a disposizione dal java per salvarti i dati in una sessione http creata appositamente.

qui puoi trovare un esempio pratico di come settare/recuperare dati dalla sessione in una jsp, anche se il mio consiglio è di fare questa operazione nelle servlet in modo da separare in modo netto la logica di business dalla logica di view.

ciau
#LiveSimple and #ProgramThings
https://github.com/ilmich
http://ilmich6502.it/

hashbang
Packager
Packager
Messaggi: 2021
Iscritto il: ven 4 giu 2010, 10:27
Nome Cognome: Luca De Pandis
Distribuzione: macOS/OpenBSD
Località: Lecce/Bergamo

Re: Login personalizzato in JSP

Messaggio da hashbang »

Perdona la risposta tardiva, ma questo è stato un periodo critico. #-o

Condivido appieno la tua idea di separare nettamente la Business logic dal resto. Difatti il codice che l'utente del link da te postato ha piazzato nella jsp, io l'avevo già inserito all'interno delle classi (che sono a sè stanti dalla parte JSP).

Comunque ho risolto in questo modo:
Essendo che i parametri immessi nel form di login, venivano gestiti tranquillamente in login.jsp, mi è bastato modificare il response.sendRedirect in questo modo:

Codice: Seleziona tutto

response.sendRedirect("./beneficiario_loggato.jsp?user=" +username);
e

Codice: Seleziona tutto

response.sendRedirect("./docente_loggato.jsp?user=" +username);
Dove user è un parametro gestito all'interno delle pagine beneficiario_loggato.jsp e docente_loggato.jsp. Così facendo, mi è bastato richiamare, all'interno di queste pagine, il valore del parametro user, per sfruttare due metodi appositi che hanno il compito di costruire un oggetto con gli attributi presi dal database, basandosi solo sullo username (getBeneficarioByUsername(String username) e getDocenteByUsername(String username)). :)

Ti ringrazio, comunque, per la disponibilità.

ilmich
Master
Master
Messaggi: 1645
Iscritto il: lun 16 lug 2007, 17:39
Slackware: 15.0 64bit
Kernel: 5.15.27
Desktop: kde
Località: Roma

Re: [RISOLTO] Login personalizzato in JSP

Messaggio da ilmich »

premesso che nn so bene cosa tu stia sviluppando e perchè, permettimi di dirti che la tua soluzione è ottima per esercitarti con java.. ma a mio avviso non va assolutamente bene in casi reali per i seguenti motivi

1) esponi l'username dell'utente loggato
2) se non utilizzi il concetto di sessione legata all'utente loggato dovresti reiterare il punto dolente nr1 in tutte le pagine in cui ti serve l'info sull'utente
3) usare parametri passati tramite url per fare query su database sql, se non correttamente validati sono passibili facilmente di sql injection(ma immagino che abbia usato i prepared statement e non semplici sostituzioni di stringhe in una query preformata). quindi questa tecnica è da usare in casi in cui è impossibile fare altrimenti
4) come lo gestisci il il fatto che se scrivo direttamente la url beneficiario_loggato.jsp?user=ciccio senza aver fatto login, ma direttamente nel browser, mi autorizza ad entrare dove non dovrei entrare?
5) etc etc etc

comunque sono contento che hai risolto :)

ciau
#LiveSimple and #ProgramThings
https://github.com/ilmich
http://ilmich6502.it/

hashbang
Packager
Packager
Messaggi: 2021
Iscritto il: ven 4 giu 2010, 10:27
Nome Cognome: Luca De Pandis
Distribuzione: macOS/OpenBSD
Località: Lecce/Bergamo

Re: [RISOLTO] Login personalizzato in JSP

Messaggio da hashbang »

miklos ha scritto:premesso che nn so bene cosa tu stia sviluppando
Diciamo che per questo esame bisogna sviluppare una applicazione in Java, con una interfaccia in JSP che giri su Tomcat, attraverso l'uso di:
Eclipse for Java EE Web Developers IDE
JDK 6 SE
Apache Tomcat
MySQL, che permetta ad un docente di censire risorse e ai beneficiari di prenotare materiali.
e perchè, permettimi di dirti che la tua soluzione è ottima per esercitarti con java..
Considera che nè Java nè SQL nè HTML li abbiamo affrontati nel corso.
Abbiamo parlato solo di UML. Il resto lo ha chiesto il professore. Quindi, l'apprendimento del linguaggio è piuttosto "alla volemose bene" (avessi più tempo mi sarei messo per bene a studiarlo, ma purtroppo il tempo è quello che è. Già è molto che sia riuscito a mettere su qualcosa di funzionante in una settimana.) :(
1) esponi l'username dell'utente loggato
Vero. Ma solo DOPO che uno si è loggato.
Altrimenti, non compare nulla. Nemmeno sulla barra di stato.
Questo di per sè non lo vedo come un problema. Dopotutto, se uno ha fatto il login attraverso il form, lo conoscerà il suo username, no? :P
2) se non utilizzi il concetto di sessione legata all'utente loggato dovresti reiterare il punto dolente nr1 in tutte le pagine in cui ti serve l'info sull'utente
Su questo, non posso darti torto :roll:
Infatti, ad ogni pagina richiamo lo user...altrimenti è finita.
3) usare parametri passati tramite url per fare query su database sql, se non correttamente validati sono passibili facilmente di sql injection(ma immagino che abbia usato i prepared statement e non semplici sostituzioni di stringhe in una query preformata). quindi questa tecnica è da usare in casi in cui è impossibile fare altrimenti
I metodi per la connessione al database non li ho scritti io :)
Ce li ha dati direttamente il professore. Comunque si, usa delle prepared statement.
4) come lo gestisci il il fatto che se scrivo direttamente la url beneficiario_loggato.jsp?user=ciccio senza aver fatto login, ma direttamente nel browser, mi autorizza ad entrare dove non dovrei entrare?
A questo ci avevo già pensato. :)
Inizialmente avevo risolto con un semplice:

Codice: Seleziona tutto

if(session.getAttribute("docente")==null)
      response.sendRedirect("./index.jsp?error=1");
fi
Il problema, però, è che riesco ad accedere comunque ad una home page di un altro account, se ho fatto il login anche con un altro username.
Esempio:
1) faccio il login con l'account "pippo"
2) edito nella barra degli indirizzi il parametro user=pippo in user=paperino

Comunque, sembra che sia risuscito a risolvere:

Codice: Seleziona tutto

String user=request.getParameter("user");
Docente d=DocenteDAO.getInstance().getDocenteByUsername(user);
if((session.getAttribute("docente")!=null) && (user.equals(d.getNome())))
	session.getAttribute("docente");
else
	session.invalidate();
	response.sendRedirect("./index.jsp?error=1"); //Accesso negato alla risorsa
Ho fatto una prova, editando il campo user nella barra degli indirizzi e mi ritorna in index.jsp con errore.



Comunque, se hai qualche altro suggerimento, non farti problemi a scrivere ;)

ilmich
Master
Master
Messaggi: 1645
Iscritto il: lun 16 lug 2007, 17:39
Slackware: 15.0 64bit
Kernel: 5.15.27
Desktop: kde
Località: Roma

Re: [RISOLTO] Login personalizzato in JSP

Messaggio da ilmich »

hashbang ha scritto:Considera che nè Java nè SQL nè HTML li abbiamo affrontati nel corso.
Abbiamo parlato solo di UML. Il resto lo ha chiesto il professore. Quindi, l'apprendimento del linguaggio è piuttosto "alla volemose bene" (avessi più tempo mi sarei messo per bene a studiarlo, ma purtroppo il tempo è quello che è. Già è molto che sia riuscito a mettere su qualcosa di funzionante in una settimana.)
ti capisco... non avessi cestinato e sovrascritto n volte l'hard disk con dentro i miei primi esperimenti con java ti farei vedere che obbrobri scrivevo io anni or sono(e considera che io praticamente sono un autodidatta un po' come te) :)

per quanto riguarda il fatto di mettere lo username nella url ti sei risposto da solo quando hai detto che giocando con quella url riuscivi a 'fregare' il sistema di autenticazione. ma considerando comunque il contesto in cui ti trovi è una cosa su cui potresti anche sorvolare.

detto questo ecco come lo farei io, in modo molto semplice.
chiamando:

a) la servlet che fa il login
b) la pagina dei docenti
c) la pagina dei beneficiari

il flusso sarebbe piu' o meno cosi'

- a riceve dal form nome utente e password, li valida tramite chiamata al database e mette in sessione il nome utente. fatto questo redireziona alle pagine di competenza con i dati che ha recuperato dal database mentre faceva la validazione (quindi senza impostare piu' nulla nella url)
- b controlla che ci sia una sessione attiva(puoi testare anche solo la presenza dell'attributo). recupera l'attributo col nome utente e con quello va a fare la chiamata al database, altrimenti redireziona alla pagina di errore (fossi in te controllerei pure che il database ritorni qualcosa.. cerca sempre di non dare per scontato nulla o ti ritroverai in futuro in situazioni criptiche difficili da gestire ;) )
- c fa la stessa cosa di b

se vuoi fare una cosa piu' sfiziosa e far si che ogni pagina validi pure che tu sia effettivamente un docente piuttosto che un beneficiario puoi settare questa eventuale proprietà nella sessione con un valore a tuo piacimento (tipo d => docente, b => beneficiario) ( ma forse questa cosa l'hai gestita con i pezzi di codice che hai allegato, solo che nn si capisce bene .. dovrei vedere il tutto :( )

ultima cosa riguardo sempre al codice che hai postato. l'uguaglianza

Codice: Seleziona tutto

user.equals(d.getNome())
a prima vista mi sembra sempre vera visto che la variabile user è quella che utilizzi per la query quindi l'oggetto d.getNome() è per forza identico.

tieni conto che sicurezza in piu'... logica in meno.. concettualmente è cosi' che funzionano la stragrande maggioranza dei sistemi di autenticazione web :)

ciau
#LiveSimple and #ProgramThings
https://github.com/ilmich
http://ilmich6502.it/

hashbang
Packager
Packager
Messaggi: 2021
Iscritto il: ven 4 giu 2010, 10:27
Nome Cognome: Luca De Pandis
Distribuzione: macOS/OpenBSD
Località: Lecce/Bergamo

Re: [RISOLTO] Login personalizzato in JSP

Messaggio da hashbang »

miklos ha scritto:ultima cosa riguardo sempre al codice che hai postato. l'uguaglianza

Codice: Seleziona tutto

user.equals(d.getNome())
a prima vista mi sembra sempre vera visto che la variabile user è quella che utilizzi per la query quindi l'oggetto d.getNome() è per forza identico.
È la stessa cosa che ho pensato anche io.
Eppure, grazie a questa uguaglianza, ho risolto il problema della modifica nella barra degli indirizzi, di cui ti parlavo nell'ultimo post. :-k
Dovrò indagare meglio...

ilmich
Master
Master
Messaggi: 1645
Iscritto il: lun 16 lug 2007, 17:39
Slackware: 15.0 64bit
Kernel: 5.15.27
Desktop: kde
Località: Roma

Re: [RISOLTO] Login personalizzato in JSP

Messaggio da ilmich »

il fatto è che è sbagliato usare l'utente nella url.
cerco di spiegarti al meglio come funzionano le sessioni http, cosi' posso poi farti vedere bene dove sbagli.
come dicevo in precedenti post l'http è un protocollo stateless quindi per dare una parvenza di flusso di dati che possono essere usati fra una chiamata e l'altra si sono inventati le sessioni http.
il server web dà ad ogni connessione effettuata dal browser un identificativo univoco che usa al suo interno per memorizzare una mappa chiave/valore (su filesystem tipicamente, ma puo' anche essere memorizzata in un database)
questo identificativo viene scambiato attraverso un cookie (se apri i cookie del tuo browser dovresti trovarne uno chiamato JSESSIONID me pare).

quando ti colleghi la prima volta il server nn riceve alcun cookie e quindi crea una nuova sessione http e nella risposta che invia allega il primo cookie che contiene l'id della sessione appena creata.
la seconda volta che il browser va sul server ha con se un cookie valido da inviare e di conseguenza il server ti 'riconosce' e anzichè creare una nuova sessione riutilizza quella vecchia recuperando i dati che eventualmente sono stati memorizzati
e cosi via fino a quando non decidi a codice di buttare tutto (per esempio quando fai un logout) oppure non passa un tot di tempo di inattività superato il quale tutte le sessioni scadute vengono buttate(tipo quando qui su slacky ti logghi e non fai niente per un po'.. quando refreshi ti richiede il login).

quindi, secondo il meccanismo che ti ho spiegato, l'oggetto "docente" che metti in sessione te lo ritrovi sempre ed è sempre valido quindi il tuo primo tentativo di arginare il bug dell'autorizzazione non va bene per questo.

guardando bene il tuo secondo tentativo, a meno che non abbia scritto una bozza, mi sembra sbagliato nel momento in cui se non usi le parentesti { } nei blocchi if/else viene eseguita solo la prima istruzione quindi per quello che vedo io a prescidere dai risultati delle if fa sempre il redirect alla pagina di errore.
#LiveSimple and #ProgramThings
https://github.com/ilmich
http://ilmich6502.it/

hashbang
Packager
Packager
Messaggi: 2021
Iscritto il: ven 4 giu 2010, 10:27
Nome Cognome: Luca De Pandis
Distribuzione: macOS/OpenBSD
Località: Lecce/Bergamo

Re: [RISOLTO] Login personalizzato in JSP

Messaggio da hashbang »

Miklos, tutto quello che dici è sacrosanto, ma il problema è: come faccio a gestire la sessione, in maniera differente da come ho fatto io, senza una servlet e avendo gestito le classi separatamente rispetto a come riportava l'esempio del link da te postato all'inizio?
Se faccio su Eclipse: New->Servlet ottengo un errore relativo all'import, derivato dal fatto che la mia JDK (in quanto Java SE) non dispone di javax.servlet (disponibile su Java EE).
Il mio progetto, comunque, è così composto:

Codice: Seleziona tutto

src/
|_package.creato.da.me.1/
|  |_Business.java  //i cui metodi non sono altro che richiami ai metodi presenti nelle altre classi.
|_package.creato.da.me.2/
|    |_Docente.java   //eredita da Persona
|    |_Persona.java
|    |_Beneficiario.java  //eredita da Persona
|    |_Richiesta.java
|    |_Materiale.java
|_package.dato.dal.professore/
|  |_DbConnection.java        //contenti i metodi per l'interrogazione/gestione del database
|_package.creato.da.me.3/  /* contiene le classi DAO, che
    |_DocenteDAO.java          * contenenti, i metodi per la gestione dell'applicativo:
    |                                     * aggiunta/rimozione materale/richiesta/account
    |_PersonaDAO.java          * e via discorrendo, con le relative chiamate a
    |                                     * DbConnection.java per ottenere i metodi di interrogazione al DB */
    |_BeneficiarioDAO.java
WebContent/
|_images/
|_styles/
|_*.jsp
Il workaround (perchè così si può definire) adottato, non piace nemmeno a me. Credimi, mi fa schifo solo a pensarlo, ma purtroppo non ho gli strumenti per poter gestire il tutto. Ho parlato con altri miei compagni di corso, che stanno realizzando questo progetto per l'esame, e anche loro hanno adottato il mio stesso metodo, ottenendo gli stessi bug. Il progetto esempio del nostro docente, non è servito a molto, poichè esso fa il login esclusivamente con l'impiegato (ha la sola pagina docente_loggato.jsp).
miklos ha scritto:guardando bene il tuo secondo tentativo, a meno che non abbia scritto una bozza, mi sembra sbagliato nel momento in cui se non usi le parentesti { } nei blocchi if/else viene eseguita solo la prima istruzione quindi per quello che vedo io a prescidere dai risultati delle if fa sempre il redirect alla pagina di errore.
Ho scritto la condizione giusto per mostrarla, non ho fatto il copia-incolla dal sorgente.
Comunque, la condizione è errata a prescindere dalle parentesi. Il redirect infatti viene stabilito da una errata uguaglianza tra user (che contiene lo stesso valore di d.getUsername()) e d.getNome() che non contiene lo username, ma il nome della persona. Perdona, l'errore, ma dopo cinque ore, senza sosta, di lavoro a questo progetto, non avevo la lucidità necessaria a rendermi conto di un errore logico tanto evidente. #-o

ilmich
Master
Master
Messaggi: 1645
Iscritto il: lun 16 lug 2007, 17:39
Slackware: 15.0 64bit
Kernel: 5.15.27
Desktop: kde
Località: Roma

Re: [RISOLTO] Login personalizzato in JSP

Messaggio da ilmich »

hashbang ha scritto: Se faccio su Eclipse: New->Servlet ottengo un errore relativo all'import, derivato dal fatto che la mia JDK (in quanto Java SE) non dispone di javax.servlet (disponibile su Java EE).
pero' hai detto di usare tomcat e li' le classi servlet te le ritrovi nei jar distribuiti, devi solo nel tuo progetto eclipse impostare bene le dipendenze(coi nuovi eclipse è ancora piu' facile e sono sicuro che se spulci un po' su google troverai tutorial molto semplici per questa configurazione)

quando poi esporti il war e fai il deploy su tomcat il tuo progetto funziona senza fare storie perchè girando all'interno di tomcat trova le classi che gli servono.

tieni conto che per quanto riguarda lo standard J2EE quando si tratta di applicazioni web TUTTO è una servlet, persino le jsp non sono altro che servlet generate partendo dal codice html(per dimostrarti questa ultima affermazione fai caso che la prima invocazione ad una jsp è molto piu' lenta delle successive proprio perchè la prima volta tomcat genera e compila codice java partendo dalla tua jsp... poi dopo riusa il compilato)

in sostanza non hai avuto modo di rendertene conto, ma stai già usando delle servlet ;)

EDIT: mi piacerebbe avere un po' di tempo per poterti fornire snippet molto piu' corposi, pero' purtroppo sti giorni riesco giusto a mangiare/dormire/scribacchiare qui su slacky.. il resto solo lavoro pero' vista la tematica del post e il fatto che con queste cose ci combatto da anni, ci tenevo ad aiutarti. chiaramente visto che magari il tuo esame è alle porte e il tempo stringe vai pure avanti cosi' e facci sapere come è andata :)

RI-EDIT: mettiti fra i bookmarks il link che ti ho postato con il codice di esempio. quel sito è ottimo perchè contiene una serie di piccoli esempi per quasi tutti gli ambiti classici di java (J2EE, threads, etc etc etc)
#LiveSimple and #ProgramThings
https://github.com/ilmich
http://ilmich6502.it/

hashbang
Packager
Packager
Messaggi: 2021
Iscritto il: ven 4 giu 2010, 10:27
Nome Cognome: Luca De Pandis
Distribuzione: macOS/OpenBSD
Località: Lecce/Bergamo

Re: [RISOLTO] Login personalizzato in JSP

Messaggio da hashbang »

Salve ragazzi :)

Posto solo adesso, ad un mese dall'appello, perchè purtroppo non ho più tanto tempo a disposizione :(

Avevo avvisato via MP miklos e abbiamo convenuto che sarebbe stato bello avvisarvi.

L'esame è andato bene (25) e grazie ai suggerimenti appresi in questo post, ho citato sia lui che tutta la community di Slacky.eu nella documentazione cartacea data al docente.

Colgo l'occasione per ringraziare non solo miklos, per gli ottimi consigli dati, ma anche tutta la community per la qualità e la competenza che pochi forum italiani possono vantare di avere.

Rispondi