JavaRush /Java Blog /Random-IT /JAAS - Introduzione alla tecnologia (Parte 2)
Viacheslav
Livello 3

JAAS - Introduzione alla tecnologia (Parte 2)

Pubblicato nel gruppo Random-IT
Continuazione della prima parte dell'articolo su JAAS. Scopriamo se è possibile utilizzare solo annotazioni per JAAS e quali problemi incontreremo. Impareremo in questa parte quali strumenti API Servlet ci consentono di rendere il codice più universale. E riassumiamo ciò che leggiamo.
JAAS - Introduzione alla tecnologia (Parte 2) - 1

Continuazione

Nella prima parte della revisione della tecnologia JAAS (vedere " JAAS - Introduzione alla tecnologia (parte 1) ") abbiamo esaminato il caso d'uso principale di JAAS e dell'API Servlet. Abbiamo visto che il servlet container Tomcat gestiva la sicurezza della nostra applicazione web utilizzando l'architettura JAAS. Conoscendo il "metodo di autenticazione" e il "regno di sicurezza", il contenitore Tomcat stesso ci ha fornito l'implementazione necessaria del meccanismo di autenticazione e ci ha fornito CallbackHandler, abbiamo semplicemente utilizzato tutto nel nostro modulo di accesso. L'unica cosa importante da ricordare è che il browser salva i dati di login e password trasmessi tramite l'autenticazione BASIC. Pertanto, per ogni nuova scansione utilizzando Chrome, puoi premere Ctrl+Shift+N per aprire una nuova finestra e lavorare in modalità di navigazione in incognito.
JAAS - Introduzione alla tecnologia (Parte 2) - 2

Annotazioni

La configurazione tramite XML è da tempo fuori moda. Pertanto, è importante dire che a partire dalla versione 3.0 dell'API Servlet, abbiamo l'opportunità di impostare le impostazioni del servlet utilizzando le annotazioni, senza utilizzare il file descrittore di distribuzione web.xml. Vediamo come cambierà la gestione della sicurezza se utilizziamo le annotazioni. Ed è possibile implementare gli approcci sopra descritti utilizzando le annotazioni? La specifica API Servlet e la sua sezione “ Annotazioni e collegabilità ” ci aiuteranno ancora una volta a comprendere le annotazioni . Questa sezione dice che una dichiarazione servlet web.xmlpuò essere sostituita da un'annotazione @WebServlet. Di conseguenza, il nostro servlet sarà simile a questo:
@WebServlet(name="app", urlPatterns = "/secret")
public class App extends HttpServlet {
Successivamente, diamo un'occhiata al capitolo " 13.3 Sicurezza programmatica ". Dice che possiamo anche dichiarare un vincolo di sicurezza tramite annotazioni:
@WebServlet(name="app", urlPatterns = "/secret")
@ServletSecurity(httpMethodConstraints = {
        @HttpMethodConstraint(value = "GET", rolesAllowed = "admin")
})
public class App extends HttpServlet {
Ora web.xmlnel nostro è rimasto solo un blocco: login-config. Il problema è che si dà il caso che non ci sia modo di sostituirlo facilmente e semplicemente. A causa della stretta connessione tra le impostazioni di sicurezza delle applicazioni web e le impostazioni di sicurezza del server web, non esiste un modo semplice e universale per farlo, nemmeno a livello di programmazione. Questo è uno dei problemi con l'autenticazione tramite JAAS e API Servlet. Parlando del blocco login-config, vale la pena capire che si tratta di una descrizione dichiarativa dei meccanismi di autenticazione, ad es. meccanismi di autenticazione. Non esiste ancora un modo semplice e universale per sostituirlo, perché... l'elaborazione web.xmlavviene in profondità all'interno dei contenitori servlet. Ad esempio, in Tomcat puoi guardare l'origine ContextConfig.java . Pertanto anche per il servlet container Tomcat esistono diverse opzioni e tutte diverse. Ad esempio, se utilizziamo il contenitore servlet Embedded Tomcat (ovvero creiamo un server Web dal codice), puoi leggere informazioni su tali opzioni qui: " Tomcat incorporato con autenticazione di base tramite codice ". Inoltre, un esempio generale di creazione di Embedde Tomcat può essere visto nella guida della piattaforma Heroku PaaS: " Crea un'applicazione Web Java utilizzando Embedded Tomcat ". Se Tomcat non viene utilizzato in modalità incorporata, per Tomcat è possibile utilizzare un approccio comunemente utilizzato: ascoltatori di eventi. In Tomcat questo è " Il componente LifeCycle Listener ". Allo stesso tempo, è importante capire che i contenitori servlet (nel nostro caso Tomcat) potrebbero avere i propri caricatori di classi e non sarà possibile semplicemente prendere e utilizzare le proprie classi. Per Tomcat è necessario comprendere il " Class Loader COME FARE ". In un altro contenitore servlet chiamato Undertow, ciò può essere ottenuto utilizzando " Estensioni Servlet ". Come puoi vedere, alcuni hanno fornito meccanismi più flessibili, mentre altri no. Come puoi vedere, non esiste un’unica opzione. Sono tutti molto diversi. È possibile in qualche modo fare qualcosa di universale solo con l'API Servlet e JAAS? Su Internet è possibile trovare una proposta per utilizzare il filtro servlet per eseguire l'autenticazione senza blocco login-config. Consideriamo finalmente questa opzione. Ciò ci consentirà di ripetere il funzionamento di JAAS.
JAAS - Introduzione alla tecnologia (Parte 2) - 3

Filtro di autenticazione

Quindi, il nostro obiettivo è eliminare web.xmlcompletamente il file. Se ce ne liberiamo, sfortunatamente non saremo più in grado di utilizzare i vincoli di sicurezza, perché la loro elaborazione può avvenire molto prima rispetto all'applicazione dei filtri servlet. Questa è la tariffa che devi pagare per la “versatilità” dell’utilizzo dei filtri. Quelli. dovremo rimuovere l'annotation @ServletSecurity, e tutti i controlli che abbiamo precedentemente descritto nel vincolo di sicurezza dovranno essere eseguiti a livello di codice. Come puoi vedere, questa opzione ci impone anche molte spiacevoli restrizioni. Prima di tutto rimuoviamo l'annotazione @ServletSecuritydalla risorsa e il blocco login-configdal file web.xml. Ora dovremo noi stessi implementare l'autenticazione di base. Ora aggiungiamo il nostro filtro:
@WebFilter("/*")
public class JaasFilter implements javax.servlet.Filter {
Fin qui sembra semplice. Scriviamo un metodo di inizializzazione:
@Override
public void init(FilterConfig filterConfig) throws ServletException {
	String jaas_conf = filterConfig.getServletContext().getRealPath("/WEB-INF/jaas.config");
	System.getProperties().setProperty("java.security.auth.login.config",jaas_conf);
}
Come puoi vedere, ora siamo costretti a utilizzare gli strumenti JAAS di base per cercare il file di configurazione jaas. Ciò presenta un grosso svantaggio: se sono presenti più applicazioni, un'applicazione può interrompere l'autenticazione di un'altra. Il modo in cui è possibile impostare in generale un file Jaas Config è descritto in dettaglio nella documentazione JAAS: " Appendice A: Impostazioni JAAS nel file delle proprietà di sicurezza java.security ". Successivamente, descriveremo il metodo di filtraggio stesso. Iniziamo ricevendo una richiesta HTTP:
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
	HttpServletRequest req = (HttpServletRequest) request;
	// Если в реквесте уже есть Principal - ничего не делаем
	if (req.getUserPrincipal() != null ) {
		chain.doFilter(request, response);
	}
Tutto è semplice qui. Se Principal è disponibile, l'autenticazione ha esito positivo. Successivamente, è necessario descrivere le azioni del filtro quando l'utente non ha superato l'autenticazione, ad es. non è stato ancora riconosciuto. In precedenza abbiamo descritto il metodo di autenticazione di base, BASIC. Perché Dato che ora stiamo scrivendo noi stessi il filtro, dovremo capire come funziona effettivamente l'autenticazione BASIC. È possibile utilizzare " Documenti Web MDN: autorizzazione HTTP ". E anche " Come funziona l'autenticazione HTTP? " Dalla descrizione di come funziona l'autenticazione di base, è chiaro che se il server desidera eseguire l'autenticazione BASIC e l'utente non ha fornito dati, il server invia un'intestazione speciale "WWW-Authenticate" e il codice di errore 401. Creiamo un metodo interno per questo:
private void requestNewAuthInResponse(ServletResponse response) throws IOException {
	HttpServletResponse resp = (HttpServletResponse) response;
	String value = "Basic realm=\"JaasLogin\"";
	resp.setHeader("WWW-Authenticate", value);
	resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
Ora utilizziamo questo metodo e aggiungiamo doFilteril seguente blocco di codice al metodo:
// Получаем security Header. А если его нет - запрашиваем
String secHeader = req.getHeader("authorization");
if (secHeader == null) {
	requestNewAuthInResponse(response);
}
Ora aggiungiamo un ramo per if, che verrà eseguito quando l'intestazione sarà già stata trasmessa:
// Проверяем аутентификацию
else {
	String authorization = secHeader.replace("Basic ", "");
	Base64.Decoder decoder = java.util.Base64.getDecoder();
	authorization = new String(decoder.decode(authorization));
	String[] loginData = authorization.split(":");
	try {
		if (loginData.length == 2) {
			req.login(loginData[0], loginData[1]);
			chain.doFilter(request, response);
		} else {
			requestNewAuthInResponse(response);
		}
	} catch (ServletException e) {
		requestNewAuthInResponse(response);
	}
}
Puoi aggiungere l'autorizzazione a questo codice, ad esempio: req.isUserInRole("admin") Quindi abbiamo effettuato l'autenticazione con te utilizzando un filtro. Da un lato, c’è molto codice ed elaborazione manuale. D'altra parte, c'è versatilità e indipendenza dal server.
JAAS - Introduzione alla tecnologia (Parte 2) - 4

Conclusione

Ora siamo giunti alla fine di questa recensione. Spero che ora diventi un po' più chiaro cosa è JAAS, cosa è un Soggetto e cosa sono i Principali. Le parole Security Realm e Login Config non solleveranno più domande. Inoltre, ora sappiamo come utilizzare insieme JAAS e l'API Servlet. Inoltre, abbiamo appreso dei colli di bottiglia in cui le annotazioni nell'API Servlet non ci salveranno. Naturalmente, questo non è tutto. Ad esempio, l'autenticazione in Java potrebbe non essere solo BASIC. Puoi vedere gli altri tipi nella specifica API Servlet nella sezione " 13.6 Autenticazione ". È difficile trovare informazioni dettagliate su JAAS su Internet. Ma posso consigliare questo materiale: Spero che le informazioni di questa recensione siano utili e comprensibili. #Viacheslav
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION