Autenticazione, ruoli e profili

Aggiungere il servizio del dominio autenticato alla soluzione WCF RIA Services quando si desidera verificare le credenziali di un utente, limitare l'accesso per alcune operazioni o conservare le proprietà per ogni utente del progetto client. In un'applicazione Web ASP.NET tradizionale è possibile utilizzare il framework di appartenenza ASP.NET per eseguire queste funzioni. RIA Services si basa sul framework di appartenenza ASP.NET esponendo il framework di appartenenza ai Rich Internet Client tramite il servizio del dominio autenticato. Dopo avere aggiunto un servizio del dominio autenticato, è possibile abilitare le funzioni seguenti:

  • Autenticazione: per verificare le credenziali di un utente e contrassegnare l'utente come connesso o disconnesso.

  • Ruoli: per raggruppare gli utenti per responsabilità e concedere le autorizzazioni delle risorse ai membri autenticati di un gruppo.

  • Profili: per conservare le proprietà per gli utenti autenticati e recuperarle nell'applicazione.

In questo argomento viene illustrato come utilizzare l'autenticazione, i ruoli e i profili in una soluzione Servizi RIA.

Servizio del dominio autenticato

RIA Services fornisce il modello del servizio del dominio autenticato per facilitare l'accesso all'autenticazione, ai ruoli e ai profili a livello di presentazione. Per creare un servizio del dominio autenticato, creare semplicemente un nuovo elemento nel progetto server e selezionare il modello del servizio del dominio autenticato durante la creazione dell'elemento.

RIA_ServicesAddAuth

Quando si aggiunge un servizio del dominio autenticato, il framework di Servizi RIA aggiunge automaticamente due classi al progetto server. La classe che rappresenta il servizio di autenticazione deriva dalla classe AuthenticationBase. La classe che rappresenta l'utente deriva dalla classe UserBase. La classe dell'utente contiene le proprietà del profilo per un utente autenticato.

Quando si compila la soluzione, in Servizi RIA viene automaticamente generata una classe WebContext nel progetto client. La classe WebContext consente di accedere al servizio del dominio autenticato e all'utente nel progetto client. Utilizzare la proprietà Current per recuperare l'istanza corrente di WebContext. La classe WebContext deriva da WebContextBase.

Per un esempio di come aggiungere un servizio del dominio autenticato a una soluzione Servizi RIA, vedere Procedura dettagliata: utilizzo del servizio di autenticazione con Applicazione di navigazione Silverlight.

Applicazione aziendale di Silverlight e autenticazione

Quando si seleziona il modello di applicazione aziendale di Silverlight per creare una soluzione, la soluzione include automaticamente un servizio del dominio autenticato e i controlli per gestire l'accesso e la registrazione degli utenti. Per impostazione predefinita, la soluzione utilizza l'autenticazione basata su form, ma è possibile configurarla facilmente per l'utilizzo dell'autenticazione di Windows. Vengono abilitati i ruoli e viene definita una proprietà del profilo. Per un esempio delle funzionalità di autenticazione incluse per impostazione predefinita in un'applicazione aziendale di Silverlight e di come passare dalla configurazione con autenticazione basata su form a quella con autenticazione di Windows, vedere Procedura dettagliata: utilizzo del modello Applicazione aziendale di Silverlight. Per un esempio dell'utilizzo delle funzionalità predefinite in un'applicazione aziendale di Silverlight, vedere Procedura dettagliata: utilizzo del servizio di autenticazione con l'applicazione aziendale di Silverlight.

Nell'illustrazione seguente viene mostrata la finestra di registrazione, ovvero una delle funzionalità predefinite incluse nell'applicazione aziendale di Silverlight.

Finestra di dialogo Registrazione

Autenticazione

Servizi RIA fornisce le classi che consentono di implementare facilmente l'autenticazione basata su form o l'autenticazione di Windows nella soluzione. Per utilizzare l'autenticazione nella soluzione Servizi RIA, è necessario configurare il progetto server e il progetto client per l'autenticazione. Per ulteriori informazioni, vedere Procedura: abilitare l'autenticazione in Servizi RIA.

Dopo avere configurato i progetti server e client, è possibile consentire l'accesso degli utenti in modo asincrono dall'applicazione Silverlight chiamando il metodo Login sull'oggetto WebContext. Se si utilizza l'autenticazione di Windows o se si recupera un utente con le credenziali persistenti, non è necessario chiamare il metodo Login. Chiamare invece il metodo LoadUser per recuperare l'utente autenticato tramite l'autenticazione di Windows o per caricare un utente con le credenziali persistenti.

Quando si implementa l'autenticazione nel progetto client vengono in genere utilizzati i metodi e le proprietà seguenti.

Membro Codice da utilizzare Attività

Authentication

WebContext.Current.Authentication

Per accedere al servizio di autenticazione.

User

WebContext.Current.User

Per accedere all'oggetto che contiene lo stato dell'utente.

Login

oppure

Login

oppure

Login

WebContext.Current.Authentication.Login(string, string)

oppure

WebContext.Current.Authentication.Login(LoginParameters)

oppure

WebContext.Current.Authentication.Login(LoginParameters, LoginOperation, object)

Per verificare in modo asincrono le credenziali dell'utente.

Logout

oppure

Logout

WebContext.Current.Authentication.Logout(boolean)

oppure

WebContext.Current.Authentication.Logout(LogoutOperation, object)

Per disconnettere in modo asincrono un utente autenticato.

LoadUser

oppure

LoadUser

WebContext.Current.Authentication.LoadUser()

oppure

WebContext.Current.Authentication.LoadUser(LoadUserOperation, object)

Per caricare un utente autenticato, aggiornare lo stato di un utente, caricare l'autenticazione persistente di un utente o recuperare l'oggetto entità utente se utilizzato con l'autenticazione di Windows.

Nell'esempio seguente viene illustrato come chiamare il metodo Login da un gestore eventi per un pulsante di accesso. Viene incluso un metodo di callback per rispondere ai risultati dell'operazione di accesso.

Private Sub LoginButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim lp As LoginParameters = New LoginParameters(UserName.Text, Password.Password)
    WebContext.Current.Authentication.Login(lp, AddressOf Me.LoginOperation_Completed, Nothing)
    LoginButton.IsEnabled = False
    LoginResult.Text = ""
End Sub

Private Sub LoginOperation_Completed(ByVal lo As LoginOperation)
    If (lo.HasError) Then
        LoginResult.Text = lo.Error.Message
        LoginResult.Visibility = System.Windows.Visibility.Visible
        lo.MarkErrorAsHandled()
    ElseIf (lo.LoginSuccess = False) Then
        LoginResult.Text = "Login failed. Please check user name and password."
        LoginResult.Visibility = System.Windows.Visibility.Visible
    ElseIf (lo.LoginSuccess = True) Then
        SetControlVisibility(True)
    End If
    LoginButton.IsEnabled = True
End Sub
private void LoginButton_Click(object sender, RoutedEventArgs e)
{
    LoginParameters lp = new LoginParameters(UserName.Text, Password.Password);
    WebContext.Current.Authentication.Login(lp, this.LoginOperation_Completed, null);
    LoginButton.IsEnabled = false;
    LoginResult.Text = "";
}

private void LoginOperation_Completed(LoginOperation lo)
{
    if (lo.HasError)
    {
        LoginResult.Text = lo.Error.Message;
        LoginResult.Visibility = System.Windows.Visibility.Visible;
        lo.MarkErrorAsHandled();
    }
    else if (lo.LoginSuccess == false)
    {
        LoginResult.Text = "Login failed. Please check user name and password.";
        LoginResult.Visibility = System.Windows.Visibility.Visible;
    }
    else if (lo.LoginSuccess == true)
    {
        SetControlVisibility(true);
    }
    LoginButton.IsEnabled = true;
}

Ruoli

Dopo avere implementato l'autenticazione, è possibile configurare la soluzione in modo da utilizzare i ruoli. Con i ruoli è possibile assegnare gli utenti ai gruppi. È quindi possibile specificare che un'operazione di dominio specifica sia disponibile solo per i membri di tale ruolo. È possibile limitare l'accesso a un'operazione di dominio applicando l'attributo RequiresRoleAttribute all'operazione di dominio. Per ulteriori informazioni, vedere Procedura: abilitare i ruoli in Servizi RIA.

Quando si implementano i ruoli vengono in genere utilizzati i metodi e le proprietà seguenti.

Membro Codice da utilizzare Attività

Roles

WebContext.Current.User.Roles

Per accedere ai ruoli ai quali viene assegnato l'utente.

IsInRole

WebContext.Current.User.IsInRole(string)

Per determinare se l'utente autenticato è un membro di un ruolo specificato.

Nell'esempio seguente viene illustrata un'operazione di dominio con accesso limitato ai membri di un ruolo denominato Managers.

<RequiresRole("Managers")> _
Public Function GetCustomers() As IQueryable(Of Customer)
    Return Me.ObjectContext.Customers
End Function
[RequiresRole("Managers")]
public IQueryable<Customer> GetCustomers()
{
    return this.ObjectContext.Customers;
}

Se si chiama un'operazione di dominio quando l'utente non dispone delle credenziali necessarie, l'operazione di dominio restituisce un'eccezione. È possibile evitare questa situazione controllando le credenziali prima di chiamare l'operazione di dominio. Nell'esempio seguente viene illustrato come controllare se l'utente è un membro del ruolo richiesto prima di caricare i dati.

Private Sub LoadRestrictedReports()
    Dim loadSales = context.Load(context.GetSalesOrderHeadersQuery().Take(numberOfRows))
    SalesOrdersGrid.ItemsSource = loadSales.Entities
    SalesOrdersGrid.Visibility = System.Windows.Visibility.Visible

    If (WebContext.Current.User.IsInRole("Managers")) Then
        Dim loadCustomers = context.Load(context.GetCustomersQuery().Take(numberOfRows))
        CustomersGrid.ItemsSource = loadCustomers.Entities
        CustomersGrid.Visibility = System.Windows.Visibility.Visible
    Else
        CustomersGrid.Visibility = System.Windows.Visibility.Collapsed
    End If
End Sub
private void LoadRestrictedReports()
{
    LoadOperation<SalesOrderHeader> loadSales = context.Load(context.GetSalesOrderHeadersQuery().Take(numberOfRows));
    SalesOrdersGrid.ItemsSource = loadSales.Entities;
    SalesOrdersGrid.Visibility = System.Windows.Visibility.Visible;

    if (WebContext.Current.User.IsInRole("Managers"))
    {
        LoadOperation<Customer> loadCustomers = context.Load(context.GetCustomersQuery().Take(numberOfRows));
        CustomersGrid.ItemsSource = loadCustomers.Entities;
        CustomersGrid.Visibility = System.Windows.Visibility.Visible;
    }
    else
    {
        CustomersGrid.Visibility = System.Windows.Visibility.Collapsed;
    }
}

Profili

Le proprietà del profilo consentono di salvare le informazioni sull'utente. È possibile utilizzare queste proprietà per personalizzare l'applicazione per ogni utente. Per utilizzare i profili nella soluzione, è necessario configurare la soluzione per i profili. Per ulteriori informazioni, vedere Procedura: abilitare i profili in Servizi RIA.

Quando si implementano i profili vengono in genere utilizzati i metodi e le proprietà seguenti.

Membro Codice da utilizzare Attività

User

WebContext.Current.User

Per accedere all'oggetto che contiene tutte le proprietà aggiunte alla classe User, ad esempio User.PhoneNumber.

LoadUser

oppure

LoadUser

WebContext.Current.Authentication.LoadUser()

oppure

WebContext.Current.Authentication.LoadUser(LoadUserOperation, object)

Per aggiornare lo stato dell'utente.

SaveUser

oppure

SaveUser

WebContext.Current.Authentication.SaveUser(boolean)

oppure

WebContext.Current.Authentication.SaveUser(SaveUserOperation, object)

Per salvare tutte le modifiche nello stato dell'utente, ad esempio dopo avere impostato il valore di una proprietà del profilo.

Nell'esempio seguente viene illustrato come impostare la proprietà di un utente in base al valore selezionato dall'utente.

Private Sub OKButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles OKButton.Click
    Dim newSelection = Integer.Parse(defaultRows.SelectionBoxItem.ToString())
    If (newSelection <> WebContext.Current.User.DefaultRows) Then
        WebContext.Current.User.DefaultRows = newSelection
        WebContext.Current.Authentication.SaveUser(True)
    End If
    Me.DialogResult = True
End Sub
private void OKButton_Click(object sender, RoutedEventArgs e)
{
    int newSelection = int.Parse(defaultRows.SelectionBoxItem.ToString());
    if (newSelection != WebContext.Current.User.DefaultRows)
    {
        WebContext.Current.User.DefaultRows = newSelection;
        WebContext.Current.Authentication.SaveUser(true);
    }
    this.DialogResult = true;
}

Gestione degli errori di autenticazione nel client

È possibile gestire gli errori che si verificano durante l'accesso, la disconnessione, il caricamento o il salvataggio degli utenti fornendo un metodo di callback come parametro quando si chiamano tali metodi. Nel metodo di callback aggiungere un codice per gestire l'errore e chiamare il metodo MarkErrorAsHandled per specificare che il framework non genererà un'eccezione. La classe AuthenticationService consente di fornire un metodo di callback quando si chiamano i metodi seguenti:

  • LoadUser

  • Login

  • Logout

  • SaveUser

Nell'esempio descritto nella sezione "Autenticazione" precedente viene illustrato un metodo di callback per l'operazione Login che gestisce gli errori.

Per ulteriori informazioni, vedere Gestione degli errori sul client.

Limitazione dell'accesso a un servizio del dominio

Dopo avere implementato l'autenticazione e i ruoli, è possibile limitare l'accesso in un servizio del dominio solo a specifici utenti. Applicare gli attributi seguenti all'intero servizio del dominio o alle singole operazioni nel servizio. Quando si applica un attributo all'intero servizio, esso viene applicato a tutte le operazioni.

  • RequiresAuthenticationAttribute: specifica che solo gli utenti con le credenziali di autenticazione valide possono accedere all'operazione.

  • RequiresRoleAttribute: specifica che solo gli utenti autenticati che appartengono ai ruoli specificati possono accedere all'operazione.

È possibile creare anche un attributo di autorizzazione personalizzato. Per ulteriori informazioni, vedere Procedura: creare un attributo di autorizzazione personalizzato.

Nell'esempio seguente viene illustrato un servizio del dominio con tre operazioni di dominio. Gli attributi RequiresAuthenticationAttribute e RequiresRoleAttribute vengono utilizzati per limitare l'accesso. L'operazione di dominio GetProducts è disponibile per qualsiasi utente, GetSalesOrderHeaders è disponibile per gli utenti autenticati e GetCustomers è disponibile solo per gli utenti nel ruolo Managers.

<EnableClientAccess()>  _
Public Class AdventureWorksDomainService
    Inherits LinqToEntitiesDomainService(Of AdventureWorksLT_DataEntities)

    <RequiresRole("Managers")> _
    Public Function GetCustomers() As IQueryable(Of Customer)
        Return Me.ObjectContext.Customers
    End Function
    
    Public Function GetProducts() As IQueryable(Of Product)
        Return Me.ObjectContext.Products
    End Function

    <RequiresAuthentication()> _
    Public Function GetSalesOrderHeaders() As IQueryable(Of SalesOrderHeader)
        Return Me.ObjectContext.SalesOrderHeaders
    End Function
End Class
[EnableClientAccess()]
public class AdventureWorksDomainService : LinqToEntitiesDomainService<AdventureWorksLT_DataEntities>
{
    [RequiresRole("Managers")]
    public IQueryable<Customer> GetCustomers()
    {
        return this.ObjectContext.Customers;
    }
 
    public IQueryable<Product> GetProducts()
    {
        return this.ObjectContext.Products;
    }

    [RequiresAuthentication()]
    public IQueryable<SalesOrderHeader> GetSalesOrderHeaders()
    {
        return this.ObjectContext.SalesOrderHeaders;
    }
}

Vedere anche

Attività

Procedura dettagliata: utilizzo del servizio di autenticazione con Applicazione di navigazione Silverlight
Procedura dettagliata: utilizzo del servizio di autenticazione con l'applicazione aziendale di Silverlight

Concetti

Sicurezza per WCF RIA Services