Java Authentication and Authorization Service

Java Authentication and Authorization Service (JAAS) představuje javovskou verzi standardního Pluggable Authentication Module (PAM) frameworku.[1]

Je využíván pro dvě činnosti:

  • Autentizace (Ověření pravosti) – ověření identity uživatele. Provádí se nejčastěji přijetím uživatelova jména a hesla. Ověření je bezpečné a důvěryhodné.
  • Autorizace – určení, zda ověřený uživatel má práva k přístupu k určité části systému

Základní popis

JAAS je standardní součástí Javy od JavaTM 2 SDK, Standard Edition (J2SDK), v 1.4. Ve verzi 1.3 byla součástí volitelnou. Byl přidán z důvodu nízké flexibility u původního systému zabezpečení, zejména pro provozování serverových aplikací. Jako součást Java 2 security se zabývá poskytováním povolení a bezpečnostní kontrolou těchto povolení. Toto vše je prováděno mimo kód aplikace, takže není nutné původní aplikaci upravovat. Samotná aplikace si není vědoma, že je na ní prováděna autentizace a autorizace.

Obsah frameworku[1]

Základní třídy

  • Subject – zastupuje zdroj požadavku (uživatele), může jím být jak osoba, tak služba. Po autentizaci je k němu připojeno až několik objektů Principal a Credential.
  • Principal – zastupuje identitu uživatele. Vždy se jedná jen o jednu identitu, ale Subject jich může obsahovat několik. Může jí být například zaměstnanecké číslo, rodné číslo, jméno… Dále zastupuje role uživatele v systému. Subject opět může mít více rolí.
  • Credential – Může jím být cokoliv, co dokáže prokázat identitu uživatele (jméno a heslo, otisk prstu…) Není součástí knihovny JAAS, neboť jakákoliv třída může být Credential. Měl by implementovat metody Refreshable Archivováno 12. 10. 2008 na Wayback Machine. a Destroyable Archivováno 7. 5. 2009 na Wayback Machine.. Credential může být veřejný nebo soukromý. Pod veřejným si lze představit jméno a pod soukromým heslo.

Třídy a Rozhraní autentifikace

  • LoginContext – obsahuje základní metody pro autentizaci Subjectu
  • LoginModule – rozhraní pro přidání vlastní autentizační technologie
  • CallbackHandler – rozhraní pro komunikaci uživatele s LoginModule a naopak
  • Callback – rozhraní pro přenos různých autentizačních informací.

Třídy autorizace

  • Policy – abstraktní třída reprezentující tzv. bezpečnostní politiku. Stanovuje povolení přidělená kódu spuštěného z určitého zdroje (URL) nebo určitou identitou (osobou) Principal.
  • AuthPermission – třída pro základní povolení v JAAS. Využívá předvolené názvy pro určitá povolení.
  • PrivateCredentialPermission – třída pro ochranu soukromých Credential.

Průběh autentifikace a autorizace[1]

Autentifikace

  • Aplikace vytvoří instanci LoginContext
  • LoginContext pomocí dat z konfigurace načte všechny LoginModule přidružené k aplikaci
  • Aplikace zavolá login metodu na LoginContext
  • Login metoda zavolá všechny LoginModule. Ty se pokusí o autentifikaci subjektu. Pokud se to podaří, jsou objektu Subject přiřazeny relevantní Principal a Credential. Tímto je subjekt autentizovaný.
  • LoginContext předá status o autentizaci aplikaci
  • Při úspěšné autentizaci dostane aplikace objekt Subject od LoginContext

Autorizace

  • Uživatel musí být autentizován
  • Subject, který je výsledkem autentizace, musí mít k sobě přiřazený kontext řízení přístupu (access control context)
  • Principal položky musí být konfigurovány v Policy

Příklady

Jednoduchý příklad, kde se zjišťuje povolení k zápisu do souboru cheese.txt[2]

Aplikace:

package chp02;

 import java.io.File;
 import java.io.IOException;

 public class Chp02aMain {

   public static void main(String[] args) throws IOException {
     File file = new File("build/conf/cheese.txt");
     try {
       file.canWrite();
       System.out.println("Můžeme zapsat do cheese.txt");
     } catch (SecurityException e) {
       System.out.println("Nemůžeme zapsat do cheese.txt");
     }
 }
}
  • Aplikace si vytvoří objekt souboru cheese.txt
  • Zjistí, zda má povolení pro zápis do tohoto souboru
  • Podle nastavených práv pak zjistí, zda je schopen zápisu do souboru (pak je vyhozeno hlášení „Můžeme zapsat do cheese.txt“), nebo je vyhozena bezpečnostní výjimka a zahlášeno „Nemůžeme zapsat do cheese.txt“

Konfigurační soubor Policy:

grant
{
 permission java.io.FilePermission "build/conf/cheese.txt", "write";
};
  • Garantujeme povolení typu FilePermission na soubor "build/conf/cheese.txt" a to na zápis do tohoto souboru

Příklad logování do aplikace[3]

Aplikace:

CallbackHandler handler = new RanchCallbackHandler(userName, password); 

try {
   LoginContext loginContext = new LoginContext("RanchLogin", handler);
   // Přihlášení
   loginContext.login();
} catch (LoginException e) {
   // Chyba při přihlášení, nepodařilo se přihlásit
   e.printStackTrace();
}
  • Aplikace vytvoří instanci LoginContext
  • Provede se pokus o nalogování

Login konfigurační soubor:

RanchLogin {
   com.javaranch.auth.RanchLoginModule required;
};
  • Tento soubor určuje, který z LoginModule bude použit pro logování a jak (viz Login konfigurační soubor podrobněji).
  • Zde se nastavuje, že pro jméno "RanchLogin" je použito RanchLoginModule a je nutné, aby modul uživatele autentizoval
  • Nastavuje se pro JVM přes parametr: -Djava.security.auth.login.config="JAAS_CONFIG_FILENAME"
'''LoginModul "RanchLoginModule":'''
 public boolean login() throws LoginException {
    boolean returnValue = true;
 	if (callbackHandler == null){
        throw new LoginException("No callback handler supplied.");
    }
 
    Callback[] callbacks = new Callback[2];
    callbacks[0] = new NameCallback("Username");
    callbacks[1] = new PasswordCallback("Password", false);
 
    try {
        callbackHandler.handle(callbacks);
        String userName = ((NameCallback) callbacks[0]).getName();
        char [] passwordCharArray = ((PasswordCallback)  
          callbacks[1]).getPassword();
        String password = new String(passwordCharArray);
 //-->autentifikuje se pomocí jména a hesla, které musí být stejné         
        returnValue = userName.equals(password);
    } catch (IOException ioe)  {
        ioe.printStackTrace();
        throw new LoginException("IOException occurred:
          "+ioex.getMessage());
    } catch (UnsupportedCallbackException ucbe) {
        ucbe.printStackTrace();
        throw new LoginException("UnsupportedCallbackException encountered:
          "+ucbe.getMessage());
    }
 
    System.out.println("Přihlášen");
    return returnValue;
 }
  • Pomocí Callbacků a CalbackHandleru se získá jméno a heslo
  • Porovná se, zda se jméno shoduje s heslem
  • Vrátí se návratová hodnota true nebo false podle porovnání jména a hesla

Konfigurační soubor Policy:

grant {
   permission java.util.PropertyPermission "user", "read";
   permission java.util.PropertyPermission "pass", "read";
   permission java.util.PropertyPermission
    "java.security.auth.login.config", "read";
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission javax.security.auth.AuthPermission
    "createLoginContext.RanchLogin";
};
  • Nastavení práv pro možnost vytváření objektu LoginContext a přístup k atributům
  • Je nutné pouze při aktivním security manageru

Výsledky spuštění aplikace:

Stejné jméno a heslo

java -Duser=rahul
    -Dpass=rahul
    -Djava.security.auth.login.config=jaas.config
    -jar jaas-example.jar
  • Přihlášení proběhlo v pořádku

Různé jméno a heslo

java -Duser=rahul
    -Dpass=notrahul
    -Djava.security.auth.login.config=jaas.config
    -jar jaas-example.jar
  • Jméno a heslo nejsou stejné, proto se nepřihlásí

Stejné jméno a heslo + spuštěn security manager

java -Duser=rahul
    -Dpass=rahul
    -Djava.security.auth.login.config=jaas.config
    -Djava.security.manager
    -jar jaas-example.jar
  • Nejsou nastavena práva. Není tedy schopen provést operace pro přihlášení a nepřihlásí se

Stejné jméno a heslo + spuštěn security manager + nstavena práva

java -Duser=rahul
    -Dpass=rahul
    -Djava.security.auth.login.config=jaas.config
    -Djava.security.manager
    -Djava.security.policy=policy.config
    -jar jaas-example.jar
  • Přihlášení proběhlo v pořádku

Login konfigurační soubor podrobněji[3]

RanchLogin {
   com.javaranch.auth.FirstLoginModule
       requisite debug=true ;

   com.javaranch.auth.SecondLoginModule
       required debug=false email=admin@mydomain.com ;
};

Jak je vidět z příkladu pod jedním jménem (RanchLogin) může být více než jeden LoginModule. Obsahují také své vlastní parametry, které jsou pak v jednotlivých modulech přístupné (debug pro FirstLoginModule, debug a email pro SecondLoginModule). Poslední položkou je konfigurace jednotlivých modulů. Ty mohou být podle klíčových slov:

  • Required – Modul musí autentizovat uživatele. Pokud se tak nestane, stejně je předáno řízení dalšímu LoginModul
  • Requisite – Pokud se nepovede přihlášení, vrátí se okamžitě zpět do aplikace a další LoginModuly se nespouští
  • Sufficient – Pokud se tomuto modulu podaří přihlásit, autentizace se bere jako splněná a vrací se zpět do aplikace. Pokud ne, pokračuje se dalšími LoginModuly
  • Optional – Pokračuje vždy k dalšímu LoginModulu, nezávisle na výsledku autentizace

Reference

  1. a b c JAAS Reference Guide [online]. Dostupné online. (anglicky) 
  2. COTÉ, Michael. JAAS in action ["PDF online"]. 2005-10-26. Dostupné online. (anglicky) 
  3. a b BHATTACHARJEE, Rahul. Authentication using JAAS [online]. Příprava vydání Ulf Dittmer. 4.2008 [cit. 2010-06-16]. Dostupné v archivu pořízeném dne 2012-02-13. (anglicky)