View
245
Download
1
Category
Preview:
Citation preview
7/27/2019 capcha webdynpro
1/12
Bid adieu to bots - using CAPTCHAs
Posted byBala Krishnaninbalabon 25-Sep-2006 07:01:02
inShare
Motive - A brief note:
First things first, so, what is a CAPTCHA?, you might ask. Most of us would have come across
the band-pass filterlike images when we sign up for a new account atYahoo !.
Yes, you got it right!!!. ACAPTCHA is an automated test that can distinguish between machines
and humans. It can generate and grade tests automatically that virtually accepts all humans and
rejects all machines.
With bots posing severe threat, there are many instances where WebDynpro applications are
exposed to the public for purpose of registration etc,. Under such circumstances, how to retaliate
against the spam robots?. Here comesPassword as graphic picture on a page to entryandAlexis`[Showing up the generated Image |Re: Read Session ID in WD].
During this attempt to solve the security problem, I got a simple yet effective solution forExternal Library(another forum post), as a by-product. Though there exists the possibily to workwith aA bit of (impractical) scripting for Web Dynprofor this dependency problem, it becomes
quite complex (atleast for me) as one would need to work across several DC borders using entity
references. Setting up the platform:
To start with, we need all the required libraries. As JCAPTCHA has built-in references to other
open source libraries, let`s get those libraries as well from the links specified below:
JCAPTCHA
1.2.
Commons Collections
1.
http://scn.sap.com/blogs/balab/2006/09/25/bid-adieu-to-bots--using-captchashttp://scn.sap.com/blogs/balab/2006/09/25/bid-adieu-to-bots--using-captchashttp://scn.sap.com/blogs/balab/2006/09/25/bid-adieu-to-bots--using-captchashttp://scn.sap.com/people/bala.krishnan2http://scn.sap.com/people/bala.krishnan2http://scn.sap.com/people/bala.krishnan2http://scn.sap.com/blogs/balabhttp://scn.sap.com/blogs/balabhttp://scn.sap.com/blogs/balabhttps://edit.yahoo.com/config/eval_register?.intl=us&new=1&.done=https%3A//login.yahoo.com/config/validate%3F.src=flkctx%26.pc=5134%26.done=http%253A%252F%252Fwww.flickr.com%252Fsignin%252Fyahoo%252F&.src=flkctx&.v=0&.u=cltms0l2hffn3&partner=&.partner=&pkg=&stepid=&.p=&promo=&.last=https://edit.yahoo.com/config/eval_register?.intl=us&new=1&.done=https%3A//login.yahoo.com/config/validate%3F.src=flkctx%26.pc=5134%26.done=http%253A%252F%252Fwww.flickr.com%252Fsignin%252Fyahoo%252F&.src=flkctx&.v=0&.u=cltms0l2hffn3&partner=&.partner=&pkg=&stepid=&.p=&promo=&.last=https://edit.yahoo.com/config/eval_register?.intl=us&new=1&.done=https%3A//login.yahoo.com/config/validate%3F.src=flkctx%26.pc=5134%26.done=http%253A%252F%252Fwww.flickr.com%252Fsignin%252Fyahoo%252F&.src=flkctx&.v=0&.u=cltms0l2hffn3&partner=&.partner=&pkg=&stepid=&.p=&promo=&.last=http://en.wikipedia.org/wiki/Captchahttp://en.wikipedia.org/wiki/Captchahttp://en.wikipedia.org/wiki/Captchahttp://scn.sap.com/blogs/balab/2006/09/25/bid-adieu-to-bots--using-captchas/%3EJCAPTCHA%3C/a%3E%20for%20the%20rescue%20and%20this%20blog%20portrays%20the%20simple%20step%20by%20step%20integration%20procedure%20for%20using%20JCAPTCHA%20in%20WebDynpro%20applications.%20In%20addition,%20an%20attempt%20has%20also%20been%20made%20to%20solve%20the%20issues%20raised%20in%20the%20forum%20threads%20%3Ca%20href=http://scn.sap.com/blogs/balab/2006/09/25/bid-adieu-to-bots--using-captchas/%3EJCAPTCHA%3C/a%3E%20for%20the%20rescue%20and%20this%20blog%20portrays%20the%20simple%20step%20by%20step%20integration%20procedure%20for%20using%20JCAPTCHA%20in%20WebDynpro%20applications.%20In%20addition,%20an%20attempt%20has%20also%20been%20made%20to%20solve%20the%20issues%20raised%20in%20the%20forum%20threads%20%3Ca%20href=http://scn.sap.com/blogs/balab/2006/09/25/bid-adieu-to-bots--using-captchas/%3EJCAPTCHA%3C/a%3E%20for%20the%20rescue%20and%20this%20blog%20portrays%20the%20simple%20step%20by%20step%20integration%20procedure%20for%20using%20JCAPTCHA%20in%20WebDynpro%20applications.%20In%20addition,%20an%20attempt%20has%20also%20been%20made%20to%20solve%20the%20issues%20raised%20in%20the%20forum%20threads%20%3Ca%20href=http://scn.sap.com/message/2261592#2261592http://scn.sap.com/message/2261592#2261592http://scn.sap.com/message/2261592#2261592http://scn.sap.com/thread/171469http://scn.sap.com/thread/171469http://scn.sap.com/people/valery.silaev/blog/2005/09/14/a-bit-of-impractical-scripting-for-web-dynprohttp://scn.sap.com/people/valery.silaev/blog/2005/09/14/a-bit-of-impractical-scripting-for-web-dynprohttp://scn.sap.com/people/valery.silaev/blog/2005/09/14/a-bit-of-impractical-scripting-for-web-dynprohttp://optusnet.dl.sourceforge.net/sourceforge/jcaptcha/jcaptcha-bin-1.0-RC3.ziphttp://optusnet.dl.sourceforge.net/sourceforge/jcaptcha/jcaptcha-bin-1.0-RC3.ziphttp://www.uniontransit.com/apache/jakarta/commons/collections/binaries/commons-collections-3.2.ziphttp://www.uniontransit.com/apache/jakarta/commons/collections/binaries/commons-collections-3.2.ziphttp://www.uniontransit.com/apache/jakarta/commons/collections/binaries/commons-collections-3.2.ziphttp://optusnet.dl.sourceforge.net/sourceforge/jcaptcha/jcaptcha-bin-1.0-RC3.ziphttp://scn.sap.com/people/valery.silaev/blog/2005/09/14/a-bit-of-impractical-scripting-for-web-dynprohttp://scn.sap.com/thread/171469http://scn.sap.com/message/2261592#2261592http://scn.sap.com/blogs/balab/2006/09/25/bid-adieu-to-bots--using-captchas/%3EJCAPTCHA%3C/a%3E%20for%20the%20rescue%20and%20this%20blog%20portrays%20the%20simple%20step%20by%20step%20integration%20procedure%20for%20using%20JCAPTCHA%20in%20WebDynpro%20applications.%20In%20addition,%20an%20attempt%20has%20also%20been%20made%20to%20solve%20the%20issues%20raised%20in%20the%20forum%20threads%20%3Ca%20href=http://en.wikipedia.org/wiki/Captchahttps://edit.yahoo.com/config/eval_register?.intl=us&new=1&.done=https%3A//login.yahoo.com/config/validate%3F.src=flkctx%26.pc=5134%26.done=http%253A%252F%252Fwww.flickr.com%252Fsignin%252Fyahoo%252F&.src=flkctx&.v=0&.u=cltms0l2hffn3&partner=&.partner=&pkg=&stepid=&.p=&promo=&.last=http://scn.sap.com/blogs/balabhttp://scn.sap.com/people/bala.krishnan2http://scn.sap.com/blogs/balab/2006/09/25/bid-adieu-to-bots--using-captchas7/27/2019 capcha webdynpro
2/12
2.Commons Betwixt Extract the zip files (available @ links 1,2,3) to get jars commons-betwixt-0.7.jar,jcaptcha-all-1.0-RC3.jar, commons-collections-3.2.jarand commons-collections-
3.2.jar.
Libraries & External Library DC:
In the NWDS, navigate to 'File' --> 'New' --> 'Development Component Project' and choose'Local Development'. Then, select 'My Components' under 'Local Development' and click 'Next'.
You'll get the 'New Development Component' wizard. Fill in the appropriate values (as shown
below) and choose 'External Library' as the DC Type and click 'Finish' to create a new Library
DC project.
Add the aforementionedjarfiles to this Library DC by simply copying and pasting them to the
'libraries' folder of the project.
http://apache.adult-pilot.net/jakarta/commons/betwixt/binaries/commons-betwixt-0.7.ziphttp://scn.sap.com/servlet/JiveServlet/showImage/38-42422-45617/CopyofExtLibDC.JPGhttp://apache.adult-pilot.net/jakarta/commons/betwixt/binaries/commons-betwixt-0.7.zip7/27/2019 capcha webdynpro
3/12
Public Part declaration:
This is the an important step where in we define two public parts (with the same contents
libraries), with one of type 'Compilation' and the other of type 'Assembly' (In other words, one
for Build-Time and another for Runtime). So, first, select one of the newly added jar files (underthe Library Project --> 'libraries' folder) say, commons-betwixt-0.7.jarand right click to choose
'Development Component' --> 'Add to Public Part' from the context menu.
http://scn.sap.com/servlet/JiveServlet/showImage/38-42422-45618/AddLibs.jpg7/27/2019 capcha webdynpro
4/12
PP - Compilation:
In the 'Add Public Part' wizard, specify a valid name (see to it that the option 'Provides an API
for developing/compiling other DCs' is checked!) and click 'Finish' to create a public part of
type 'Compilation'.
http://scn.sap.com/servlet/JiveServlet/showImage/38-42422-45619/AddPP.JPG7/27/2019 capcha webdynpro
5/12
PP - Assembly:
Now, right click the same jar file commons-betwixt-0.7.jar, and choose 'DevelopmentComponent' --> 'Add to Public Part'. In the 'Pulic Part Editor' window, click 'New' to create a
new public part of type 'Assembly' by selecting the option 'Can be packaged into other build
results (e.g. SDAs)'.
http://scn.sap.com/servlet/JiveServlet/showImage/38-42422-45620/PP1.jpg7/27/2019 capcha webdynpro
6/12
Similarly, add the other three jar files to the same public parts by repeating the following steps
seperately for each jar file:
1.2. Right click the jar and select 'Development Component' --> 'Add to Public Part' -->ExternalLibCompilation3.4. Right click the same jar and select 'Development Component' --> 'Add to Public Part' -->
ExternalLibAssembly5.
Finally do a DC build by choosing 'Development Component' --> 'Build' in the right click
context menu of the Library project. Now the public parts are ready with us and we may proceed
further to see how these libraries (contained in the public parts) could be accessed from a WD
DC.
WebDynpro DC & DC usage relations:
Create a WebDynpro DC (by following the same steps mentioned for External Library creation,
except that the DC Type should be chosen as 'WebDynpro') and add both the External Library
http://scn.sap.com/servlet/JiveServlet/showImage/38-42422-45621/PP2.jpg7/27/2019 capcha webdynpro
7/12
public parts to the WD DC as used DCs. Care must be taken to ensure that only the 'Build Time'
dependency is established. Hint: One need not manipulate the dependency types as we already
have two pulic parts: one each for 'Runtime' and 'Build Time'. Here are the steps to add the DCusage relations.
Choose 'DC Metadata' under your WD DC and navigate to 'DC Definition' --> 'Used DCs'. Rightclick 'Used DCs' to add the DC usage relations. In the 'Add Dependency' wizard, choose 'LocalDevelopment' --> 'My Components' --> 'jcaptcha/jars' --> 'Public Parts'. Select both the pulic
parts ExternalLibCompilation and ExternalLibAssembly and check the dependency type
'Build Time', and click 'Finish'.
Finally, 'Build' the WD DC, so that all the declared dependency relationships gets well
established. Thus far we've seen the approach for solving the problems related to the usage ofExternal Library DCs.
http://scn.sap.com/servlet/JiveServlet/showImage/38-42422-45624/DCUsage.jpghttp://scn.sap.com/servlet/JiveServlet/showImage/38-42422-45623/CopyofDCUsage.jpghttp://scn.sap.com/servlet/JiveServlet/showImage/38-42422-45622/TopDCUsage.jpg7/27/2019 capcha webdynpro
8/12
Caveat confector:
One should always remember this significant and valid point: 'Use ONLY DC Builds to create
the deployable archive if you work with assembly public parts. '. Let me explain this clearly.
We have added a public part of type 'Assembly' to the WD DC and hence, the local create
archive options are not supported. So, never use the function 'Create archive' or 'Deploy newarchive and run' while working with 'Assembly' type public parts. Instead, always use the DC'Build', after that DC 'Deploy' and then simply 'Run' the WD application.
Implementing JCAPTCHA/WD Application
Having discussed in detail, the procedure for invoking JCAPTCHA libraries from the WD DC,
let`s dive into the actual application itself. Developing the application is very simple. In the
WebDynpro perspective, switch to the 'Navigator' tab. Select the WD project and go to the folder'src' to create a new logical folder structure 'com.jcaptcha.util'. Add a new java class
'CaptchaServiceSingleton.java' under that and add the following code to it for instantiating a
singleton captcha service.
public class CaptchaServiceSingleton
{
/* Instantiate a Singleton CaptchaService */
private static ImageCaptchaService instance = new
DefaultManageableImageCaptchaService();
public static ImageCaptchaService getInstance()
{
return instance;
}
}
Go back to 'WebDynpro Explorer' to create a Label, (for specifying a short text) Inputfield, (totake the user perceived input based on the CAPTCHA), an Image UI element (for displaying the
generated image) and a Button (for verifying the CAPTCHA) in the view. Add a method
called createCaptcha() and invoke it from the wdDoInit() of the view.
Code for createCaptcha() /* Specify a Captcha ID that will identify the generated
1. captcha. Note that same Captcha ID must be used to1. validate the response as well .1. So, the request hashcode is a good candidate!.1. As an alternative, the standard java 'Random.nextLong()'
7/27/2019 capcha webdynpro
9/12
1. can also be used as the Captcha ID.*/
wdContext.currentContextElement().setCaptchaID( WDProtocolAdapter.getProtocolAdapter().
getRequestObject().hashCode()+ "");
/* Get the challenge for the specified ID */ BufferedImage image =
CaptchaServiceSingleton.getInstance().getImageChallengeForID(
wdContext.currentContextElement().getCaptchaID(),WDClientUser.getLoggedInClientUser().getLocale());
/* Create a new file for storing the image */ File outFile = new File(wdContext.currentContextElement().getCaptchaID() + ".jpg"); try {
/* Write the image to the created file */ ImageIO.write( image,
"jpg",outFile); } catch (IOExceptione) { wdComponentAPI.getMessageManager().reportException(e.getLocalizedMe
ssage(), true); }
/* Get the URL for the generated image */ String fileURL ="http://localhost:53000/" + "jcaptcha/resources/" +
wdContext.currentContextElement().getCaptchaID() + ".jpg";
/* Instead of using hardcoded values for the hostname and
1.
port, you may use the WebDynpro service TaskBinder
1. to get the hostname and the port*/
http://localhost:53000/http://localhost:53000/http://localhost:53000/7/27/2019 capcha webdynpro
10/12
/* Set the image URL to the attribute bound to the image UI element.
*/ wdContext.currentContextElement().setEncryptedImage(fileURL);
How to retrieve the generated image?:
Everything in the code looks pretty straight forward except for one point. +Why should the
image be retrieved using a URL instead of using a plain Image name (outFile.getName()) ?. Theanswer is simple and I guess all of us know that. By default, WD Runtime does a look-up for the
specified 'Image' in the folder
'../../../resources///Components//', whereasthe CAPTCHA image gets generated under the root folder '+'. Then, how to access the images?.
Solution: 'UseHTTP Alias '. One may referCreating an HTTP Alias in WASfor creating the
alias (with Alias Name = '' ) used in the code above.
CAPTCHA verification:
'How to check if the user perceived input matches with the generated CAPTCHA?'. You
can validate the input, by having the following code in the action handler associated with theButton.
public void onActionverify(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent
http://help.sap.com/saphelp_nw04/helpdata/en/ee/0618d0899001408d821096c85ff8a2/frameset.htmhttp://help.sap.com/saphelp_nw04/helpdata/en/ee/0618d0899001408d821096c85ff8a2/frameset.htmhttp://help.sap.com/saphelp_nw04/helpdata/en/ee/0618d0899001408d821096c85ff8a2/frameset.htmhttp://scn.sap.com/people/renjith.andrews/blog/2005/03/31/creating-an-http-alias-in-washttp://scn.sap.com/people/renjith.andrews/blog/2005/03/31/creating-an-http-alias-in-washttp://scn.sap.com/people/renjith.andrews/blog/2005/03/31/creating-an-http-alias-in-washttp://scn.sap.com/servlet/JiveServlet/showImage/38-42422-45625/Output.jpghttp://scn.sap.com/people/renjith.andrews/blog/2005/03/31/creating-an-http-alias-in-washttp://help.sap.com/saphelp_nw04/helpdata/en/ee/0618d0899001408d821096c85ff8a2/frameset.htm7/27/2019 capcha webdynpro
11/12
) { //@@begin onActionverify(ServerEvent) /* Get the User Input code from the input field
*/ String userResponse = wdContext.currentContextElement().getEnteredText();
try { /* Call the service method to check if the user input
1. matches the generated code. Remember that for validation,1. we need to use the same Captcha ID (that we specified1. during Captcha creation)
*/ Boolean validate =
CaptchaServiceSingleton.getInstance().validateResponseForID(wdContext.currentContextEleme
nt().getCaptchaID(),userResponse); if(validate.booleanValue()) {
wdComponentAPI.getMessageManager().reportException("Entered code is correct !!!",true); } else { wdComponentAPI.getMessageManager().
reportException("Entered code is Invalid. Please enter the correct code", true);
/* Blank out the input field
*/ wdContext.currentContextElement().setEnteredText("");
/* If the entered code is wrong, generate a newCaptcha*/ createCaptcha(); } } catch (Exception
e) { wdComponentAPI.getMessageManager().raiseException(e.getLocalizedMes
sage(), true); } //@@end }
!https://weblogs.sdn.sap.com/weblogs/images/62531/Error.jpg|height=325|alt=image|width=438|
src=https://weblogs.sdn.sap.com/weblogs/images/62531/Error.jpg|border=0!
Points to be noted in CAPTCHA generation principles:
A new CAPTCHA has to be generated after every validation. i.e, let`s assume that the user
entered code doesn't match the generated code, then, for the immediately next validation session,we can't use/show the same image, as CAPTCHA is destroyed after first validation. An
exception (CaptchaServiceException) is thrown when the provided ID is no longer valid (non-
existant/ destroyed/expired CAPCTHA). So, in such cases, there is no way to retrieve theresponse back from the CAPTCHA, as this is the way the JCAPTCHA core security feature has
been designed.
public Boolean validateResponseForID(String ID, Object response)throws
https://weblogs.sdn.sap.com/weblogs/images/62531/Error.jpg%7Cheight=325%7Calt=image%7Cwidth=438%7Csrc=https:/weblogs.sdn.sap.com/weblogs/images/62531/Error.jpg%7Cborder=0https://weblogs.sdn.sap.com/weblogs/images/62531/Error.jpg%7Cheight=325%7Calt=image%7Cwidth=438%7Csrc=https:/weblogs.sdn.sap.com/weblogs/images/62531/Error.jpg%7Cborder=0https://weblogs.sdn.sap.com/weblogs/images/62531/Error.jpg%7Cheight=325%7Calt=image%7Cwidth=438%7Csrc=https:/weblogs.sdn.sap.com/weblogs/images/62531/Error.jpg%7Cborder=0https://weblogs.sdn.sap.com/weblogs/images/62531/Error.jpg%7Cheight=325%7Calt=image%7Cwidth=438%7Csrc=https:/weblogs.sdn.sap.com/weblogs/images/62531/Error.jpg%7Cborder=0https://weblogs.sdn.sap.com/weblogs/images/62531/Error.jpg%7Cheight=325%7Calt=image%7Cwidth=438%7Csrc=https:/weblogs.sdn.sap.com/weblogs/images/62531/Error.jpg%7Cborder=0https://weblogs.sdn.sap.com/weblogs/images/62531/Error.jpg%7Cheight=325%7Calt=image%7Cwidth=438%7Csrc=https:/weblogs.sdn.sap.com/weblogs/images/62531/Error.jpg%7Cborder=07/27/2019 capcha webdynpro
12/12
CaptchaServiceException
{
if (!store.hasCaptcha(ID))
{
throw new CaptchaServiceException("Invalid ID, could not validate!");
}
else
{
Boolean valid = store.getCaptcha(ID).validateResponse(response);
store.removeCaptcha(ID);return valid;
}
}
Further, there is a small pitfall in the CAPTCHA verification rules. The method
validateResponseForID(String, Object) returns a case in-sensitive result, i.e, it treats both theLowerCase/UpperCase input character codes as one and the same.
Recommended