capcha webdynpro

Embed Size (px)

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-captchas
  • 7/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.zip
  • 7/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.jpg
  • 7/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.JPG
  • 7/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.jpg
  • 7/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.jpg
  • 7/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.jpg
  • 7/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.htm
  • 7/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=0
  • 7/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.