Ejemplo de Código de Aleatorización BotDetect ASP.NET 1.1 CAPTCHA VB.NET

Este ejemplo de aleatorización con BotDetect ASP.NET CAPTCHA muestra como puede aleatorizar fácilmente varios parámetros de control CAPTCHA, lo que puede mejorar significativamente la seguridad de protección CAPTCHA y es la mejor forma de sacarle provecho a los 50 distintos algoritmos CAPTCHA que vienen con BotDetect.

Ubicación de los archivos del proyecto de ejemplo

Por defecto, el proyecto de ejemplo queda instalado en
C:\Archivos de Programa\Lanapsoft\BotDetect\ASP.NET 1.1\v2.0\Samples\VBNetBotDetect2RandomDemo\.

También lo puede arrancar desde el Menú de Inicio:
Programas > Lanapsoft > BotDetect > ASP.NET 1.1 > v2.0 > Samples > VB.NET BotDetect Random Demo Preview.

Default.aspx

Listado del Código Fuente Completo

<%@ Page Language="vb" AutoEventWireup="false"
  Codebehind="Default.aspx.vb" Inherits="VBNetBotDetectDemo._Default" 
%>

<%@ Register Assembly="Lanap.BotDetect" Namespace="Lanap.BotDetect" 
  TagPrefix="BotDetect" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>BotDetect Demo</title>
    <link type='text/css' rel='Stylesheet' href='StyleSheet.css' />
</head>
<body>
    <form id="form1" runat="server">
    <fieldset id="Preview">
        <legend>
            <span id="PreviewLegend">CAPTCHA Preview</span>
        </legend>
        <div id="PromptDiv">
            <span id="Prompt">Type the characters you see in 
              the picture</span>
        </div>
        <div id="CaptchaDiv">
            <BotDetect:Captcha ID="SampleCaptcha" runat="server" />
        </div>
        <div id="ValidationDiv">
            <asp:TextBox ID="CodeTextBox" runat="server">
            </asp:TextBox>
            <asp:Button ID="ValidateButton" runat="server" />
            <asp:Label ID="MessageCorrectLabel" runat="server">
            </asp:Label>
            <asp:Label ID="MessageIncorrectLabel" runat="server">
            </asp:Label>
        </div>
    </fieldset>
    <div id="Note">
        <span>NOTE: the Trial version will use "LANAP" instead of a 
          random code in 50% of renderings.</span>
    </div>
    </form>
</body>
</html>

Explicación

Las líneas requeridas para agregar el control de BotDetect CAPTCHA al formulario ASP.NET están marcadas con negritas. Para usar el control <BotDetect:Captcha>, primero debemos registrar el ensamble Lanap.BotDetect.dll usando la directiva <%@Register %>.

El formulario también contiene <asp:TextBox> para la entrada del usuario, un <asp:Button> para enviar la página, y un par de controles <asp:Label> que son utilizados para mostrar los resultados de la validación CAPTCHA.

El resto del archivo es generado por defecto por Visual Studio 2005 o, simplemente define el diseño y la presentación visual de la página.

No hay diferencia entre el archivo .aspx de este ejemplo y el básico, ya que toda la aleatoridad CAPTCHA es realizada detrás del código.

Default.aspx.vb

Listado del Código Fuente Completo

Public Class _Default
    Inherits System.Web.UI.Page

    #Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub _
        InitializeComponent()
    End Sub
    
    Protected WithEvents MessageCorrectLabel As _
        System.Web.UI.WebControls.Label
				
    Protected WithEvents MessageIncorrectLabel As _
        System.Web.UI.WebControls.Label
				
    Protected WithEvents SampleCaptcha As _
        Lanap.BotDetect.Captcha
				
    Protected WithEvents CodeTextBox As _
        System.Web.UI.WebControls.TextBox
				
    Protected WithEvents ValidateButton As _
        System.Web.UI.WebControls.Button

    'NOTE: The following placeholder declaration is required by 
    'the Web Form Designer. Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object

    Private Sub Page_Init(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form 
        'Designer. Do not modify it using the code editor.
        InitializeComponent()
    End Sub

    #End Region
		
    Protected Sub Page_Load(ByVal sender As System.Object, 
        ByVal e As System.EventArgs) Handles MyBase.Init
				
        'register CAPTCHA-specific event handler
        AddHandler SampleCaptcha.PreDrawCaptchaImage, 
           AddressOf SampleCaptcha_PreDrawCaptchaImage
    End Sub

    Protected Sub Page_PreRender(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.PreRender

        ' initial page setup
        If (Not IsPostBack) Then

            'set control text
            ValidateButton.Text = "Validate"
            MessageCorrectLabel.Text = "Correct!"
            MessageIncorrectLabel.Text = "Incorrect!"

            'these messages are shown only after validation
            MessageCorrectLabel.Visible = False
            MessageIncorrectLabel.Visible = False
        End If
				
        CodeTextBox.Attributes.Add("onkeyup", _
            "this.value = this.value.toLowerCase();")

        If (IsPostBack) Then
            'validate the input code, and show the 
            'appropriate message 
            Dim code As String = CodeTextBox.Text.Trim().ToUpper()

            If (SampleCaptcha.Validate(code)) Then
                MessageCorrectLabel.Visible = True
                MessageIncorrectLabel.Visible = False
            Else
                MessageCorrectLabel.Visible = False
                MessageIncorrectLabel.Visible = True
            End If

            'clear previous user code input
            CodeTextBox.Text = ""
        End If

    End Sub

    ' all CAPTCHA Aleatorización should be performed in this event 
    ' handler instead of Page_Load or Page_PreRender, because this 
    ' event is also fired for direct CAPTCHA image requests (which 
    ' skip the page events since the page is never loaded), for 
    ' example when clicking the Reload CAPTCHA button repeatedly
    Protected Sub SampleCaptcha_PreDrawCaptchaImage( _ 
        ByVal sender As System.Object, ByVal e As System.EventArgs)
        
        Dim captcha As ICaptcha = sender

        ' randomize code generation properties
        captcha.CodeType = RandomizationHelper.GetRandomCodeType()
        captcha.CodeLength = _ 
            RandomizationHelper.GetRandomCodeLength(4, 6)

        ' randomize text style
        Dim styles As TextStyleEnum() = { _
            TextStyleEnum.Lego, TextStyleEnum.MeltingHeat, _
            TextStyleEnum.Ghostly, TextStyleEnum.FingerPrints, _
            TextStyleEnum.Graffiti2, TextStyleEnum.Bullets2, _
            TextStyleEnum.CaughtInTheNet2, TextStyleEnum.Collage, _ 
            TextStyleEnum.Chalkboard
        }

        captcha.TextStyle = _ 
            RandomizationHelper.GetRandomTextStyle(styles)

    End Sub

End Class

Explicación

En la fase Page_Init del ciclo de vida de la página ASP.NET, registramos un manejador de eventos especial para que sea ejectutado antes de que cada imagen CAPTCHA sea generada, en cual realizamos la aleatorización CAPTCHA. Ya que las imágenes CAPTCHA son generadas y enviadas al cliente en una solicitud Http separada de la que carga la página ASP.NET (cuando este código se ejecuta), agregamos este manejador de eventos para asegurar que el CAPTCHA es aleatorizado cada vez que es dibujado, y no una vez que se carge la página.

Esto es importante porque las peticiones de imagen CAPTCHA no tienen que estar ligados a un número de cargas de página - más notable, cuando se usa el botón de Recargar CAPTCHA, y cuando robots acceden a la imagen CAPTCHA directamente, es posible que muchas imágenes CAPTCHA sean generadas depués de una sola carga de página (y la relacionada ejecución Page_PreRender execution).

En el manejador Captcha_PreDrawCaptchaImage,la instancia de control CAPTCHA está disponible como un parámetro sender. Para hacer la aleatorización lo más simple posible, usamos la clase RandomizationHelper, que nos permite obtener un valor aleatorio de un parámetro dado de todas los valores disponibles (como el CodeType de CAPTCHA), o de un rango dado de valores (como el CodeLength de CAPTCHA), o de un set de valores dados (como el TextStyle de CAPTCHA).

También puede hacer aleatorias otras propiedades de CAPTCHA de manera similar, pero el algoritmo de dibujo CAPTCHA y la longitud del código CAPTCHA son las que mejoran la seguridad CAPTCHA cuando son aleatoreas. Cada algoritmo CAPTCHA individual puede ser teóricamente y eventualmente roto (dado suficiente esfuerzo), pero si el robot también tiene que reconocer el algoritmo usado para cada imagen, la tarea se vuelve de mayor magnitud. También, varios algoritmos populares CAPTCHA han sido rotos porque usaban un número fijo de caracteres en sus imágenes – "encuentre 5 caracteres en esta imagen" es una tarea más fácil de automatizar que "encuentre un número desconocido de caracteres en esta imagen."

RandomizationHelper.vb

Listado del Código Fuente Completo

Imports Microsoft.VisualBasic
Imports System.Drawing
Imports Lanap.BotDetect

Public NotInheritable Class RandomizationHelper

    Private Sub New()
        'constructor omitted, static methods only
    End Sub

    ' a single global generator is used for all random numbers
    Private Shared ReadOnly _rand As Random = New Random()

    Public Const DefaultCodeType As CodeTypeEnum = _
        CodeTypeEnum.AlphaNumeric

    Public Shared Function GetRandomCodeType( _
        ByVal ParamArray usedValues As CodeTypeEnum()) As CodeTypeEnum

        Dim codeType As CodeTypeEnum = DefaultCodeType

        If (0 = usedValues.Length) Then
            Dim max As Integer = 
                System.Enum.GetValues(GetType(CodeTypeEnum)).Length
            codeType = CType(_rand.Next(max), CodeTypeEnum)
        ElseIf (1 = usedValues.Length) Then
            codeType = usedValues(0)
        Else
            Dim max As Integer = usedValues.Length
            Dim index As Integer = _rand.Next(max)
            codeType = usedValues(index)
        End If

        Return codeType

    End Function

    Public Const DefaultCodeLength As Integer = 5
    Public Const MinCodeLength As Integer = 1
    Public Const MaxCodeLength As Integer = 15

    Public Shared Function GetRandomCodeLength( _
        Optional ByVal min As Integer = 0, Optional ByVal max As _
            Integer = 0) Integer

        If ((max > MaxCodeLength) OrElse (max < MinCodeLength)) Then
            max = MaxCodeLength
        End If

        If ((min < MinCodeLength) OrElse (min > max)) Then
            min = MinCodeLength
        End If

        Return _rand.Next(min, max + 1)

    End Function

    Public Shared ReadOnly DefaultImageFormat As ImageFormatEnum = _
        ImageFormatEnum.Jpeg

    Public Shared Function GetRandomImageFormat( _
        ByVal ParamArray usedValues As ImageFormatEnum()) As _ 
            ImageFormatEnum

        Dim imageFormat As ImageFormatEnum = DefaultImageFormat

        If (0 = usedValues.Length) Then
            Dim max As Integer = System.Enum.GetValues( _
                GetType(ImageFormatEnum)).Length
            imageFormat = CType(_rand.Next(max), ImageFormatEnum)
        ElseIf (1 = usedValues.Length) Then
            imageFormat = usedValues(0)
        Else
            Dim max As Integer = usedValues.Length
            Dim index As Integer = _rand.Next(max)
            imageFormat = usedValues(index)
        End If

        Return imageFormat

    End Function

    Public Shared ReadOnly DefaultImageSize As Size = New Size(250, 50)
    Public Shared ReadOnly MinImageSize As Size = New Size(50, 40)
    Public Shared ReadOnly MaxImageSize As Size = New Size(500, 200)

    Public Shared Function GetRandomImageSize() As Size
        Return GetRandomImageSize(New Size(0, 0), New Size(0, 0))
    End Function

    Public Shared Function GetRandomImageSize(ByVal maxSize As Size) _
        As Size
        
        Return GetRandomImageSize(New Size(0, 0), maxSize)
    End Function

    Public Shared Function GetRandomImageSize(ByVal minSize As Size, _
        ByVal maxSize As Size) As Size
				
        'determine width
        If ((maxSize.Width > MaxImageSize.Width) OrElse _
            (maxSize.Width < MinImageSize.Width)) Then
            maxSize.Width = MaxImageSize.Width
        End If

        If ((minSize.Width < MinImageSize.Width) OrElse _
            (minSize.Width > maxSize.Width)) Then
            minSize.Width = MinImageSize.Width
        End If
				
        Dim width As Integer = _
            _rand.Next(minSize.Width, maxSize.Width + 1)

        'determine height
        If ((maxSize.Height > MaxImageSize.Height) OrElse _
           (maxSize.Height < MinImageSize.Height)) Then
            maxSize.Height = MaxImageSize.Height
        End If

        If ((minSize.Height < MinImageSize.Height) OrElse _
            (minSize.Height > maxSize.Height)) Then
            minSize.Height = MinImageSize.Height
        End If
				
        Dim height As Integer = _
            _rand.Next(minSize.Height, maxSize.Height + 1)

        'the result
        Return New Size(width, height)
    End Function

    Public Const DefaultTextStyle As TextStyleEnum = _
        TextStyleEnum.Chalkboard

    Public Shared Function GetRandomTextStyle( _
        ByVal ParamArray usedValues As TextStyleEnum()) As _
        TextStyleEnum

        Dim textStyle As TextStyleEnum = DefaultTextStyle

        If (0 = usedValues.Length) Then
            Dim max As Integer = _ 
                System.Enum.GetValues(GetType(TextStyleEnum)).Length
            textStyle = CType(_rand.Next(max), TextStyleEnum)
        ElseIf (1 = usedValues.Length) Then
            textStyle = usedValues(0)
        Else
            Dim max As Integer = usedValues.Length
            Dim index As Integer = _rand.Next(max)
            textStyle = usedValues(index)
        End If

        Return textStyle

    End Function

End Class

Explicación

RandomizationHelper es una pequeña clase de utilidad que puede usar en sus proyectos para simplificar varios parámetros CAPTCHA de aleatorización.

Para cada parámetro CAPTCHA que puede tomar un valor númerico o enumerado, esta clase provee un método estático que retorna un valor aleatorio. Cada parámetro tiene su valor por defecto, y parámetros numéricos también tienen valores máximos y mínimos predefinidos.

Todos los métodos de aleatorización toman un número variable de parámetros, via sobrecargas de métodos múltiples o via la palabra params.

Métodos que retornan valores numéricos (como por ejemplo, CodeLenght) se comportan de la siguiente manera:

  • Si no se dan parámetros, un valor aleatorio es seleccionado entre los valores mínimo y máximo predefinidos.
  • Si un único valor es dado como parámetro, el valor aleatorio es seleccionado entre el mínimo valor predefinido y el valor dado como el máximo. Note que no es posible usar un máximo más grande que el predefinido, solo uno menor.
  • Si dos valores son dados como parámetros, el valor aleatorio es seleccionado de entre el primer valor como el mínimo y el segundo valor como el máximo. Note que no es posible usar un máximo mayor que el predefinido, o un mínimo menor que el predefinido.

Los métodos que retornan valores enumerados (por ejemplo, CodeType) se comportan de la siguiente manera:

  • Si no se da ningún parámetro, el valor aleatorio es seleccionado de todos los valores de enumeración posibles.
  • Si un único valor es dado como parámetro, es retornado como el resultado - tenga cuidado de no pasar un único valor a estos métodos, ya que no habría aleatorización. Y si quiere usar un único valor, simplemente asígnelo directo al parámetro apropiado.
  • Si un set de valores (por ejemplo, un arreglo) es dado como parámetro, el valor aleatorio es seleccionado del set.

Por supuesto, también podría usar tal código de aleatorización directamente en sus proyectos, pero encapsulándolo en la clase RandomizationHelper .

Web.config

Listado del Código Fuente Completo

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    
  <system.web>
  
  <httpHandlers>
    <add verb="*" path="LanapCaptcha.aspx" 
      type="Lanap.BotDetect.CaptchaHandler, Lanap.BotDetect"/>
  </httpHandlers>

  <!-- DYNAMIC DEBUG COMPILATION
    Set compilation debug="true" to enable ASPX debugging. Otherwise, 
    setting this value to false will improve runtime performance of 
    this application. Set compilation debug="true" to insert debugging 
    symbols (.pdb information) into the compiled page. Because this 
    creates a larger file that executes more slowly, you should set 
    this value to true only when debugging and to false at all other 
    times. For more information, refer to the documentation about 
    debugging ASP.NET files.
  -->
  <compilation 
    defaultLanguage="vb"
    debug="false"
  />

  <!-- CUSTOM ERROR MESSAGES
    Set customErrors mode="On" or "RemoteOnly" to enable custom error 
    messages, "Off" to disable. 
		
    Add <error> tags for each of the errors you want to handle.

    "On" Always display custom (friendly) messages.
		
    "Off" Always display detailed ASP.NET error information.
		
    "RemoteOnly" Display custom (friendly) messages only to users not 
      running on the local Web server. This setting is recommended for 
      security purposes, so that you do not display application detail 
      information to remote clients.
  -->
  <customErrors 
    mode="RemoteOnly" 
  /> 

  <!-- AUTHENTICATION 
    This section sets the authentication policies of the application. 
    Possible modes are "Windows", "Forms", "Passport" and "None".

    "None" No authentication is performed. 
		
    "Windows" IIS performs authentication (Basic, Digest, or 
    Integrated Windows) according to its settings for the 
    application. Anonymous access must be disabled in IIS. 
		
    "Forms" You provide a custom form (Web page) for users to 
    enter their credentials, and then you authenticate them 
    in your application. A user credential token is stored 
    in a cookie.
		
    "Passport" Authentication is performed via a centralized 
    authentication service provided by Microsoft that offers 
    a single logon and core profile services for member sites.
  -->
  <authentication mode="Windows" /> 

  <!-- AUTHORIZATION 
    This section sets the authorization policies of the 
    application. You can allow or deny access to application 
    resources by user or role. Wildcards: "*" mean everyone, 
    "?" means anonymous (unauthenticated) users.
  -->

  <authorization>
    <allow users="*" /> <!-- Allow all users -->
    <!-- 
    <allow users="[comma separated list of users]"
      roles="[comma separated list of roles]"/>
    <deny users="[comma separated list of users]"
      roles="[comma separated list of roles]"/>
    -->
  </authorization>

  <!-- APPLICATION-LEVEL TRACE LOGGING
    Application-level tracing enables trace log output for 
    every page within an application. 
    Set trace enabled="true" to enable application trace 
    logging. If pageOutput="true", the trace information 
    will be displayed at the bottom of each page. Otherwise, 
    you can view the application trace log by browsing the 
    "trace.axd" page from your web application root. 
  -->
  <trace
    enabled="false"
    requestLimit="10"
    pageOutput="false"
    traceMode="SortByTime"
    localOnly="true"
  />

  <!-- SESSION STATE SETTINGS
    By default ASP.NET uses cookies to identify which requests 
    belong to a particular session. If cookies are not available, 
    a session can be tracked by adding a session identifier to the 
    URL. To disable cookies, set sessionState cookieless="true".
  -->
  <sessionState 
    mode="InProc"
    stateConnectionString="tcpip=127.0.0.1:42424"
    sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
    cookieless="false" 
    timeout="20" 
  />

  <!-- GLOBALIZATION
    This section sets the globalization settings of the application. 
  -->
  <globalization 
    requestEncoding="utf-8" 
    responseEncoding="utf-8" 
  />
   
 </system.web>

</configuration>

Explicación

Las líneas necesarias para que BotDetect CAPTCHA funcione correctamente han sido marcadas con negritas, las demás líneas son valores estándar generados por Visual Studio 2003 por defecto. No hay configuraciones especiales relacionadas con la aleatorización CAPTCHA en el archivo web.config.

El elemento <httpHandlers> registra la ruta usada por las peticiones de imagen y sonido CAPTCHA para ser procesadas por el código Lanap.BotDetect.dll, mientras que el elemento <sessionState> declara el mecanismo de persistencia usado por BotDetect para mantener los códigos de CAPTCHA y configuraciones para cada usuario.

Puede usar diferentes configuraciones y modos de Estado de Sesión dependiendo de las necesidades de su aplicación, pero tendrá que asegurarse de que la persistencia de Estado de Sesión está disponible para que trabaje BotDetect. También, un cuidado especial debería ser tomado si está corriendo múltiples servidores de carga-balanceada, como es explicado en este item de preguntas frecuentes.

Versiones Actuales de BotDetect

Advertencia

Esta página es una traducción no oficial de la página original: BotDetect CAPTCHA Randomization VB.NET Code Sample y puede estar incompleta, incorrecta o poco actualizada.

Última traducción del 2009-12-18. Esto se aplica para los productos BotDetect ASP.NET CAPTCHA v2.0.15 y BotDetect ASP CAPTCHA v2.0.9.

language: English Español Tiếng Việt