Avatar billede cogitans Nybegynder
14. april 2003 - 14:32 Der er 100 kommentarer og
1 løsning

JAAS (java authentication and authorization service)

Findes der en forklarende og gennemgående tekst online, som man kan få adgang til?
Problemet er, at jeg gerne vil implementere noget login i mit system (lavet i Java), og det skulle JAAS-teknologien (java authentication and authorization service) vist være god til. Men hvor og hvordan finder jeg ud af at bruge teknologien?
Avatar billede arne_v Ekspert
14. april 2003 - 14:38 #1
Avatar billede cogitans Nybegynder
14. april 2003 - 14:44 #3
jo...:-)...men jeg synes nu, at det jeg kan finde der, er ret forvirende. Findes der ikke nogle dokumenter på dansk? Eller kan en person herinde fra forklare mig, hvordan JAAS virker?
Avatar billede arne_v Ekspert
14. april 2003 - 14:46 #4
Jeg tvivler meget på at der er skrevet noget godt på dansk om JAAS.

Og jeg tvivler også på at det er muligt at beskrive JAAS nemt - det er
komplicerede ting vi snakker om.
Avatar billede arne_v Ekspert
14. april 2003 - 14:47 #5
Hvis du beskriver dit setup lidt nærmere, så er det muligt at jeg
kan forklare noget.

Snakker vi web-applikationer på Tomcat eller EJB'er i WebLogic eller ?
Avatar billede cogitans Nybegynder
14. april 2003 - 14:48 #6
Ja, det kan vi skam hurtigt blive enige om :-)
Men der må da fidnes nogle engelske dokumenter så, som beskriver JAAS sådan nogenlunde, så det er til at forstå?

Men nogle eksempler ville garanteret sætte gang i forståelsen også...(?)
Avatar billede cogitans Nybegynder
14. april 2003 - 14:51 #7
Det er en web-aplikation på TomCat. CLienterne til programet har adgang til en menu. Men det er ikke alle menupunkterne, som de skal have adgang til. Det kommer an på deres rettigheder.
Menuen ligger på en index-side på serversiden, som clienten requester. Alt afhænging af hvem der logger in på systemet, har clienten mulighed for bestemte valg i denne menu. Jeg har tænkt mig at bruge denne menu, i stedet for at lave noget smart rettigheds-noget inde i Access. Jeg ved bare ikke, hvordan jeg skal gøre det...?
Avatar billede cogitans Nybegynder
14. april 2003 - 14:53 #8
Indtil videre har jeg fundet ud af, at JAAS også henter indformationer i policy.tool-filen. Den fil er rimelig nem, at sætte op. Men hvordan får JAAS så adgang til filen, hvad giver det JAAS af muligheder og og hvordan kan JAAS håndhæve disse restriktioner?
Avatar billede arne_v Ekspert
14. april 2003 - 14:59 #9
http://www.mooreds.com/jaas.html

ligner lidt er mere praktisk eksempel.

Men ellers bliver jeg nødt til selv at prøve at lave noget til Tomcat.
Avatar billede cogitans Nybegynder
14. april 2003 - 15:10 #10
Er det nemt og hurtigt, hvis du lige lavede et eksempel selv?
Avatar billede arne_v Ekspert
14. april 2003 - 15:12 #11
Det bliver sgu hårdt arbejde.

Men OK - med de point du har udlovet, så har du da også ret
til at forvente lidt mere end et par link.
Avatar billede cogitans Nybegynder
14. april 2003 - 15:13 #12
;-)
det ville jeg i hvert fald sætte pris på. Og hvis pointmængden er et problem, så giver jeg også gerne flere for et ordentlig stykke arbejde....
Avatar billede arne_v Ekspert
14. april 2003 - 15:16 #13
Du må slet ikke give flere point ifølge ekspertens regler. 200 er max..
Avatar billede cogitans Nybegynder
14. april 2003 - 15:18 #14
Så holder jeg mig straks under grænsen!
Avatar billede arne_v Ekspert
14. april 2003 - 15:20 #15
Jeg prøver at kigge på det i løbet af dagen/aftenen.

(JAAS er ikke 5 minutters arbejde)
Avatar billede cogitans Nybegynder
14. april 2003 - 15:26 #16
okay - og tak for det!
Avatar billede arne_v Ekspert
14. april 2003 - 19:15 #17
Jeg har nu authentication delen til at virke.

JaasTest.java
-------------

package jaastest;

import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;

public class JaasTest {
    private static boolean test(String name, String password) {
        try {
            LoginContext lc = new LoginContext("JaasTest", new TestCallbackHandler(name, password));
            lc.login();
            return true;
        } catch (LoginException ex) {
            return false;
        }
    }
    public static void main(String[] args) {
        System.out.println(test("arne", "forkert"));
        System.out.println(test("arne", "rigtig"));
        System.out.println(test("notarne", "rigtig"));
        System.out.println(test(null, null));
    }
}

TestCallbackHandler.java
------------------------

package jaastest;

import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;

public class TestCallbackHandler implements CallbackHandler {
    private String name;
    private String password;
    public TestCallbackHandler(String name, String password) {
        this.name = name;
        this.password = password;
    }
    public void handle(Callback[] callbacks) {
        for(int i = 0; i < callbacks.length; i++) {
            if(callbacks[i] instanceof NameCallback) {
                ((NameCallback)callbacks[i]).setName(name);
            } else if(callbacks[i] instanceof PasswordCallback) {
                ((PasswordCallback)callbacks[i]).setPassword(password.toCharArray());
            }
        }
    }
}

TestAuthenticator.java
----------------------

package jaastest;

import java.io.IOException;
import java.util.Map;

import javax.security.auth.spi.LoginModule;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

public class TestAuthenticator implements LoginModule {
    private String name = null;
    private String password = null;
    public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
        try {
            Callback[] cb = new Callback[2];
            cb[0] = new NameCallback("Name");
            cb[1] = new PasswordCallback("Password", false);
            callbackHandler.handle(cb);
            name = ( (NameCallback) cb[0]).getName();
            password = new String( ( (PasswordCallback) cb[1]).getPassword());
        } catch (UnsupportedCallbackException ex) {
        } catch (IOException ex) {
        }
    }
    public boolean login() throws LoginException {
        if(name != null && name.equals("arne") &&
            password != null && password.equals("rigtig")) {
            return true;
        } else {
            throw new LoginException("Bad name/password");
        }
    }
    public boolean commit() throws LoginException {
        // nothing
        return true;
    }
    public boolean abort() throws LoginException {
        // nothing
        return true;
    }
    public boolean logout() throws LoginException {
        // nothing
        return true;
    }
}

JaasTest.cfg
------------

JaasTest {
  jaastest.TestAuthenticator required debug=false;
};

java kommando
-------------

-Djava.security.auth.login.config="C:/Documents and settings/arne/jbproject/E/src/JaasTest.cfg"
Avatar billede arne_v Ekspert
14. april 2003 - 19:16 #18
Og ja - det er lidt komplekst.
Avatar billede bearhugx Nybegynder
14. april 2003 - 19:34 #19
arne_v >> nu er jeg måske lidt uvidene - men skal der så "meget" til for at teste om en given usr/pwd kombination er rigtig ???

Hvilke fordele kan JAAS yde...

I min naivitet kunne jeg jo finde på at skrive
  public static boolean( String usr, String pwd ) {
  return ( ("arne").equals(usr) && ("rigtig").equals(pwd) );
  }

Såå... For en, som ikke kender JAAS -- hvilke fordele ville jeg have ved at bruge JAAS til styre login - og hvilke situationer ville det _ikke_ være overkill at bruge JAAS

/Søren :-)
Avatar billede arne_v Ekspert
14. april 2003 - 19:48 #20
Godt spørgsmål !

:-)

Det er en API-SPI baseret standard.

JaasTest.java og TestCallbackHandler.java er API baseret.

TestAuthenticator.java er SPI baseret.

Fordi JAAS er en standard vil man kunne rette i JaasTest.cfg til
at bruge en anden authenticator (f.ex. Windows eller Unix system
login eller baseret på en database tabel) uden at skulle rette
og recompile applikationen (JaasTest.java og TestCallbackHandler.java).

Tilsvarende kan en tredie parts komponent købt som binary only
kalde denne her authenticator.

Fordi det er en en standard.

Det må være fordelen ved det.

Og når noget skal kunne bruges som standard så sætter man en
masse kloge mennesker sammen om at finde ud af, hvad der er
brug for. Og normalt så bliver resulatet rimeligt komplekst.
Avatar billede arne_v Ekspert
14. april 2003 - 20:04 #21
Men hvis du spørger mig om jeg ville bruge JAAS til at sikre en
web-applikation, så ville svaret være: nej - ikke medmindre der var
specielle forhold der gjorde det nødvendigt.
Avatar billede arne_v Ekspert
15. april 2003 - 08:53 #22
Så har jeg også authorization med i eksemplet:

JassTest.java
-------------

package jaastest;

import java.security.AccessControlException;

import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.security.auth.Subject;

public class JaasTest {
    private static boolean test(String name, String password) {
        try {
            LoginContext lc = new LoginContext("JaasTest", new TestCallbackHandler(name, password));
            lc.login();
            lc.logout();
            return true;
        } catch (LoginException ex) {
            return false;
        }
    }
    private static void test2(String name, String password) {
        try {
            LoginContext lc = new LoginContext("JaasTest", new TestCallbackHandler(name, password));
            lc.login();
            Subject me = lc.getSubject();
            Subject.doAsPrivileged(me, new Test(), null);
            System.out.println("access for " + name);
            lc.logout();
            return;
        } catch (AccessControlException ex) {
            System.out.println("no access for " + name);
        } catch (LoginException ex) {
            ex.printStackTrace();
        }
    }
    public static void main(String[] args) {
        System.out.println(test("arne", "forkert"));
        System.out.println(test("arne", "rigtig"));
        System.out.println(test("notarne", "rigtig"));
        System.out.println(test(null, null));
        test2("arne", "rigtig");
        test2("system", "rigtig");
    }
}

TestCallbackHandler.java
------------------------

package jaastest;

import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;

public class TestCallbackHandler implements CallbackHandler {
    private String name;
    private String password;
    public TestCallbackHandler(String name, String password) {
        this.name = name;
        this.password = password;
    }
    public void handle(Callback[] callbacks) {
        for(int i = 0; i < callbacks.length; i++) {
            if(callbacks[i] instanceof NameCallback) {
                ((NameCallback)callbacks[i]).setName(name);
            } else if(callbacks[i] instanceof PasswordCallback) {
                ((PasswordCallback)callbacks[i]).setPassword(password.toCharArray());
            }
        }
    }
}

TestAuthenticator.java
----------------------

package jaastest;

import java.io.IOException;
import java.util.Map;

import javax.security.auth.spi.LoginModule;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

public class TestAuthenticator implements LoginModule {
    private String name = null;
    private String password = null;
    private Subject subject;
    public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
        try {
            Callback[] cb = new Callback[2];
            cb[0] = new NameCallback("Name");
            cb[1] = new PasswordCallback("Password", false);
            callbackHandler.handle(cb);
            name = ( (NameCallback) cb[0]).getName();
            password = new String( ( (PasswordCallback) cb[1]).getPassword());
            this.subject = subject;
        } catch (UnsupportedCallbackException ex) {
        } catch (IOException ex) {
        }
    }
    public boolean login() throws LoginException {
        if(name != null && name.equals("arne") &&
          password != null && password.equals("rigtig")) {
            return true;
        } else if(name != null && name.equals("system") &&
                  password != null && password.equals("rigtig")) {
            return true;
        } else {
            throw new LoginException("Bad name/password");
        }
    }
    public boolean commit() throws LoginException {
        subject.getPrincipals().add(new TestPrincipal(name));
        return true;
    }
    public boolean abort() throws LoginException {
        // nothing
        return true;
    }
    public boolean logout() throws LoginException {
        // nothing
        return true;
    }
}

Test.java
---------

package jaastest;

import java.security.PrivilegedAction;
import java.security.AccessController;

public class Test implements PrivilegedAction {
    public Object run() {
        AccessController.checkPermission(new TestPermission());
        return null;
    }
}
TestPermission.java
-------------------

package jaastest;

import java.security.BasicPermission;

public class TestPermission extends BasicPermission {
    public TestPermission() {
        super("TestPermission");
    }
}
TestPrincipal.java
------------------

package jaastest;

import java.security.Principal;

public class TestPrincipal implements Principal {
    private String name;
    public TestPrincipal(String name) {
        this.name = name;
    }
    public boolean equals(Object another) {
        return name.equals((String)another);
    }
    public String toString() {
        return "*";
    }
    public String getName() {
        return name;
    }
}
JaasTest.cfg
------------

JaasTest {
  jaastest.TestAuthenticator required debug=false;
};
JaasTest.policy
---------------

grant {
  permission javax.security.auth.AuthPermission "createLoginContext.JaasTest";
  permission javax.security.auth.AuthPermission "doAsPrivileged";
  permission javax.security.auth.AuthPermission "modifyPrincipals";
};
grant Principal jaastest.TestPrincipal "system" {
  permission jaastest.TestPermission;
};
grant Principal jaastest.TestPrincipal "arne" {
};
java kommando-linie
-------------------

-Djava.security.auth.login.config=JaasTest.cfg -Djava.security.manager -Djava.security.policy=JaasTest.policy
Avatar billede arne_v Ekspert
15. april 2003 - 08:54 #23
Og bemærk det her er ikke tilnærmelsesvist et realistisk eksempel.

Det er kun på "hello world" niveauet.
Avatar billede arne_v Ekspert
15. april 2003 - 09:01 #24
Har du prøvet at kigge på de to alternativer:

A)  login og security håndteret udelukkende af din kode

B)  standard form based & declarative security håndeteret af
    JSP/servlet container

?
Avatar billede cogitans Nybegynder
15. april 2003 - 11:23 #25
Det ser da godt ud, med al denne gennemgang :-)
Men hvad mener du med dit sidste spørgsmål (09:01:43) ?

Nu skrev du jo, at du ikke ville benytte JAAS til login, hvis du kunne undgå det. Men er en ganske almindelig tabel, som man går ind og checker loginnavn og password i, så tilstrækkelig?

det første eksempel du gav, synes jeg godt, at jeg kan finde rundt i. Men det sidste her giver mig lidt problemer. (?)

Hvad er forskellen på/hvad bruges de til (hvad gør filerne helt præcist):
TestCallbackHandler.java
TestAuthenticator.java
TestPrincipal.java

Og hvad er dette for en fil:
JaasTest.cfg

???
Avatar billede arne_v Ekspert
15. april 2003 - 11:26 #26
Hvis du checker username/password i en tabel, så er det løsning #A
ovenfor.

Det kan godt laves sikkert.

Det allernemmeste er dog nok #B.
Avatar billede arne_v Ekspert
15. april 2003 - 11:26 #27
Mit spørgsmål gik på hvorvidt på hvorvidt du har undersøgt
mulige løsninger der er nemmere end JAAS.
Avatar billede arne_v Ekspert
15. april 2003 - 11:27 #28
JaasTest.cfg er filen hvor du definerer hvilken authenticator der skal bruges.
Avatar billede arne_v Ekspert
15. april 2003 - 11:29 #29
TestAuthenticator.java er kernen i det hele - modulet som
checker username/password og tildeler roller.

TestPrincipal.java er bare en do nothing klasse der
repræsenterer en rolle.

TestCallbackHandler.java er der hvor authenticatoren henter
username/password fra.
Avatar billede cogitans Nybegynder
15. april 2003 - 11:31 #30
Jo, men har du skrevet nogle eksempler på #A og #B herinde?

Det eneste jeg har undersøgt er, at man kunne lave en almindelig databasetabel, hvor der både var loginnavn og passowrd i. Så kunne man fyre nogle SQL's afsted til tabellen. Og hvis de 2 felter i den aktuelle record passede overens med inputtet i SQL'en, så kunne man loges ind - eller var der fejl (ved exception).
Avatar billede cogitans Nybegynder
15. april 2003 - 11:33 #31
Så TestCallbackHandler har ikke noget specielt at gøre med CAllBACK-begrebet? Altså noget med RMI, CORBA eller sådan noget?
Avatar billede arne_v Ekspert
15. april 2003 - 11:37 #32
callback er et generelt begreb når X sender noget over til Y så
Y kan kalde X.

TestCallbackHandler handle bliver kaldt med med et antal
callbacks fra TestAuthenticator.
Avatar billede arne_v Ekspert
15. april 2003 - 11:39 #33
#A er ligeud af landevejen. Du laver en HTML/JSP side med en
form, når brugeren submitter så verificerer du username/password,
lukker ham ind til siderne eller ej og gemmer information i hans
session om username så alle sider kan checke om han er logget ind
og hvem han er.
Avatar billede arne_v Ekspert
15. april 2003 - 11:39 #34
#B består primært i at skrive lidt i sin web.xml så sørger
JSP/servlet containeren for det hele.
Avatar billede cogitans Nybegynder
15. april 2003 - 11:42 #35
okay - begge muligheder lyder jo atraktive. Meeen...det er vel ikke noget, som du eventuel kan komme med et lille eksempel på? Det ville jeg i hvert fald påskønne. Bare et simpelt et - men dog gerne, så flere forskellige JSP-sider bliver kaldt efter hinanden, hvor brugeren stadig er logged in?
Avatar billede arne_v Ekspert
15. april 2003 - 11:44 #36
Du kan læse lidt om mulighederne i #B på:
  http://jakarta.apache.org/tomcat/tomcat-4.1-doc/realm-howto.html
Avatar billede arne_v Ekspert
15. april 2003 - 11:48 #37
Og som der står i bunden så shipper Tomcat med et eksempel i
examples applikationen.
Avatar billede arne_v Ekspert
15. april 2003 - 11:48 #38
Men jeg kan da godt prøve at lave et meget simpelt eksempel på #B.
Avatar billede cogitans Nybegynder
15. april 2003 - 11:56 #39
det ville da være dejligt....men det ville skam også være dejligt med et lille eksempel på #A....?
Avatar billede cogitans Nybegynder
15. april 2003 - 13:35 #40
Hvordan laver jeg "JaasTest.cfg"?
Og hvordan bruger jeg den?
Avatar billede cogitans Nybegynder
15. april 2003 - 13:47 #41
Når jeg prøver, at benytte den JaasTest-fil dér, ved hjælp af denne kommando:
C:\>-Djava.security.auth.login.config="C:/JAAStest/Authentification/JaasTest.cfg"

så skriver den følgende ud:

C:\>-Djava.security.auth.login.config="C:/JAAStest/Authentification/JaasTest.cfg
"
'-Djava.security.auth.login.config' is not recognized as an internal or external
command,
operable program or batch file.

hvad betyder dette? At jeg ikke har den rigtige version af JDK installeret? Eller at jeg ikke har tilmeldt den rigtige fil i noget lign. classpath-agtigt noget?
Avatar billede cogitans Nybegynder
15. april 2003 - 13:48 #42
(jeg har lavet "JaasTest.cfg" i notepad...)
Avatar billede cogitans Nybegynder
15. april 2003 - 13:52 #43
når jeg kører testfilen, så skriver den:

java.lang.SecurityException: Unable to locate a login configuration
        at com.sun.security.auth.login.ConfigFile.<init>(ConfigFile.java:97)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
        at java.lang.Class.newInstance0(Class.java:306)
        at java.lang.Class.newInstance(Class.java:259)
        at javax.security.auth.login.Configuration$3.run(Configuration.java:221)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.login.Configuration.getConfiguration(Configuration.java:215)
        at javax.security.auth.login.LoginContext$1.run(LoginContext.java:170)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.login.LoginContext.init(LoginContext.java:167)
        at javax.security.auth.login.LoginContext.<init>(LoginContext.java:404)
        at Authentification.JaasTest.test(JaasTest.java:9)
        at Authentification.JaasTest.main(JaasTest.java:17)
Caused by: java.io.IOException: Unable to locate a login configuration
        at com.sun.security.auth.login.ConfigFile.init(ConfigFile.java:206)
        at com.sun.security.auth.login.ConfigFile.<init>(ConfigFile.java:95)
        ... 15 more
Exception in thread "main" 

???
Avatar billede arne_v Ekspert
15. april 2003 - 13:54 #44
Der der -D 'er er til jav kommandoen !

Altså:

java -Djava.security.auth.login.config="C:/JAAStest/Authentification/JaasTest.cfg  jaastest.JaasTest
Avatar billede arne_v Ekspert
15. april 2003 - 13:55 #45
java kommandoen
Avatar billede arne_v Ekspert
15. april 2003 - 13:55 #46
Der komme rnoget med #B i aften (måske også #A).
Avatar billede arne_v Ekspert
15. april 2003 - 13:56 #47
Og notepad er helt fin til at lave både .cfg og .policy.
Avatar billede cogitans Nybegynder
15. april 2003 - 13:57 #48
Ja, det er rigtigt - selvfølgelig er det med Java i begyndelsen...
Men når jeg skriver det, så skriver den:

C:\>java -Djava.security.auth.login.config="C:/JAAStest/Authentification/JaasTes
t.cfg"
Usage: java [-options] class [args...]
          (to execute a class)
  or  java -jar [-options] jarfile [args...]
          (to execute a jar file)

where options include:
    -client      to select the "client" VM
    -server      to select the "server" VM
    -hotspot      is a synonym for the "client" VM  [deprecated]
                  The default VM is client.

    -cp -classpath <directories and zip/jar files separated by ;>
                  set search path for application classes and resources
    -D<name>=<value>
                  set a system property
    -verbose[:class|gc|jni]
                  enable verbose output
    -version      print product version and exit
    -showversion  print product version and continue
    -? -help      print this help message
    -X            print help on non-standard options
    -ea[:<packagename>...|:<classname>]
    -enableassertions[:<packagename>...|:<classname>]
                  enable assertions
    -da[:<packagename>...|:<classname>]
    -disableassertions[:<packagename>...|:<classname>]
                  disable assertions
    -esa | -enablesystemassertions
                  enable system assertions
    -dsa | -disablesystemassertions
                  disable system assertions
Avatar billede cogitans Nybegynder
15. april 2003 - 14:00 #49
I dit indlæg fra 13:54:49 ... skal man så skrive "jaastest.JaasTest" efter den første linie? Altså linien med "java -Djava.security.auth.login.config="C:/JAAStest/Authentification/JaasTest.cfg"...?
Avatar billede cogitans Nybegynder
15. april 2003 - 14:03 #50
Jeg er dig meget taknemmelig, hvis du kan udstyre mig med nogle eksempler i aften.

Hvad står "cfg" egentlig for?

Og kan det ikke skyldes, at min version af JDK ikke understøtter JAAS, når jeg får de fejlmeddelelser, som jeg gør?
Avatar billede arne_v Ekspert
15. april 2003 - 14:12 #51
Ja - det er:

java -D... -D... -D... mainklasse
Avatar billede arne_v Ekspert
15. april 2003 - 14:13 #52
cfg er bare en forkortelse for config (jeg er så gammel at jeg
foretrækker 3 bogstavs fil typer).
Avatar billede arne_v Ekspert
15. april 2003 - 14:13 #53
Enhver J2SE 1.4 (altså Java SDK 1.4.x) skulle have JAAS.
Avatar billede cogitans Nybegynder
15. april 2003 - 14:14 #54
Ja, jeg havde det nok på fornemmelsen, at det var "config", det stod for.

Hvad mener du med: "java -D...-D...-D....mainklasse"?
Avatar billede cogitans Nybegynder
15. april 2003 - 14:16 #55
findes der ikke en kommando til dos-promten, som fortæller hvilken JDK-version man har installeret?
Avatar billede bearhugx Nybegynder
15. april 2003 - 14:17 #56
java -version
Avatar billede cogitans Nybegynder
15. april 2003 - 14:17 #57
nå, jeg bruger vist JDK 1.4.1 - det skriver "Sun ONE Studio"...
Avatar billede cogitans Nybegynder
15. april 2003 - 14:18 #58
:-) ja, dos-promten skriver det også nu...
Avatar billede bearhugx Nybegynder
15. april 2003 - 14:18 #59
min skriver

C:\WINDOWS>java -version
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)
Avatar billede arne_v Ekspert
15. april 2003 - 14:30 #60
1.4.1_01 er helt fin.
Avatar billede arne_v Ekspert
15. april 2003 - 14:31 #61
Jeg mener alt det her på en enkelt linie:

java -Djava.security.auth.login.config=JaasTest.cfg -Djava.security.manager -Djava.security.policy=JaasTest.policy jaastest.JaasTest
Avatar billede cogitans Nybegynder
15. april 2003 - 14:37 #62
Nu skriver den:

C:\>java -Djava.security.auth.login.config=JaasTest.cfg -Djava.security.manager
-Djava.security.policy=JaasTest.policy C:/JAAStest.Authentification.JaasTest
Exception in thread "main" java.lang.NoClassDefFoundError: C:/JAAStest/Authentif
ication/JaasTest

Hvad betyder dette så?
Avatar billede arne_v Ekspert
15. april 2003 - 14:44 #63
Hvis klassen JaasTest ligger i pakken jaastest og
projekt roden er i C:\JAAStest, så skal filen hedde:

C:\JAAStest\jaastest\JaasTest.java

og kommandoen være:

java -Djava.security.auth.login.config=JaasTest.cfg -Djava.security.manager -Djava.security.policy=JaasTest.policy -classpath C:\JAAStest  jaastest.JaasTest
Avatar billede arne_v Ekspert
15. april 2003 - 14:45 #64
pakke angivelse med punktum i angivelse af main class

classpath peger på roden i fil system syntax
Avatar billede cogitans Nybegynder
15. april 2003 - 15:11 #65
Nå, nu fik jeg vist fat i noget med rettigheder:

C:\>java -Djava.security.auth.login.config=JaasTest.cfg -Djava.security.manager
-Djava.security.policy=JaasTest.policy -classpath C:\JAAStest  Authentification.
JaasTest
Exception in thread "main" java.security.AccessControlException: access denied (
javax.security.auth.AuthPermission createLoginContext.JaasTest)
        at java.security.AccessControlContext.checkPermission(AccessControlConte
xt.java:270)
        at java.security.AccessController.checkPermission(AccessController.java:
401)
        at java.lang.SecurityManager.checkPermission(SecurityManager.java:542)
        at javax.security.auth.login.LoginContext.init(LoginContext.java:157)
        at javax.security.auth.login.LoginContext.<init>(LoginContext.java:404)
        at Authentification.JaasTest.test(JaasTest.java:9)
        at Authentification.JaasTest.main(JaasTest.java:17)

C:\>

Det fortæller vel, at jeg ikke har rettigheder til at køre filen?
Avatar billede arne_v Ekspert
15. april 2003 - 15:15 #66
Det lyder som om JaasTest.policy ikke indeholder det den skal.
Avatar billede cogitans Nybegynder
15. april 2003 - 15:19 #67
JaasTest.policy? Nå, den fil, som vi kaldte "JaasTest.cfg"?
Avatar billede arne_v Ekspert
15. april 2003 - 15:21 #68
Nej.

Der er både en .cfg og en .policy !
Avatar billede arne_v Ekspert
15. april 2003 - 15:23 #69
Se min 08:53:24 kommentar nederst.

I .cfg angiver du hvilken authenticator du vil bruge.

I .policy angiver du hvilke permissions de forskellige
principals (roller) skal have.
Avatar billede arne_v Ekspert
15. april 2003 - 15:23 #70
Og jeg håber ikke at jeg er kommet til at give dig det indtryk at JAAS
er simpelt !

:-)
Avatar billede cogitans Nybegynder
15. april 2003 - 15:32 #71
Naj, JAAS er ikke simpelt i begyndelsen...men alt er "simpelt", når man forstår det ;-)

...jeg havde ikke lagt mærke til den policy-fil, i dit eksempel...
Avatar billede cogitans Nybegynder
15. april 2003 - 15:33 #72
...men skal man både have AUTHENTIFICATION-classer OG AUTHORIZATION-classer med, før eksemplet virker?
Avatar billede arne_v Ekspert
15. april 2003 - 15:36 #73
Lidt min fejl.

Først lavede jeg et authentificerings eksempel.

Derefter udbyggede jeg det til et kombineret authentificerings+autorisations
eksempel.

Mest af praktiske årsager: man skal være logget ind som en bruger inden
man kan checke om brugeren har adgang.
Avatar billede cogitans Nybegynder
15. april 2003 - 15:47 #74
...okay...

Men filerne skal altså ligge i samme bibliotek, for at det fungerer?
Avatar billede arne_v Ekspert
15. april 2003 - 15:55 #75
Ja.

Alle .java filerne er i samme pakke og skal derfor kigge i samme dir.

.cfg og .policy kan ligge hvor somhelst da man kan angive
directory i -D.
Avatar billede cogitans Nybegynder
15. april 2003 - 15:57 #76
okay...det checker jeg lige ud så...
Avatar billede cogitans Nybegynder
15. april 2003 - 15:58 #77
Der er bare lige noget med nogle navne så...nogle af filerne hedder vist det samme...
Avatar billede arne_v Ekspert
15. april 2003 - 16:05 #78
Mine filer fra idag er et komplet sæt som totalt erstatter mine filer fra
i går.
Avatar billede cogitans Nybegynder
15. april 2003 - 16:15 #79
Så tror jeg da lige, at jeg prøver en test med dine opdaterede filer.
Avatar billede arne_v Ekspert
15. april 2003 - 17:32 #80
OK her kommer noget til form baseret authentication og declarative
security ("den nemme løsning").

Jeg har lavet to tabeller i en MS Access database:

Tomcat_users
------------

username    password

arne            arne
system            system

Tomcat_roles
------------

username    role

arne            user
system            administrator

Så retter jeg i Tomcat conf server.xml og tilføjer følgende:

      <Realm  className="org.apache.catalina.realm.JDBCRealm" debug="99"
            driverName="sun.jdbc.odbc.JdbcOdbcDriver"
          connectionURL="jdbc:odbc:TestMSAccess"
        connectionName="" connectionPassword=""
              userTable="Tomcat_users" userNameCol="username" userCredCol="password"
          userRoleTable="Tomcat_roles" roleNameCol="role" />

Så tilføjer jeg følgende til min web applikation test's web.xml:

  <security-constraint>
      <web-resource-collection>
          <web-resource-name>test</web-resource-name>
          <url-pattern>/*</url-pattern>
      </web-resource-collection>
      <auth-constraint>
          <role-name>administrator</role-name>
      </auth-constraint>
  </security-constraint>
  <login-config>
      <auth-method>FORM</auth-method>
      <form-login-config>
          <form-login-page>/login.jsp</form-login-page>
          <form-error-page>/error.jsp</form-error-page>
      </form-login-config>
  </login-config>

Så har jeg følgende 3 JSP-sider i roden af min web applikation test:

test.jsp
--------

(indhold ligegyldigt for dette formål)

login.jsp
---------

<form action="j_security_check" method="POST">
Username: <input type="text" name="j_username"><br>
Password: <input type="text" name="j_password"><br>
<input type="submit" value="Login">
</form>

error.jsp
---------

Login failed !
Avatar billede arne_v Ekspert
15. april 2003 - 17:34 #81
Og det var det !

http://localhost:8080/test/test.jsp får en login-side til
at komme frem.

x x giver "Login failed !"

system system giver mig korrekt test.jsp

arne arne giver mig "Access to the requested resource has been denied"

[fordi det var kun administrator gruppen som kun system er medlem af
der har adgang til siden]
Avatar billede arne_v Ekspert
15. april 2003 - 17:37 #82
Det er selvfølgelig stadigvæk kun demo kode.

Men du må indrømem at det er noget nemmere end JAAS !

:-)
Avatar billede arne_v Ekspert
15. april 2003 - 21:28 #83
Et eksempel på hvordan man gør det hele selv:

secure.jsp
----------

<%@page import="java.util.*"%>
<%
if((session == null) || (session.getAttribute("username") == null)) {
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    if((username!=null)&&(password!=null)) {
        if((username.equals("arne")&&password.equals("arne"))||(username.equals("system")&&password.equals("system"))) {
            session.setAttribute("username", username);
            %>
            Press reload.
            <%
        } else {
            %>
            Invalid username/password.
            <%
            return;
        }
    } else {
      %>
      <form action="secure.jsp" method="GET">
      Username: <input type="text" name="username"><br>
      Password: <input type="text" name="password"><br>
      <input type="submit" value="Login">
      </form>
      <%
      return;
    }
} else {
    if(session.getAttribute("username").equals("system")) {
        %>
        <%=(new Date())%>
        <%
        return;
    } else {
        %>
        No access.
        <%
        return;
    }
}
%>
Avatar billede arne_v Ekspert
15. april 2003 - 21:29 #84
Det er naturligvsi ikke kønt JSP, men det illustrerer teknikken.

(og de hardcoded username/password kan naturligvis nemt erstattes
med et database opslag via JDBC)
Avatar billede cogitans Nybegynder
16. april 2003 - 11:00 #85
jo, men dette er så ikke JAAS (?).
JAAS er vel også nemt, da men "bare" skal override nogle interfaces. Der findes jo metoder til det hele. Det kan være lidt mere besværligt, at finde rundt i...men det er jo det, som jeg søger hjælp til her ;-)
Avatar billede cogitans Nybegynder
16. april 2003 - 11:11 #86
Okay - jeg vil lige teste noget af dit JAAS af...
Når jeg kører dette her:

TestPrincipal
-------------
package jaastest;

import java.security.Principal;

public class TestPrincipal implements Principal {
    private String name;
    public TestPrincipal(String name) {
        this.name = name;
    }
    public boolean equals(Object another) {
        return name.equals((String)another);
    }
    public String toString() {
        return "*";
    }
    public String getName() {
        return name;
    }
}

TestPermission
--------------
package jaastest;

import java.security.BasicPermission;

public class TestPermission extends BasicPermission {
    public TestPermission() {
        super("TestPermission");
    }
}
TestCallbackHandler
-------------------
package jaastest;

import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;

public class TestCallbackHandler implements CallbackHandler {
    private String name;
    private String password;
    public TestCallbackHandler(String name, String password) {
        this.name = name;
        this.password = password;
    }
    public void handle(Callback[] callbacks) {
        for(int i = 0; i < callbacks.length; i++) {
            if(callbacks[i] instanceof NameCallback) {
                ((NameCallback)callbacks[i]).setName(name);
            } else if(callbacks[i] instanceof PasswordCallback) {
                ((PasswordCallback)callbacks[i]).setPassword(password.toCharArray());
            }
        }
    }
}
TestAuthenticator
-----------------
package jaastest;

import java.io.IOException;
import java.util.Map;

import javax.security.auth.spi.LoginModule;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

public class TestAuthenticator implements LoginModule {
    private String name = null;
    private String password = null;
    private Subject subject;
    public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
        try {
            Callback[] cb = new Callback[2];
            cb[0] = new NameCallback("Name");
            cb[1] = new PasswordCallback("Password", false);
            callbackHandler.handle(cb);
            name = ( (NameCallback) cb[0]).getName();
            password = new String( ( (PasswordCallback) cb[1]).getPassword());
            this.subject = subject;
        } catch (UnsupportedCallbackException ex) {
        } catch (IOException ex) {
        }
    }
    public boolean login() throws LoginException {
        if(name != null && name.equals("arne") &&
          password != null && password.equals("rigtig")) {
            return true;
        } else if(name != null && name.equals("system") &&
                  password != null && password.equals("rigtig")) {
            return true;
        } else {
            throw new LoginException("Bad name/password");
        }
    }
    public boolean commit() throws LoginException {
        subject.getPrincipals().add(new TestPrincipal(name));
        return true;
    }
    public boolean abort() throws LoginException {
        // nothing
        return true;
    }
    public boolean logout() throws LoginException {
        // nothing
        return true;
    }
}
Test
----
package jaastest;

import java.security.PrivilegedAction;
import java.security.AccessController;

public class Test implements PrivilegedAction {
    public Object run() {
        AccessController.checkPermission(new TestPermission());
        return null;
    }
}
JaasTest
--------
package jaastest;

import java.security.AccessControlException;

import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.security.auth.Subject;

public class JaasTest {
    private static boolean test(String name, String password) {
        try {
            LoginContext lc = new LoginContext("JaasTest", new TestCallbackHandler(name, password));
            lc.login();
            lc.logout();
            return true;
        } catch (LoginException ex) {
            return false;
        }
    }
    private static void test2(String name, String password) {
        try {
            LoginContext lc = new LoginContext("JaasTest", new TestCallbackHandler(name, password));
            lc.login();
            Subject me = lc.getSubject();
            Subject.doAsPrivileged(me, new Test(), null);
            System.out.println("access for " + name);
            lc.logout();
            return;
        } catch (AccessControlException ex) {
            System.out.println("no access for " + name);
        } catch (LoginException ex) {
            ex.printStackTrace();
        }
    }
    public static void main(String[] args) {
        System.out.println(test("arne", "forkert"));
        System.out.println(test("arne", "rigtig"));
        System.out.println(test("notarne", "rigtig"));
        System.out.println(test(null, null));
        test2("arne", "rigtig");
        test2("system", "rigtig");
    }
}

så skriver den:
java.lang.SecurityException: Unable to locate a login configuration
        at com.sun.security.auth.login.ConfigFile.<init>(ConfigFile.java:97)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
        at java.lang.Class.newInstance0(Class.java:306)
        at java.lang.Class.newInstance(Class.java:259)
        at javax.security.auth.login.Configuration$3.run(Configuration.java:221)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.login.Configuration.getConfiguration(Configuration.java:215)
        at javax.security.auth.login.LoginContext$1.run(LoginContext.java:170)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.login.LoginContext.init(LoginContext.java:167)
        at javax.security.auth.login.LoginContext.<init>(LoginContext.java:404)
        at jaastest.JaasTest.test(JaasTest.java:12)
        at jaastest.JaasTest.main(JaasTest.java:36)
Caused by: java.io.IOException: Unable to locate a login configuration
        at com.sun.security.auth.login.ConfigFile.init(ConfigFile.java:206)
        at com.sun.security.auth.login.ConfigFile.<init>(ConfigFile.java:95)
        ... 15 more
Exception in thread "main"

Hvad betyder det???
Avatar billede arne_v Ekspert
16. april 2003 - 11:15 #87
Det lyder som omd den ikke kan finde JaasTest.cfg !

Har du den rigtige -D på ?

(hvis ikke filen ligger i det directory, hvor du kører skal du have
fuld sti på filen)
Avatar billede cogitans Nybegynder
16. april 2003 - 11:37 #88
Hmm - jeg kan altså ikke få dit eksempel fra 15/04-2003 17:34:40 til at fungere. Den siger hele tiden, at login.jsp not available.
?
Avatar billede cogitans Nybegynder
16. april 2003 - 11:38 #89
er det muligt, at du vil maile mig dine filer (jsp, xml, osv), så jeg ved, at det rigtige er tastet ind i filerne?
Avatar billede cogitans Nybegynder
16. april 2003 - 11:44 #90
jeg er nemlig ved at være rimelig desperat nu...så nogle eksempler i form af filer ville jeg påskønne lige nu :-) ?
Avatar billede arne_v Ekspert
16. april 2003 - 12:08 #91
Det kan jeg da godt.

Men jeg skal have en email adresse.
Avatar billede cogitans Nybegynder
16. april 2003 - 12:55 #92
heh - ja, måske skulle jeg prøve at køre filerne ude fra promten af. Jeg har kørt det fra Forte indtil videre.

Min e-mail er:
dm01f-kka@dm.horshs.dk
Avatar billede arne_v Ekspert
16. april 2003 - 12:58 #93
Øh.

Det eksempel er beregnet til at køre i Tomcat.

Forte indeholder vistnok en Tomcat, men formentlig i special
opsætning.
Avatar billede arne_v Ekspert
16. april 2003 - 13:02 #94
Directory struktur:

Directory of C:\Jakarta-tomcat-4.1.18\webapps\test

15/04/2003  21:25      <DIR>          .
15/04/2003  21:25      <DIR>          ..
15/04/2003  17:13                  14 error.jsp
15/04/2003  17:15                  198 login.jsp
23/03/2003  17:07                1,038 test.jsp
15/04/2003  20:54      <DIR>          WEB-INF

Directory of C:\Jakarta-tomcat-4.1.18\webapps\test\WEB-INF

15/04/2003  20:54      <DIR>          .
15/04/2003  20:54      <DIR>          ..
15/04/2003  20:54                1,274 web.xml
Avatar billede arne_v Ekspert
16. april 2003 - 13:02 #95
Og husk tilretningen af server.xml som skal pege på din database.
Avatar billede cogitans Nybegynder
16. april 2003 - 13:06 #96
tak for filen...vil du også sende de andre filer (specielt web.xml), så jeg er sikker på, at versionen kan fungere?
Avatar billede cogitans Nybegynder
16. april 2003 - 13:16 #97
HEY - nu fik jeg eksemplet fra 17:32:28 til at fungere. Ja, det vil sige den kan da finde filen. Men uanset om jeg skriver "Arne - Arne" eller "System - System", så viser den login-failedsiden?
Avatar billede arne_v Ekspert
16. april 2003 - 13:36 #98
Har du lavet tabellen og rettet server.xml til ?
Avatar billede cogitans Nybegynder
16. april 2003 - 13:38 #99
tabellen har jeg lavet. Den ligger i c:\
server.xml er rettet til som du ser i den tilsendte fil...
Avatar billede warpgiga Nybegynder
24. maj 2003 - 16:31 #100
Hej Arne, tak for en god gennemgang af java authentication ;)
Jeg bruger selv min egen lille login bean der gemmer info i session, og laver et tjek øverst i hver jsp fil.
Jeg bruger dog også lidt constraints så man kan udelukke folk fra at se non-jsp filer såsom billeder og statiske xml filer..
Pt. er min metode at jeg bruger en dispatcher på "/" niveau som fanger alle request til applikationen.. dette er nok ikke det smarteste hvis man vil bruge en web server til at serve non-jsp filer...  jeg vil som std. bruge et apache Httpserver + Tomcat..

p.s. det er vigtigt for min applikation at den dynamisk kan oprette brugere, og ændre deres constraints til et vidst niveau.
Avatar billede arne_v Ekspert
24. maj 2003 - 18:40 #101
De filer som du ikke vil have folk skal kunne requeste kan du jo bare
smide under WEB-INF.

Jeg er iøvrigt ikke helt klar over om det var et spørgsmål !?
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