Ejemplo de Código de Aleatorización BotDetect ASP.NET 2.0 CAPTCHA VB.NET
Este ejemplo de BotDetect ASP.NET CAPTCHA sobre aleatorización de 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:\Program Files\Lanapsoft\BotDetect\ASP.NET 2.0\v2.0\Samples\VBNetBotDetect2RandomDemo\.
También lo puede arrancar desde el Menú de Inicio:
Programs > Lanapsoft > BotDetect > ASP.NET 2.0 > v2.0 > Samples > VB.Net BotDetect CAPTCHA Randomization Sample.
Default.aspx
Listado del Código Fuente Completo
<%@ Page Language="VB" AutoEventWireup="false"
CodeFile="Default.aspx.vb" Inherits="_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 Random 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
Imports System.Drawing
Imports Lanap.BotDetect
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Page_Init(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
' clear user input on Reload button clicks
Dim scriptTemplate As String
scriptTemplate = "function LBD_ClearUserInput() {{" & _
" var LBD_textBox = document.getElementById('{0}');" & _
" if(LBD_textBox) {{" & _
" LBD_textBox.value = '';" & _
" }}" & _
"}}" & _
"LBD_RegisterHandler('PreReloadCaptchaImage', _
LBD_ClearUserInput);"
Dim script As String
script = String.Format(scriptTemplate, CodeTextBox.ClientID)
If (Not Page.ClientScript.IsStartupScriptRegistered( _
"CaptchaReloadClearInput")) Then
Page.ClientScript.RegisterStartupScript(Me.GetType(), _
"CaptchaReloadClearInput", script, True)
End If
' automatically lowercase user input
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 randomization 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
If (captcha.CaptchaId <> SampleCaptcha.CaptchaId) Then
Return
End If
' 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."
App_Code\RandomizationHelper.vb
Full Source Code Listing
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 values As Array = _
System.Enum.GetValues(GetType(CodeTypeEnum))
Dim max As Integer = values.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"?>
<!--
Note: As an alternative to hand editing this file you can use the
web admin tool to configure settings for your application. Use
the Website->Asp.Net Configuration option en Visual.
A full list of settings and comments can be found in
machine.config.comments usually located in
\Windows\Microsoft.Net\Framework\v2.x\Config
-->
<configuration>
<connectionStrings/>
<system.web>
<httpHandlers>
<add verb="*" path="LanapCaptcha.aspx"
type="Lanap.BotDetect.CaptchaHandler, Lanap.BotDetect"/>
</httpHandlers>
<sessionState mode="InProc" cookieless="AutoDetect" timeout="20"
sessionIDManagerType="Lanap.BotDetect.Persistence.
CustomSessionIDManager, Lanap.BotDetect" />
<!--
Set compilation debug="true" to insert debugging
symbols into the compiled page. Because this
affects performance, set this value to true only
during development.
-->
<compilation debug="false">
<assemblies>
<add assembly="System.Design, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
</assemblies>
</compilation>
<pages>
<namespaces>
<clear/>
<add namespace="System"/>
<add namespace="System.Collections"/>
<add namespace="System.Collections.Specialized"/>
<add namespace="System.Configuration"/>
<add namespace="System.Text"/>
<add namespace="System.Text.RegularExpressions"/>
<add namespace="System.Web"/>
<add namespace="System.Web.Caching"/>
<add namespace="System.Web.SessionState"/>
<add namespace="System.Web.Security"/>
<add namespace="System.Web.Profile"/>
<add namespace="System.Web.UI"/>
<add namespace="System.Web.UI.WebControls"/>
<add namespace="System.Web.UI.WebControls.WebParts"/>
<add namespace="System.Web.UI.HtmlControls"/>
</namespaces>
</pages>
<!--
The <authentication> section enables configuration
of the security authentication mode used by
ASP.NET to identify an incoming user.
-->
<authentication mode="None"/>
<!--
The <customErrors> section enables configuration
of what to do if/when an unhandled error occurs
during the execution of a request. Specifically,
it enables developers to configure html error pages
to be displayed in place of a error stack trace.
<customErrors mode="RemoteOnly"
defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
-->
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="LanapCaptchaHandler" />
<add name="LanapCaptchaHandler" preCondition="integratedMode"
verb="*" path="LanapCaptcha.aspx"
type="Lanap.BotDetect.CaptchaHandler, Lanap.BotDetect" />
</handlers>
</system.webServer>
</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 2005 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. El elemento <system.webServer> sirve para el mismo propósito, pero es usado sólo por máquinas IIS 7.0 configuradas para integrar la tubería ASP.NET en el proceso IIS.
La declaración validateIntegratedModeConfiguration="false" asegura que el archivo web.config puede ser procesado por versiones anteriores de IIS (5.1, 6.0) así como también por la versión 7.0. Como la sintaxis de registración HttpHandler difiere de los modos de integración de las versiones IIS y ASP.NET, teniendo ambos elementos que hacen el archivo web.config compatible con todas las versiones IIS soportadas.
El elemento <sessionState> declara el mecanismo de persistencia usado por BotDetect para mantener los códigos CAPTCHA y configuraciones para cada usuario. Diferentes modos de Estado de Sesión, proveedores y timeouts pueden ser usados, pero el elemento sessionIDManagerType es requerido para arreglar un bug causado por Windows Media Player 11 cuando pide CAPTCHAs de audio (así como es explicado en item de preguntas frecuentes). 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
- BotDetect ASP.NET CAPTCHA v2.0.152009–11–23
- BotDetect ASP CAPTCHA v2.0.92009–02–12
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.





