Wednesday Mar 17, 2010

Custom Validators in Metro Web Services Security

Although its simple to implement, here are the steps to implement plain text username/password validator for your web services security using Netbeans 6.8  and Glassfishv3 for those who were unable to get this work.
  1.  Create a new Netbeans Web Application project as shown and select the target server and click Finish.


  2. Right click on the project just created and then New --> Web Service, Enter web service name and package information and then click on Finish button.
  3. Click on Design tab of the web service and then in the GUI click on  Advanced  button to view QoS window .
  4. Select check box with name Secure Service and select User name Authentication with Symmetric Key as Security mechanism .Also select Use Development defaults.Click on ok.
  5. Now create your validator using new class wizard which extends PasswordValidationCallback.DerivedKeyPasswordValidator class.
  6. Goto Web pages and then WEB-INF folder and then open your webservice config file.This would be the file with naming pattern - wsit-<packagename>.<webservicename>.xml
  7. Locate the keystore configuration section in the wsit config file and add the below lines and save it.

    <sc:ValidatorConfiguration wspp:visibility="private">
                        <sc:Validator name="usernameValidator" classname="simple.server.SimpleValidator"/>
                    </sc:ValidatorConfiguration>
  8. Now deploy the application.
  9. Now create a client app using new webapplication wizard similar to step 1  
  10. Now create a webservice client --> check the Project radio button -->Click on Browse and select the webservice which we created earlier and click on Finish .
  11. Traverse to Webservice reference section in your client app and then open Webservice reference folder and then right click on the webservice and then select Edit Webservice attributes .
  12. Under security section , select the check box, use development defaults and click ok.
  13. Now goto Source packages in the Client project and then open the client wsit config file.Here PingWebServiceservice.xml and modify the section

     <sc:CallbackHandlerConfiguration wspp:visibility="private">
                        <sc:CallbackHandler default="wsitUser" name="usernameHandler"/>
                        <sc:CallbackHandler default="changeit" name="passwordHandler"/>
                    </sc:CallbackHandlerConfiguration>

    to use your username and password like:


     <sc:CallbackHandlerConfiguration wspp:visibility="private">
                        <sc:CallbackHandler default="sreekanth" name="usernameHandler"/>
                        <sc:CallbackHandler default="sreekanth" name="passwordHandler"/>
                    </sc:CallbackHandlerConfiguration>

  14. Now create a servlet program to test the webservice
  15. Modify the servlet code to call the webservice.(webservice can be called using the keyboard shortcut: alt+insert->Call Webservice operation and then select the web service operation in the popup window as appropraite)
  16. Now deploy your client app and run.In the attached client project , the servlet is called with the url http://localhost:8080/CustomValidatorClient/TestServlet
  17. Check to see if your Validator is called.

References/Resources:

  1. To know about how validators work refer to section "Configuration for Plain-Text Username/Password Validation " in this blog and "Configuring Validators " in this article.
  2. Sample Netbeans server and client application that is created for the demo purpose can be downloaded  from here.





Thursday Dec 10, 2009

Configuring Keystore dynamically in WebServices using Metro

    In most secure webservice scenarios we configure keystore using the keystore confuguration tag in the service policy file.But at times we may want to configure the keystore dynamically at run time as to which keystore to use basing on some condition.
In such cases we can use another variant of keystore configuration where we can specify the callback handler that can be used to select and load the keystore.

<sc:Keystore
   alias={the certificate alias from the  keystore to be used for Signatures}
   aliasSelector={the fully qualified classname of a class implementing com.sun.xml.wss.AliasSelector interface}?
   callbackHandler={fully qualified classname of a class implementing javax.security.auth.callback.CallbackHandler, should be able to handle  com.sun.xml.wss.impl.callback.KeyStoreCallback and  com.sun.xml.wss.impl.callback.PrivateKeyCallback}
/>

For more information refer to Dynamic KeyStore configuration section in Kumar's blog.

Here is a short description of such as case.

   1. Create a simple webservice using Netbeans.
   2. Now configure it to be a secure service.If you aren't aware of how to configure webservice security , refer to metro guide.Here I configured the service to use UserName authentication with Symmetric Key.
   3. Now open the service policy file and try to find the Keystore configuration tag:(similar to the one below)

<sc:KeyStore wspp:visibility="private" location="/space/Sreekanth/servers/glassfishv3/glassfish/domains/domain1 /config/keystore.jks" type="JKS" storepass="changeit" alias="xws-security-server"/>

   4. Now modify that keystore configuration to use "callbackhandler" attribute as below:
<sc:KeyStore wspp:visibility="private" type="JKS"   alias="bob" callbackHandler="simple.server.MyKeyStoreCallbackHandler"/>
   5. Write your own CallbackHandler to handle KeystoreCallback and PrivateKey call back.This is how handle() method of my callbackhandler looks like:

public class MyKeyStoreCallbackHandler implements CallbackHandler {

...

       public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

        for (Callback callback : callbacks) {

            if (callback instanceof KeyStoreCallback) {

                java.io.FileInputStream fis = null;

                try {

                    keystore = KeyStore.getInstance(KeyStore.getDefaultType());

                    String AS_HOME = System.getProperty("com.sun.aas.installRoot");

                    System.out.println("AS_HOme..." + AS_HOME);

                    fis = new java.io.FileInputStream(AS_HOME + "/xws-security/etc/server-keystore.jks");

                    keystore.load(fis, "changeit".toCharArray());

                    System.out.println("Keystore loaded..");

                    ((KeyStoreCallback) callback).setKeystore(keystore);

                } catch (NoSuchAlgorithmException nsae) {

                    System.out.println("Exception : " + nsae.getMessage());

                    nsae.printStackTrace();

                } catch (KeyStoreException kse) {

                    System.out.println("Exception : " + kse.getMessage());

                    kse.printStackTrace();

                } catch (CertificateException ce) {

                    System.out.println("Exception : " + ce.getMessage());

                    ce.printStackTrace();

                } finally {

                    if (fis != null) {

                        fis.close();

                    }

                }

            } else if (callback instanceof PrivateKeyCallback) {

               PrivateKey privateKey = null;

                Properties properties = new Properties();

                this.keyStorePassword = properties.getProperty("keystore.password");

                Certificate certs[] = null;

                try {

                    privateKey = (PrivateKey) keystore.getKey("bob", "changeit".toCharArray());

                    certs = keystore.getCertificateChain("bob");

                } catch (KeyStoreException ex) {

                    System.out.println("KeyStoreException : " + ex.getMessage());

                    ex.printStackTrace();

                } catch (NoSuchAlgorithmException nsae) {

                    System.out.println("NoSuchAlgorithmException : " + nsae.getMessage());

                    nsae.printStackTrace();

                } catch (UnrecoverableKeyException uke) {

                    System.out.println("UnrecoverableKeyException : " + uke.getMessage());

                    uke.printStackTrace();

                }          

                ((PrivateKeyCallback) callback).setKey(privateKey);

                System.out.println("Private Key callback Handled...");

            }

        }

}
   6. Now deploy your service
   7. Create a sample webservice client and invoke the client.
   8. Now you see the keystore is loaded from the callback handler we wrote.
   9. If you deploy a jsr109 webservice, then metro will try to search for the default keystores in glassfish server.Try using non 109 app.





Thursday Nov 05, 2009

Servlet [ActivationCoordinatorPortTypeImpl] and Servlet [RegistrationPortTypeImpl] have the same url pattern

Last Friday while I was creating a web service client application using Glassfish V3 and Netbeans 6.8, I had come across this problem/exception.

SEVERE: Servlet [CoordinatorPortTypeImpl] and Servlet [CompletionCoordinatorPortTypeImpl] have the same url pattern: [/WSATCoordinator]
SEVERE: Exception while deploying the app
java.lang.IllegalStateException: Servlet [CoordinatorPortTypeImpl] and Servlet
[CompletionCoordinatorPortTypeImpl] have the same url pattern:
[/WSATCoordinator]at org.glassfish.apf.AnnotationInfo@15c9b76
       at
com.sun.enterprise.deployment.archivist.Archivist.readAnnotations(Archivist.java:478)
       at
com.sun.enterprise.deployment.archivist.Archivist.readAnnotations(Archivist.java:420)
       at
com.sun.enterprise.deployment.archivist.WebArchivist.postAnnotationProcess(WebArchivist.java:309)
       at
com.sun.enterprise.deployment.archivist.WebArchivist.postAnnotationProcess(WebArchivist.java:81)
       at
com.sun.enterprise.deployment.archivist.Archivist.readRestDeploymentDescriptors(Archivist.java:397)
       at
com.sun.enterprise.deployment.archivist.Archivist.readDeploymentDescriptors(Archivist.java:373)
       at com.sun.enterprise.deployment.archivist.Archivist.open(Archivist.java:238)
       at com.sun.enterprise.deployment.archivist.Archivist.open(Archivist.java:247)
       at com.sun.enterprise.deployment.archivist.Archivist.open(Archivist.java:208)
       at
com.sun.enterprise.deployment.archivist.ApplicationFactory.openArchive(ApplicationFactory.java:148)
       at ...

Actually I wanted to use some subclass of WebServiceFeature in my client program,but netbeans wrongly imported internal api classes instead of actual classes like com.sun.xml.internal.ws.developer.BindingTypeFeature instead of com.sun.xml.ws.developer.BindingTypeFeature.(This was due to metro has apis that are not in api package, nor are separated from the big implementation bundle)

So  I started renaming the wrongly imported classes to actual classes,but Netbeans editor showed classpath problems. So in order to overcome the problem, I added webservices-osgi.jar to netbeans clients projects compile time  libraries.Then when I tried to deploy the application, GF V3 throwed the above exception.

I reported this to Fabian and he told me this problem was because we have the WS-AT servlet code in webservices-osgi.jar and that is clashing with the WS-AT servlet that already comes with glassfish and this may be resolved in the next releases of Metro.

So for now the workaround is to add webservices-osgi.jar to the projects compile time libraries with out packaging them to the final war file that we deploy as shown below.

Note: The package check box is not selected .

Even then if problem persists , clean your project and then run.

Wednesday Nov 04, 2009

Performance Testing for Web Services

If you are working on a project and you have some web services involved in your application, at some stage during your project time frame , you may want to see how they perform.

Here is a link I just found and want to share with others who would like to do some  performance testing for  their web services.I haven't completely gone through it, but will check it once I get some time later today.




About

This is my personal blog.All the information here reflects my own thoughts and feelings and should not be taken as official information from Oracle.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today