11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,


1 ) le proprietà ValidIssuer e ValidAudience a cosa servono?

In alcuni scenari, soprattutto quando vuoi realizzare il Single Sign-On, i token JWT possono essere emessi da un Identity Provider, cioè da un'applicazione che ha il preciso scopo di verificare email e password dell'utente ed emettere un token JWT che lo autorizzerà a compiere determinate operazioni presso una o più altre applicazioni presente nell'ecosistema.

In questo scenario, l'Issuer è chi sta emettendo il token (l'Identity Provider) mentre l'Audience è l'applicazione o le applicazioni (o loro moduli) su cui il token potrà essere usato.

Ad esempio, quando compri un biglietto per un concerto, l'issuer è rappresentato dalla biglietteria mentre l'audience è il concerto. Sul biglietto ci sono poi degli altri claim, tipo il numero di posto o il settore che ti è stato assegnato.

Validare l'issuer significa che all'ingresso ti controllano che il biglietto sia stato effettivamente emesso da quella biglietteria (e non da un'altra biglietteria). Validare l'audience significa verificare che il concerto sia proprio quello, altrimenti tu con un unico biglietto potresti accedere a svariati concerti diversi.

Questi due controlli in pratica impediscono a un utente di fare "forward" del suo token per usarlo su altre applicazioni dell'ecosistema a cui non avrebbe accesso.

2) A ogni richiesta come faccio a capire se l'utente è validato? Se ne occupa il middleware nel ConfigureServices?

Sì, se ne occupa il middleware. Tu, per sapere se l'utente è autenticato, devi andare a verificare il contenuto della proprietà User.Identity.Name oppure, ancora meglio, poni sulle tue action l'attributo [Authorize] che ti consentirà di verificare che l'utente sia autenticato e che, eventualmente, possieda determinati claim (es. il ruolo di Amministratore).
Qui trovi delle indicazioni in merito.
https://www.aspitalia.com/articoli/asp.net-core/autenticazione-autorizzazione-aspnetcore-p-4.aspx
https://www.aspitalia.com/script/1307/Autorizzazione-Basata-Policy-ASP.NET-Core.aspx

Ciao,
Moreno

Enjoy learning and just keep making
27 messaggi dal 28 agosto 2019
Ciao Moreno,

avresti un esempio dell'uso del token JWT su un applicazione Asp.net Core MVC , come hai citato nei commenti precedenti :

"Quando l'utente fa il login sulla Webapp emetti un cookie di autenticazione. Se usi ASP.NET Identity, il cookie di autenticazione contiene i claim della ClaimsIdentity che rappresenta l'utente. Puoi aggiungere un ulteriore claim il cui valore sarà il token JWT. In questo modo, in tutte le successive richieste dell'utente, potrai estrarre il token dal cookie e usarlo per invocare la web api. "

Grazie
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,
sì, trovi un esempio qui su come aggiungere claim personalizzati.
https://www.aspitalia.com/articoli/asp.net-core/autenticazione-autorizzazione-aspnetcore-p-3.aspx#title_3

Oppure puoi leggere questo articolo che mostra come aggiungere claim aggiuntivi nell'action di login.
https://blog.dangl.me/archive/adding-custom-claims-when-logging-in-with-aspnet-core-identity-cookie/

In tutte le richieste successive al login, il client restituirà il cookie di autenticazione al server. A quel punto puoi autorizzare l'accesso ai controller e alle action di MVC in base alla presenza e al valore dei tuoi claim personalizzati. Per farlo, usa una policy come descritto qui:
https://www.aspitalia.com/articoli/asp.net-core/autenticazione-autorizzazione-aspnetcore-p-4.aspx#title_5

ciao,
Moreno

Enjoy learning and just keep making
27 messaggi dal 28 agosto 2019
Ok grazie della risposta.
Io però ho il token JWT che viene generato da dei webServices e mi serviva capire come gestirlo nella mia app asp.net Core.
L'action che genera il token è questa:

public IActionResult GetToken(string username, string password)
{
//TokenRequest è una nostra classe contenente le proprietà Username e Password
//Avvisiamo il client se non ha fornito tali valori
if (!ModelState.IsValid)
{
return BadRequest();
}

//Lo avvisiamo anche se non ha fornito credenziali valide
if (!VerifyCredentials(username, password))
{
return Unauthorized();
}

return NoContent();
}

il token viene generato dentro il metodo VerifyCredentials e viene aggiunto nell'header con la chiave "X-Token.
Io adesso da una app esterna ho creato un client che uso per chiamare questa action quindi cosi:
WSClient ws = new WSClient();
ws.GetToken(username,password);

Come faccio a ricevere l'header con il token?
Mi conviene leggere il token o farmi passare il ClaimsPrincipal?

Grazie
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,


il token viene generato dentro il metodo VerifyCredentials e viene aggiunto nell'header con la chiave "X-Token.
Come faccio a ricevere l'header con il token?


Il token dovresti leggerlo dal tuo metodo ws.GetToken. Ti basta leggere il valore dell'intestazione X-Token presente nella risposta. Supponendo che tu stia usando HttpClient, ecco un esempio di come ottenere il valore:

//Qui sto inviando la richiesta al server
HttpResponseMessage response = await client.PostAsync(url, data);
//Qui leggo l'intestazione dalla risposta
string token = response.Headers.GetValues("X-Token").FirstOrDefault();




Mi conviene leggere il token o farmi passare il ClaimsPrincipal?

Credo che ws.GetToken dovrebbe restituire il token stringa. Se hai la necessità di estrarre delle informazioni dal token, crea un altro metodo tipo ws.GetPrincipalFromToken a cui passi il token e ti restituisce la collezione di claim trovati al suo interno.

Hai bisogno di ottenere i claim per visualizzare delle informazioni nell'app? Ad esempio lo username dell'utente loggato? Oppure per mostrare/nascondere voci di menu in base al suo ruolo?

Ciao,
Moreno

Enjoy learning and just keep making
27 messaggi dal 28 agosto 2019
Ciao,

"Hai bisogno di ottenere i claim per visualizzare delle informazioni nell'app? Ad esempio lo username dell'utente loggato? Oppure per mostrare/nascondere voci di menu in base al suo ruolo?"

Esatto proprio cosi, ho bisogno di tutte le informazioni dell'utente.

Una volta che riesco a leggere il token dall'header come faccio ad inserirlo in automatico in tutte le richieste successive che faccio dall'app?

In più a ogni richiesta che farò ai webservices il token verrà aggiornato(perchè se l'utente è autenticato il token viene rigenerato) quindi dovrei rileggerlo ogni volta ogni volta.

Grazie
Modificato da FiliBen il 07 gennaio 2020 16:51 -
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,


Esatto proprio cosi, ho bisogno di tutte le informazioni dell'utente.

Ok, allora il tuo metodo ws.GetToken potrebbe restituire una ClaimsPrincipal o al limite un IEnumerable<Claim>. Se vuoi modellarlo un po' meglio, potresti crearti una classe User con dentro varie proprietà i cui valori saranno attinti dai Claim.



Una volta che riesco a leggere il token dall'header come faccio ad inserirlo in automatico in tutte le richieste successive che faccio dall'app?

Sarà la classe WSClient che ti sei creato a doversene preoccupare.
Per esempio, dopo aver chiamato ws.GetToken, fai in modo che il token venga salvato da qualche parte (ad esempio in memoria), così che poi quando chiami un altro metodo come ws.GetProducts, il token venga riletto dal punto in cui era stato salvato (es. in memoria) e incluso nella richiesta HTTP che viene inviata alla Web API.

Come ripeto, è la classe WSClient che dovrà preoccuparsi di recuperare il token, salvarlo, e poi aggiungerlo alle richieste HTTP che vengono inviate alla Web API.


In più a ogni richiesta che farò ai webservices il token verrà aggiornato(perchè se l'utente è autenticato il token viene rigenerato) quindi dovrei rileggerlo ogni volta ogni volta.

Esatto, ma non per questo avrai codice duplicato. Fai in modo che i vari metodi di interrogazione della Web API tipo ws.GetProducts, ws.CreateProduct, ws.UpdateProduct, ws.GetCategories, ... internamente invochino un metodo privato di WSClient tipo SendRequest che come parametri accetterà il verbo HTTP (es. GET, POST, ...), l'url e gli eventuali dati da inviare nel corpo della richiesta. Sarà quel metodo a recuperare il token e ad aggiungerlo come intestazione della richiesta. Poi, si occuperà anche di ottenere il nuovo token dalla risposta e a salvarlo in memoria per l'utilizzo nella prossima richiesta.

ciao,
Moreno

Enjoy learning and just keep making
27 messaggi dal 28 agosto 2019
CIao,

va bene ci provo grazie.
Il token è corretto salvarlo nella sessione dell'utente?
Usando questa dicitura :
HttpContext.Session.SetString("JWToken", token);

Se io lo salvo nella sessione noto che se apro due schede nello stesso browser, le schede hanno lo stesso ID di sessione e quindi non riesco ad usare due account utente diversi nello stesso browser.
Mentre se uso due browser diversi ho due SessionID diversi e quindi riesco ad usare due utenti.

Ma si riesce ad usare una sessione diversa per ogni scheda?
Grazie
Modificato da FiliBen il 10 gennaio 2020 17:10 -

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.