Sei in: Home : Competenze : Applicazioni Web : Single sign-on

Single sign-on

Il Single sign-on (SSO, traducibile come autenticazione unica o identificazione unica) è un sistema specializzato che permette ad un utente di autenticarsi una sola volta e di accedere a tutte le risorse informatiche alle quali è abilitato.

Gli obiettivi sono multipli:

  • semplificare la gestione delle password: maggiore è il numero della password da gestire, maggiore è la possibilità che saranno utilizzate password simili le une alle altre e facili da memorizzare, abbassando così il livello di sicurezza;
  • semplificare la gestione degli accessi ai vari servizi;
  • semplificare la definizione e la gestione delle politiche di sicurezza.

Vi sono tre approcci per la creazione di un sistema di SSO: l'approccio centralizzato(centralizza le politiche di sicurezza), l'approccio federativo e l'approccio cooperativo (lasciano entrambi le politiche indipendenti per ogni gestore).

Esistono molti SSO gratuiti e commerciali.

JA-SIG Central Authentication Service (CAS)

http://www.jasig.org/cas è un servizio single sign-on libero (originariamente sviluppato dall'Università di Yale) che permette alle applicazioni web la possibilità di rinviare tutte le autenticazioni a un server centrale o a più server di fiducia. Numerosi client sono disponibili gratuitamente

http://www.ja-sig.org/wiki/display/CASC/.Net+Cas+Client

Per fare un esempio, immaginiamo di avere un servizio Web che restituisce i dettagli utente preso da un database. Si potrebbe avere il servizio web con 2 parametri - nome utente e password - ma questo vorrebbe dire che si dovrà passare le credenziali dell'utente. Interrogare il servizio web via SSL sarebbe un miglioramento, ma ancora lontano dall'essere ideale. Una soluzione migliore sarebbe quella di adottare un parametro - un ticket proxy generata da CAS.

È quindi possibile utilizzare questo client CAS per ottenere il nome utente nel modo seguente:

 [WebMethod]
    public String GetUserName(String ticket) {
//The first argument in the constructor is the service against which you trying to validate
//The second argument is the proxy validation URL for your CAS server
        DotNetCASClientProxyValidate client
                = new DotNetCASClientProxyValidate("http://myawesomeservice.uwe.ac.uk", "https://casserver.uwe.ac.uk/cas/proxyValidate");
        String userid = client.Authenticate(ticket);
        return userid;
    }

Ovviamente, si vorrebbe quindi utilizzare il nome utente per recuperare dati dal database. Se l'autenticazione fallisce, allora l'utente restituito sarà 'failed'.

La classe DotNetCASClientProxyValidate ha anche un metodo GetCASXML che contiene anche il ticket in formato String. Esegue lo stesso processo di autenticazione del metodo Authenticate(), ma, invece di restituire un nome utente, esso restituisce l'XML completo che CAS ha restituito - per esempio:

<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
        <cas:authenticationSuccess>
              <cas:user>testUserName</cas:user>
                <cas:proxies>
                       <cas:proxy>https://myawesomecasproxyplace/cas/pgtURL.asp</cas:proxy>
              </cas:proxies>
        </cas:authenticationSuccess>
</cas:serviceResponse>

 Questo particolarmente utile se si desidera accedere a dati in più che il nome utente - soprattutto se il CAS è configurato per restituire informazioni di altri utenti.

Al fine di ottenere l'autenticazione basata su browser la prima cosa che dovete fare è aggiungere alcune proprietà per il vostro Web.Config. Queste proprietà sono:

  • casLoginURL - l'URL di accesso all'interno della vostra applicazione server CAS. ad esempio https: / / casserver.uwe.ac.uk / CAS / login
  • casValidateURL - L'URL di validazione all'interno della vostra applicazione server CAS. ad esempio https: / / casserver.uwe.ac.uk / CAS / serviceValidate (o proxyValidate se si desidera ticket proxy)
  • serviceURL - La URL per il servizio che stai tentando di autenticazione per l'accesso. ad esempio http://myawesomeservice.uwe.ac.uk/CASTestServiceValidation/Default.aspx

Questi dovrebbero essere tutti all'interno di un elemento ApplicationSettings:

<configuration>
<appSettings>
<add key="casLoginURL" value="https://casserver.uwe.ac.uk/cas/login" />
<add key="casValidateURL" value="https://casserver.uwe.ac.uk/cas/serviceValidate" />
<add key="serviceURL" value="http://lmyawesomeservice.uwe.ac.uk/CASTestServiceValidation/Default.aspx" />
</appSettings>
...
</configuration>

È quindi necessario creare una nuova istanza di DotNetCASClientServiceValidate. Una volta che hai un 'istanza di DotNetCASClientServiceValidate, è possibile chiamare il metodo Authenticate() . Questo metodo richiede tre parametri: request, response e se avete bisogno dell'XML da CAS o solo del nome utente. Bisogna essere consapevoli del fatto che Authenticate() reindirizza il browser client tramite CAS, se necessario.

Questo metodo puo' restituire sia il nome utente, o 'failed' o l'XML restituito dal CAS.

Esempio di codice:

protected void Page_Load(object sender, EventArgs e) {
        String userId = (String) Session["userId"];
        if (userId == null) {
            DotNetCASClientServiceValidate client = new DotNetCASClientServiceValidate();
            userId = client.Authenticate(Request, Response, true);
            lblCas.Text = "Had to authenticate via CAS...";
       }
        Session["userId"] = userId;
        lblResult.Text = userId;

    }

È anche facile usare il sistema di autenticazione integrato nel sistema di autenticazione ASP.Net basato su form  Tutto ciò che è necessario è un cambiamento nel Web.config per configurare un form di login e di una pagina ASP.Net di login che utilizza  .Net CAS client come sopra. 

Quindi, la variazione del web.config potrebbe assomigliare a:

<system.web>
        <authorization>
            <deny users="?" />
        </authorization>
        <authentication mode="Forms" >
            <forms loginUrl="LoginPage.aspx" />
        </authentication>
    </system.web>

L'elemento di autorizzazione specifica che tutti gli utenti che non sono connessi dovrebbero essere costretti a passare attraverso la risorsa di accesso. L'elemento di autenticazione definisce poi il processo di login, basato su form utilizzando LoginPage.aspx. Questa pagina di accesso non dovrà cobntenere altro che:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="LoginPage.aspx.cs" Inherits="LoginPage" %>

Se poi guardiamo il codice in LoginPage.aspx.cs possiamo vedere come si può accedere in via CAS e poi informare il processo di autenticazione .NET che il login ha avuto successo

protected void Page_Load(object sender, EventArgs e) {
        DotNetCASClientServiceValidate client = new DotNetCASClientServiceValidate();
        String userId = client.Authenticate(Request, Response, false);
        if (userId.Equals("failed")) {
            //Handle the auth failure...
        } else {
            FormsAuthentication.RedirectFromLoginPage(userId, false);
        }
    }

Come potete vedere, siamo fondamentalmente solo utilizzando lo stesso processo come sopra, ma, questa volta, utilizzando il RedirectFromLoginPage () per dichiarare che l'utente sia loggato. Questo metodo richiede due argomenti: il nome utente e un valore booleano che specifica se  impostare un cookie permanente.

Ciò significa che ora tutte le risorse in questa applicazione web sono protette da CAS. Qualsiasi richiesta di una pagina, se l'utente non è autenticato, causa un reindirizzamento al LoginPage.aspx che, a sua volta, porta l'utente tramite CAS a fare il login.

Exception Handling
Nessuno dei metodi in questo client solleva eccezioni. Se si verifica un'eccezione durante il processo di autenticazione allora la classe registrerà un messaggio di errore e prenderà i provvedimenti opportuni.
I logs vengono registrati da un event logger. Sui sistemi Windows si trova nell' pplication Event View sotto CasClient C #. In base alla documentazione mono, sarà registrato in / var / lib / mono / EventLog sui sistemi Unix, a meno che non si specifica un percorso diverso. (Questo può essere un errore di battitura nella documentazione mono - dovrebbe forse essere / var / log /...).