Mã nguồn ví dụ mẫu BotDetect ASP.NET 2.0 CAPTCHA - VB.NET
Ví dụ mẫu sinh ngẫu nhiên BotDetect ASP.NET CAPTCHA cho bạn thấy việc sinh ngẫu nhiên các tham số của Captcha dễ dàng như thế nào, việc này làm tăng đáng kể tính bảo mật của CAPTCHA và đây là cách tốt nhất để tận dụng hết 50 giải thuật khác nhau của BotDetect.
Vị trí dự án mẫu
Mặc định, dự án mẫu này được cài đặt tại
C:\Program Files\Lanapsoft\BotDetect\ASP.NET 2.0\v2.0\Samples\VBNetBotDetect2RandomDemo\.
Bạn cũng có thể chạy nó từ Start Menu:
Programs > Lanapsoft > BotDetect > ASP.NET 2.0 > v2.0 > Samples > VB.NET BotDetect CAPTCHA Randomization Sample.
Default.aspx
Mã nguồn đầy đủ
<%@ 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>
Giải thích
Những dòng cần thiết để thêm BotDetect CAPTCHA vào trang ASP.NET được tô đậm. Để sử dụng <BotDetect:Captcha>, trước hết chúng ta phải đăng ký Lanap.BotDetect.dll sử dụng <%@Register %>.
Trang web còn chứa <asp:TextBox> để người dùng nhập câu trả lời, một <asp:Button> để gửi câu trả lời, và một cặp <asp:Label> dùng để hiển thị kết quả xác thực. Phần còn lại của file được sinh ra bởi Visual Studio 2005, hoặc dùng để định nghĩa cách thức sắp xếp và hiển thị của trang.
Không có sự khác biệt nào giữa file .aspx của ví dụ này với file cơ bản, vì tất cả việc sinh ngẫu nhiên đều được thực hiện ở mã xử lý trang.
Default.aspx.vb
Mã nguồn đầy đủ
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
Giải thích
Trong quá trình Page_Init của trang ASP.NET, chúng ta đăng ký một phương thức xử lý sự kiện đặc biệt được thực thi trước mỗi lần hiển thị hình ảnh CAPTCHA, trong phương thức này chúng ta thực hiện việc sinh ngẫu nhiên. Vì các hình ảnh CAPTCHA được sinh ra và gửi tới máy khách trong một yêu cầu Http tách biệt khỏi yêu cầu tải trang ASP.NET (khi mã này được thực thi), chúng ta thêm phương thức xử lý sự kiện để đảm bảo các tham số của CAPTCHA được sinh ngẫu nhiên mỗi khi nó được vẽ, và không chỉ một lần khi trang được tải.
Điều này là quan trọng vì số lần yêu cầu hình ảnh CAPTCHA không nhất thiết phải bằng số lần tải trang - dễ thấy nhất là khi sử dụng nút Reload CAPTCHA, và khi bots truy cập trực tiếp vào hình ảnh CAPTCHA, hình ảnh CAPTCHA có thể được sinh ra chỉ sau một lần tải của trang (và thực thi hàm Page_PreRender tương ứng).
Trong phương thức Captcha_PreDrawCaptchaImage, đối tượng Captcha được truyền qua tham số sender. Để việc sinh ngẫu nhiên được thực hiện dễ dàng, chúng ta sử dụng lớp RandomizationHelper, cho phép chúng ta lấy giá trị ngẫu nhiên của một tham số cho trước từ một tập hợp các giá trị cho trước (ví dụ như CAPTCHA CodeType), hoặc một khoảng các giá trị (ví dụ như CAPTCHA CodeLength), hay từ một tập các giá trị (như CAPTCHA TextStyle).
Bạn cũng có thể sinh ngẫu nhiên các thông số khác của CAPTCHA với cách tương tự, nhưng giải thuật vẽ CAPTCHA và chiều dài ký tự CAPTCHA sẽ tăng tính bảo mật của CAPTCHA nhiều nhất khi chúng được sinh ngẫu nhiên. Mỗi giải thuật CAPTCHA riêng rẽ có thể bị bẻ gãy (nếu dành đủ công sức), nhưng nếu bot còn phải phân biệt từng giải thuật trong từng ảnh, nhiệm vụ sẽ khó khăn hơn gấp bội. Hơn nữa, nhiều giải thuật CAPTCHA phổ biến đã bị bẻ gãy vì nó dùng chiều dài ký tự cố định – "tìm 5 ký tự trong hình này" thì dễ hơn rất nhiều so với "tìm một số ký tự chưa biết trong hình này".
App_Code\RandomizationHelper.vb
Mã nguồn đầy đủ
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
Giải thích
RandomizationHelper là một lớp tiện ích nhỏ bạn có thể sử dụng trong dự án của bạn để đơn giản hoá việc sinh ngẫu nhiên nhiều tham số khác nhau của CAPTCHA.
Các tham số CAPTCHA lấy các giá trị là số hoặc tập hợp, lớp này cung cấp phương thức trả về giá trị ngẫu nhiên. Mỗi tham số có một giá trị mặc định, và các tham số dạng số có giá trị nhỏ nhất và lớn nhất được định nghĩa trước.
Tất cả các phương thức sinh ngẫu nhiên dùng nhiều tham số khác nhau, thông qua phương thức overloads hoặc từ khoá params.
Phương thức trả về giá trị số (ví dụ, CodeLength) hoạt động như sau:
- Nếu không có tham số nào được truyền, giá trị ngẫu nhiên được chọn giữa giá trị nhỏ nhất và giá trị lớn nhất định nghĩa trước.
- Nếu một giá trị được truyền, giá trị ngẫu nhiên được chọn giữa giá trị nhỏ nhất định nghĩa trước và giá trị truyền vào như là giá trị lớn nhất. Chú ý rằng giá trị truyền vào phải nhỏ hơn giá trị lớn nhất được định nghĩa trước.
- If two values are given as parameters, the random value is selected between the first value as the minimum and the second value as the maximum. Chú ý rằng giá trị nhỏ nhất được truyền vào phải lớn hơn giá trị nhỏ nhất được định nghĩa trước, và giá trị lớn nhất truyền vào phải nhỏ hơn giá trị lớn nhất được định nghĩa trước.
Phương thức trả về giá trị trong tập hợp (ví dụ, CodeType) hoạt động như sau:
- Nếu không có tham số nào được truyền, giá trị ngẫu nhiên được chọn từ các giá trị có thể.
- Nếu một giá trị được truyền, nó được trả về như là kết quả - khi bạn truyền vào một giá trị thì sẽ không có sự ngẫu nhiên hoá nào cả. Và nếu bạn muốn dùng một giá trị thì chỉ việc gán trực tiếp vào tham số.
- Nếu một tập hợp (ví dụ như mảng) các giá trị được truyền, giá trị ngẫu nhiên được chọn trong tập hợp đó.
Dĩ nhiên là bạn có thể sử dụng mã này trực tiếp trong dự án của bạn nhưng đóng gói nó trong lớp RandomizationHelper làm việc đọc mã nguồn dễ dàng hơn và tăng tính tái sử dụng.
Web.config
Mã nguồn đầy đủ
<?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 in Visual Studio.
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>
Giải thích
Những dòng cần thiết để BotDetect CAPTCHA hoạt động đúng được tô đậm, những dòng khác là giá trị chuẩn được sinh ra bởi Visual Studio 2005. Không có thiết lập đặc biệt nào liên quan đến sinh ngẫu nhiên CAPTCHA trong file web.config.
Thành tố <httpHandlers> đăng ký đường dẫn sử dụng cho hình ảnh và âm thanh CAPTCHA được xử lý bởi Lanap.BotDetect.dll code. Thành tố <system.webServer> được sử dụng với cùng mục đích, nhưng chỉ được sử dụng cho IIS 7.0.
Khai báo validateIntegratedModeConfiguration="false" đảm bảo rằng file web.config có thể được xử lý bởi phiên bản cũ hơn của IIS (5.1, 6.0) cũng như phiên bản 7.0. Vì cú pháp đăng ký HttpHandler khác nhau giữa các phiên bản IIS và chế độ tích hợp ASP.NET, dùng cả hai thành tố trên giúp cho file web.config tương thích với tất cả các phiên bản IIS được hỗ trợ.
Thành tố <sessionState> khai báo cơ chế lưu trữ được sử dụng bởi BotDetect để lưu mã CAPTCHA và thiết lập cho mỗi người dùng. Thuộc tính Session State modes, providers, timeouts và cookieless attribute có thể được sử dụng, nhưng thành tố sessionIDManagerType được sử dụng để sửa lỗi gây bởi Windows Media Player 11 khi yêu cầu âm thanh CAPTCHAs (như được giải thích trong mục hỏi đáp).
Phiên bản hiện tại của BotDetect
- BotDetect ASP.NET CAPTCHA v2.0.152009–11–23
- BotDetect ASP CAPTCHA v2.0.92009–02–12
Xin lưu ý
Trang này là bản dịch tiếng Việt không chính thức của trang gốc tiếng Anh: BotDetect ASP.NET 2.0 CAPTCHA Randomization VB.NET Code Sample và có thể không chính xác, không đầy đủ hoặc không cập nhật.
Cập nhật ngày 2009-11-30. Áp dụng cho BotDetect ASP.NET CAPTCHA v2.0.15 và BotDetect ASP CAPTCHA v2.0.9.





