Avatar billede trp79 Nybegynder
16. august 2004 - 18:21 Der er 25 kommentarer og
1 løsning

SQL forespørgsel eller DB

Hejsa
Jeg forsøger at lave en JSP side, hvor man skal logge ind. Indtil videre gør jeg brug af en hsqldb database, hvor jeg gemmer brugernavn, password, rettighed osv. Men jeg kan ikke helt finde ud af om det er smartest at lave SQL forespørgsler for at validerer brugere, eller om det er smartest at lave brugerobjekter og gennemsøge disse?

Hvordan gør man i praksis, og hvordan vil man oftes gøre(gerne eksempel)

mvh
Torben
Avatar billede arne_v Ekspert
16. august 2004 - 18:23 #1
Jeg tror at man normalt vil lave en SQL forespørgsel. Fordi login sker ikke
så tit at det performance mæssigt er værd at cache alle brugere.
Avatar billede arne_v Ekspert
16. august 2004 - 18:25 #2
Det du er ved at lave kalder man application managed security.

Der er et alternativ: container managed security. Der sørger Tomcat (eller
en anden server) for det fornødne check.

Læs mere her http://www.eksperten.dk/artikler/50
Avatar billede trp79 Nybegynder
16. august 2004 - 18:40 #3
Jeg kører det så ikke på en server, men sidder bare og leger lidt med JSP i Oracle JDeveloper - det har en lille server indbygget.

Hvis jeg nu laver det med en SQL forespørgsel vil man så typisk gøre noget i stil med dette:

    public synchronized int validering(String brugernavn, String password)
    {
        try
        {
            String s="select Rettighed "+
                    "from Bruger "+
                    "where Brugernavn ='"+brugernavn+"' AND Password ='"+password+"'";
            ResultSet rs = db.doQuery(s);

            while (rs.next())    //hvis der er mere data i databasen
            {
                rettighed=rs.getString("Rettighed");    //hentes data fra databasen vha. get-metoder
            }
        }
        catch(Exception e){System.out.println("Fejl under validering.... "+e);}

        if(rettighed!=null)
        {
            return rettighed;
        }
        else
        {
            return -1;
        }
    }
eller er det helt hen i vejret?
Avatar billede arne_v Ekspert
16. august 2004 - 18:44 #4
Det virker ret OK. Den slags er set før.

Kommentarer:
  - prepared statements har nogle fordele båd eperformance og sikkerhed
  - du skal huske at resette rettighed til null inden du kalder
  - ofte foretrække rman at bruge roles fremfor et rettigheds tal
Avatar billede trp79 Nybegynder
16. august 2004 - 18:55 #5
okay, som jeg forstår det ud fra din artikkel, er role bare en string.

Når folk så er logget ind vil man så ikke bare lave en session.setAttribute("rettighed", "administrator"); ?

Jeg kan ikke lige se hvorfor jeg skal huske at resette rettighed inden kald, da rettighed vel blive null, hvis den ikke kan finde brugeren i databasen?

Håber det er iorden med lidt tillægsspørgsmål, smider lige lidt flere point i puljen når vi når så langt :)
Avatar billede arne_v Ekspert
16. august 2004 - 18:57 #6
Hvad hvis doQuery laver en exception ?
Avatar billede arne_v Ekspert
16. august 2004 - 18:58 #7
Væ riøvrigt opmærksom på at det somme tider er svært at finde System.out.println
outputtet for JSP side - et logging framework som log4j er ofte bedre.
Avatar billede arne_v Ekspert
16. august 2004 - 19:02 #8
En role er ganshe rigtigt bare en String.

Men det er et gængs concept i security.

Hvis du bruger container managed security kan du både bruge declarative
security (fortælle hvilke roller må tilgå hvilke directories) og
programmatic security (test i din JSP kode med request.isUserInRole("xxxx") ).
Avatar billede arne_v Ekspert
16. august 2004 - 19:04 #9
Bare at gemme i session er en OK løsning som er set masser af gange. Jeg ville
bare lige bringe nogle af de andre muligheder på banen.

Grunden til at roller er så brugte er de understøtter den mulighed at
en bruger kan have flere roller og dermed at man har en matrix security
med brugere på den ene dimension og funktion på den anden dimension.
Simple løsninger bruger normalt hirakisk security sådan at guest
kan næsten ingenting, user kan list, operator kan meget og administrator kan alt.
Avatar billede trp79 Nybegynder
16. august 2004 - 19:18 #10
Okay, ja så skal rettighed da resettes. Vil man oftes bare gøre det sige:

db_handler.resetRettighed();
db_handler.validering(brugernavn, password);

?

Må hellere lige få kigget lidt på log4j så - du har jo skrevet en lille artikkel om det :)
Avatar billede trp79 Nybegynder
16. august 2004 - 19:21 #11
Altså det jeg tænker på er om man på en måde kan smide resette i metoden i stedet for, så man er sikker på, at man ikke glemmer det et andet sted i koden - det er vel det smarteste.
Avatar billede trp79 Nybegynder
16. august 2004 - 19:26 #12
Jeg er jo så nød til at bruge application managed security, så her står jeg vel bare selv for det hele :( Har en skod comp, der knap nok har kræfter til at køre JDev, så det vil nok være lige rigeligt også at smide en rigtig j2ee server på.
Avatar billede arne_v Ekspert
16. august 2004 - 19:27 #13
Jeg ville lave det så primitivt som:

public synchronized int validering(String brugernavn, String password)
    {
        rettighed = null; // <----
        try
        {
            String s="select Rettighed "+
                    "from Bruger "+
                    "where Brugernavn ='"+brugernavn+"' AND Password ='"+password+"'";
            ResultSet rs = db.doQuery(s);

            while (rs.next())    //hvis der er mere data i databasen
            {
                rettighed=rs.getString("Rettighed");    //hentes data fra databasen vha. get-metoder
            }
        }
        catch(Exception e){System.out.println("Fejl under validering.... "+e);}

        if(rettighed!=null)
        {
            return rettighed;
        }
        else
        {
            return -1;
        }
    }
Avatar billede arne_v Ekspert
16. august 2004 - 19:28 #14
PS: Er der iøvrigt ikke et eller andet int versus string i den kode ?
Avatar billede arne_v Ekspert
16. august 2004 - 19:31 #15
Du behøver jo ikke en fuld J2EE app-server.

En Tomcat kører fint små web apps med et totalt memory forbrug på 25-30 MB.
Avatar billede arne_v Ekspert
16. august 2004 - 19:32 #16
Jeg er iøvrigt ret sikker på at JDev environmentet understøtter noget tilsvarende.

Det er nemlig krævet i standarden.

Implementationen er server specifik.
Avatar billede trp79 Nybegynder
16. august 2004 - 19:35 #17
Jo det er der.

Har slet ikke testet det endnu, men bare tastet lidt. Men jeg har tænkt mig at lave det til en public synchronized String validering(..) istedet for, og så skal den selvfølgelig ikke kunne returnerer -1. Desuden prøver jeg lige at lave det til prepared statement, så sikkerheden bliver bedre :)
Avatar billede arne_v Ekspert
16. august 2004 - 19:37 #18
Finessen ved prepared statement er at den beskytter mod SQL injection.
Avatar billede trp79 Nybegynder
16. august 2004 - 19:51 #19
Jep viste ikke der var problemer ellers. Men kapitel 5.4.2 på http://javabog.dk/jsp forklarer det meget godt synes jeg. Ved ikke om der er flere grunde, men det var i hvert fald forklaring nok til at jeg fremover vil bruge prepared statements! :)
Avatar billede arne_v Ekspert
16. august 2004 - 19:54 #20
Hvis du skal udføre den sammem statement mange gange så kan du få bedre performance ved
prepared statement.

Du slipper for de afskyelige dato format problemer.
Avatar billede trp79 Nybegynder
16. august 2004 - 20:26 #21
Nå, så er jeg røget i problemer :(

Jeg har nu lavet metoden:

public synchronized String validering(String brugernavn, String password)
    {
        rettighed = null;
        try
        {
            pstmt = conn.prepareStatement("select role from user_table where brugernavn = ? AND password = ?");
            pstmt.setString(0, brugernavn);
            pstmt.setString(1, password);
            ResultSet rs = pstmt.executeQuery();
            while (rs.next())    //hvis der er mere data i databasen
            {
                rettighed=rs.getString("role");    //hentes data fra databasen vha. get-metoder
                System.out.println("validering: "+rettighed);
            }
        }
        catch(Exception e){System.out.println("Fejl under validering.... "+e);}

        if(rettighed!=null)
        {
            return rettighed;
        }
        else
        {
            return "ingen";
        }
    }

Men jeg får en fejl i den metode, nemlig: "Fejl under validering.... java.lang.ArrayIndexOutOfBoundsException: -1".

når jeg kører denne jsp side(og indtaster det rigtige brugernavn og password):
<%@ page contentType="text/html;charset=windows-1252" import="java.sql.*" import="hsqldb.*" %>
<html>
<head><title>login2</title></head>
<body>
<%!
private String bn, ak;
private static Db_Handler db;
%>
<%
// hvis brugernavn="Jacob" og adgangskode="hemli" logges der ind.
// dette burde selvfølgelig hentes fra en database eller lign.
bn = request.getParameter("brugernavn");
ak = request.getParameter("adgangskode");
try {
  db = new Db_Handler("db_file");
} catch (Exception ex1) {
    ex1.printStackTrace();          // could not start db
}

if (db.validering(bn, ak).equals("Administrator"))
{
// sæt attributten "logget ind" i sessionen
session.setAttribute("logget ind", "ja");
session.setAttribute("rettighed", "administrator");
out.println("Du er logget korrekt ind som Administrator.<br>");
}
else
{
// fjern attributten "logget ind" fra sessionen
session.removeAttribute("logget ind");
out.println("Forkert brugernavn eller adgangskode.<br>");
}
%>
Du kan nu prøve at gå videre til <a href="Login3.jsp">den beskyttede side</a>
eller gå tilbage og <a href="Login.jsp">logge ind</a> igen.
</body>
</html>

Jeg når aldrig ind i whileløkken i valideringsmetoden, så måske det er min prepared statement den er gal med?
Avatar billede arne_v Ekspert
16. august 2004 - 20:30 #22
Ja.

            pstmt.setString(1, brugernavn);
            pstmt.setString(2, password);

SQL indexes starter i 1 ikke 0
Avatar billede trp79 Nybegynder
16. august 2004 - 20:58 #23
Ja det var da noget der hjalp, for nu kom der en ny fejl.

Fejl under validering.... java.sql.SQLException: Table not found: USER_TABLE in statement [select role from user_table where brugernavn = 'Torben' AND password = 'test']

Den siger altså at den ikke kan finde den pågældende tabel, men den findes altså.

Jeg har sat Run Directory til det bibliotek hvor jeg har jsp filerne (D:\jdev903\jdev\mywork\JSP\LoginDB\public_html), så der ligger database filerne som hsqldb laver altså.
Har du nogen ide om hvad der kan være galt?
Avatar billede arne_v Ekspert
16. august 2004 - 21:05 #24
Tabellen må altså mangle.

Jeg har før oplevet problemer med HSQL og forskellige apps.

Kan du ikke bruge MySQL eller MS Access eller noget andet ?
Avatar billede trp79 Nybegynder
16. august 2004 - 21:11 #25
Jo jeg gør det med MySQL istedet så.

Smid du bare et svar Arne, så putter jeg flere point i puljen og siger mange tak for hjælpen :)

Mvh
Torben
Avatar billede arne_v Ekspert
16. august 2004 - 21:22 #26
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester