Compartir a través de


Tarea 2: habilitar la autorización basada en notificaciones en el servicio de flujo de trabajo

En esta tarea se asegurará de que sólo un conjunto de credenciales de usuario pueda invocar operaciones en el servicio de flujo de trabajo que creó en Ejercicio 1: Creación de un servicio de flujo de trabajo básico. Estas credenciales se pasan al servicio como un ClaimSet. Para obtener más información acerca de ClaimSets, vea Managing Claims and Authorization with the Identity Model.

Nota

Cuando se usa el diseñador de flujo de trabajo de Visual Studio para crear o administrar servicios de flujo de trabajo, a veces se generan errores de validación falsos. Si puede generar correctamente su proyecto, omita los errores de validación.

Habilitar la validación de usuarios a través de ClaimSets

  1. Si no tiene abierta la solución WorkflowServiceTutorial, abra Visual Studio 2008, haga clic en Archivo, resalte Abrir y vaya a la solución WorkflowServiceTutorial.

  2. En el panel Explorador de soluciones, bajo el nodo de proyecto de WorkflowServiceTutorial, haga clic con el botón secundario del mouse en la subcarpeta Referencias y seleccione Agregar Referencia. O bien, si ha creado una solución de Visual Basic, haga clic con el botón secundario del mouse en el nodo de proyecto de WorkflowServiceTutorial y seleccione Agregar referencia.

  3. En el cuadro de diálogo Agregar referencia, en la pestaña .NET, seleccione System.IdentityModel y haga clic en Aceptar.

  4. Los objetos ClaimSet y List se usan en esta tarea, así que agregue las instrucciones de uso siguientes en la parte superior de Workflow1.cs:

    using System.IdentityModel.Claims;
    using System.Collections.Generic;
    

    Si ha creado una solución de Visual Basic, haga clic con el botón secundario del mouse en el nodo de proyecto de WorkflowServiceTutorial y seleccione Propiedades. Seleccione la pestaña Referencias y, en Espacios de nombres importados, haga clic en las casillas correspondientes a System.IdentityModel.Claims. Ya se admite el espacio de nombres System.Collections.Generic.

  5. Si el diseñador de flujo de trabajo para el servicio de flujo de trabajo no está visible, ábralo haciendo clic con el botón secundario del mouse en Workflow1.cs (o en Workflow1.vb si ha creado una solución de Visual Basic) y seleccione Verdiseñador.

  6. En la actividad Workflow1InitialState StateActivity, haga doble clic en la actividad WaitToStartService EventDrivenActivity para expandir esa actividad compuesta.

  7. Resalte la actividad ReceiveActivity asociada a la operación StartupService.

  8. En el panel Propiedades, en OperationValidation, escriba ValidateUser y presione Entrar para generar automáticamente un controlador de eventos para el evento OperationValidation.

  9. Vaya al controlador de eventos ValidateUser.

    En el cuerpo de ValidateUser, compruebe que el servicio ha reconocido previamente el usuario, y si no es así, no les permita invocar ninguna operación. Por ejemplo, esto es útil si un empleado de ventas inicia un pedido de compra y no vuelve atrás para completarlo hasta después de varios días. Debería comprobar que es el mismo usuario antes de permitirle invocar cualquiera operación más en el servicio. No se pueden usar los identificadores de contexto y conversación porque los usuarios malintencionados pueden suplantarlos.

        Private Sub ValidateUser(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.OperationValidationEventArgs)
            For Each claims As ClaimSet In e.ClaimSets
                ' Find the claim that contains the name of the operation caller.
                Dim opCaller As List(Of Claim) = claims.FindClaims(ClaimTypes.Name, Rights.PossessProperty).ToList()
    
                ' Retrieve the name of the caller from the claim.
                Dim opCallerName As String = opCaller(0).Resource.ToString()
    
                ' If this is the caller's first time through the ValidationUser method, set 
                ' the operation caller's name to a global variable named "owner." Every subsequent
                ' operation that uses this method will verify that the caller of
                ' the operation is the same as the caller of the initial operation before
                ' either validating or invalidating the caller.
                If [String].IsNullOrEmpty(owner) Then
                    owner = opCallerName
                ElseIf Not owner.Equals(opCallerName) Then
                    e.IsValid = False
                End If
            Next
        End Sub
    
    private void ValidateUser(object sender, OperationValidationEventArgs e)
    {
        foreach (ClaimSet claims in e.ClaimSets)
        {     
            // Find the claim that contains the name of the operation caller.
            List<Claim> opCaller = claims.FindClaims(ClaimTypes.Name, Rights.PossessProperty).ToList<Claim>();
    
            // Retrieve the name of the caller from the claim.
            string opCallerName = opCaller[0].Resource.ToString();
    
            // If this is the caller's first time through the ValidationUser method, set 
            // the operation caller's name to a global variable named "owner." Every subsequent
            // operation that uses this method will verify that the caller of
            // the operation is the same as the caller of the initial operation before
            // either validating or invalidating the caller.
            if(String.IsNullOrEmpty(owner))
            {
                owner = opCallerName;
            }
            else if (!owner.Equals(opCallerName))
            {
                e.IsValid = false;
            }
        }
    }
    
  10. Declare una variable denominada "owner" para usarla como validación al recibir invocaciones de operación posteriores, tal y como se muestra en el código siguiente:

    Public class ServerWorkflow
        Inherits StateMachineWorkflowActivity
    
        ' These variables are bound to the input and output parameters of the ReceiveActivity.
        Public returnValue As Int32 = Nothing
        Public inputValue As Int32 = Nothing
    
        'This variable contains the user name for the NT account used in operation validation.
        Public owner As String = Nothing
    ...
    End Class
    
    public sealed partial class ServerWorkflow : StateMachineWorkflowActivity
    {
        public ServerWorkflow()
        {
            InitializeComponent();
        }
    
        // These variables are bound to the input and output parameters of the ReceiveActivity.
        public int returnValue = default(int);
        public int inputValue = default(int);
    
        // This variable contains the user name for the NT account used 
        // in operation validation.
        public string owner = default(string);
        ...
    }
    
  11. Para cada una de las operaciones restantes, asocie el evento OperationValidation al método ValidateUser.

  12. Genere su solución y compruebe que su autorización comprueba el trabajo.

    Si un usuario con un nombre diferente intenta invocar una operación en el servicio una vez establecida la variable owner, entonces se devolverá el mensaje de error siguiente al cliente:

    Security check failed.
    

    Nota

    ClaimSet se procesa antes que PrincipalPermissionRole o PrincipalPermissionName, por lo que si realiza dos comprobaciones de autorización diferentes de un grupo de cuenta NT, una usando ClaimSet y la otra mediante PrincipalPermissionRole, la comprobación de autorización ClaimSet tendrá lugar primero.

Consulte también

Tareas

Tarea 1: Habilitación de autorización basada en función en el servicio de flujo de trabajo

Otros recursos

Ejercicio 2: Implementación de características de seguridad en el servicio de flujo de trabajo

Copyright © 2007 Microsoft Corporation. Reservados todos los derechos.