SECURISER GLASSFISH AVEC SSL

1)	Configuring Keystores
This section describes configuring keystores and truststores. Security mechanisms that use certificates require keystore and truststore files for deployment. 
For GlassFish, default keystore and truststore files come bundled, however WSIT security mechanisms for message security require X.509 version 3 certificates. GlassFish contains version 1 certificates, therefore, to enable the WSIT applications to run on GlassFish, you will need to follow the instructions in Updating GlassFish Certificates.
The following sections discuss how to specify and configure the keystore, truststore, and validators. 
Updating GlassFish Certificates
The WSIT message security mechanisms require the use of v3 certificates. The default GlassFish keystore and truststore do not contain v3 certificates at this time (but should before FCS). (GlassFish instances installed using JDK 1.6 do have a v3 certificate but the certificate lacks a particular extension required for supporting some secure WSIT mechanisms.) In order to use message security mechanisms with GlassFish, it is necessary to download keystore and truststore files that contain v3 certificates and import the appropriate certificates into the default GlassFish stores. 
To update the GlassFish certificates, follow these steps. 
1.	Download the zip file that contains the certificates and the Ant scripts (copyv3.zip) by going to this URL: https://xwss.dev.java.net/servlets/ProjectDocumentList?folderID=6645&expandFolder=6645&folderID=6645.
2.	Unzip this file and change into its directory, copyv3.
3.	Verify that an environment variable named AS_HOME is created, and that it specifies the full path to the location of your GlassFish installation, for example, C:\Program Files\glassfish-v2ur1.
NOTE: Some releases of GlassFish may have different default passwords for the keystores. If you are using a different version of GlassFish than the one recommended at wsit.dev.java.net, edit the file build.xml and specify the correct default password in the AS_KEYSTORE_PASSWORD field. 
4.	From the copyv3 directory, execute the Ant command that will copy the keystore and truststore files to the appropriate location, and import the appropriate certificates into the GlassFish keystore and truststore. This Ant command is simply: <AS_HOME>/lib/ant/bin/ant 
The command window will echo back the certificates that are being added to the keystore and truststore files, and should look something like this: 
[echo] WARNING: currently we add non-CA certs to GF truststore, this will not be required in later releases when we WSIT starts supporting CertStore(s)
[java] Added Key Entry :xws-security-server
[java] Added Key Entry :xws-security-client
[java] Added Trusted Entry :xwss-certificate-authority
[java] Added Key Entry :wssip
[java] Added Trusted Entry :xws-security-client
[java] Added Trusted Entry :xws-security-server
[java] Added Trusted Entry :wssip
[echo] Adding JVM Option for https outbound alias, this will take atleast One Minute.
... 
Specifying Aliases with the Updated Stores 
The configuration of the aliases for all containers (Tomcat, GlassFish) and for all applications (JSR-109-compliant and non-JSR-109-compliant), except for applications that use a Security Token Service (STS) mechanism, is as shown in Table 6-3:
Table 6-3 Keystore and Truststore Aliases   	
  	Keystore Alias 	Truststore Alias 	
Client-Side 
Configuration 	xws-security-client 	xws-security-server 	
Server-Side 
Configuration 	xws-security-server	xws-security-client 	
The configuration of the aliases for applications that use a Security Token Service (STS) mechanism is as shown in Table 6-4:
Table 6-4 Keystore and Truststore Aliases for STS  	
  	Keystore Alias 	Truststore Alias 	
Client-Side 
Configuration 	xws-security-client 	xws-security-server 	
STS 
Configuration 	xws-security-client 	wssip 	

Add a Keystore
NetBeans IDE already knows the location of the default keystore file and its password, but you need to specify which alias is to be used. The following sections discuss configuring the keystore on the service and on the client. 
Configuring the Keystore on a Service 
A keystore is a database of private keys and their associated X.509 certificate chains authenticating the corresponding public keys. A key is a piece of information that controls the operation of a cryptographic algorithm. For example, in encryption, a key specifies the particular transformation of plaintext into ciphertext, or vice versa during decryption. Keys are used in digital signatures for authentication. 
To configure a keystore on a service, perform the following steps: 
1.	Go to Tools and then select Keystores
2.	Add Keystore
3.	Add excting Keystore and enter this path <AS_HOME>/domains/domain1/config/keystore.jks. 
o	Keystore Password--Specifies the password for the keystore file. If you are running under GlassFish, GlassFish's password is already entered. If you have changed the keystore's password from the default, you must specify the correct value in this field.
o	Load Aliases--Click the Load Aliases button to populate the Alias field with the aliases contained in the keystore file. The Location and Store Password fields must be specified correctly for this option to work.
o	Alias--Specifies the alias of the certificate in the specified keystore to be used for authentication. Refer to the table in Specifying Aliases with the Updated Stores to determine which alias to choose for the selected security mechanism.
o	Key Password--Specifies the password of the key within the keystore. For this sample, leave this blank. For this field, the default assumes the key password is the same as the store password, so you only need to specify this field when the key password is different.

2)	Adding Users to GlassFish Using Admin Console 
To add users to GlassFish using the Admin Console, follow these steps: 
Start GlassFish if you haven't already done so.
Start the Admin Console if you haven't already done so. You can start the Admin Console by starting a web browser and entering the URL http://localhost:4848/asadmin. If you changed the default Admin port during installation, enter the correct port number in place of 4848.
To log in to the Admin Console, enter the user name and password of a user in the admin-realm who belongs to the asadmin group. The name and password entered during installation will work, as will any users added to this realm and group subsequent to installation. 
Expand the Configuration node in the Admin Console tree.
Expand the Security node in the Admin Console tree. 
Expand the Realms node. Select the file realm.
Click the Manage Users button.
Click New to add a new user to the realm.
Enter the correct information into the User ID, Password, and Group(s) fields. The example applications reference a user with the following attributes:
User ID = wsitUser
Group List = wsit
New Password = changeit
Confirm New Password = changeit
Click OK to add this user to the list of users in the realm.
Click Logout when you have completed this task.
Adding Users to GlassFish From Command Line 
To add users to GlassFish from the command line, make sure GlassFish is running, then enter the following command: 
<AS_HOME>/asadmin create-file-user --groups wsit wsitUser 
Enter changeit for the password when prompted.

3)	Creating a Web Service 
The starting point for developing a web service to use the WSIT technologies is a Java class file annotated with the javax.jws.WebService annotation. The WebService annotation defines the class as a web service endpoint. The following Java code shows a web service. The IDE will create most of this Java code for you.
Perform the following steps to use the IDE to create this web service: 
Click on the Runtime tab in the left pane and verify that GlassFish is listed in the left pane. If it is not listed, refer to Registering GlassFish with the IDE and register it.
Choose FileNew Project, select Web Application from the Web category, and click Next.
Assign the project a name that is representative of services that will be provided by the web service (for example, CalculatorApplication), set the Project Location to the location of the Sun application server, and click Finish.
Note: As of this writing, when creating the web service project be sure to define a Project Location that does not include spaces in the directory name. Spaces in the directory might cause the web service and web service clients to fail to build and deploy properly. To avoid this problem, Sun recommends that you create a directory, for example C:\work, and put your project there. 
Right-click the CalculatorApplication node and choose NewWeb Service.
Enter the web service name (PlacoWS) and the package name (placo.fr...) in the Web Service Name and the Package fields respectively.
Select Create an Empty Web Service. Click Finish.
The IDE then creates a skeleton PlacoWS.java file for the web service that includes an empty WebService class with annotation @Webservice. 
Right-click within the body of the class and choose Web ServiceAdd Operation.
In the upper part of the Add Operation dialog box, type add (as exemple of operation) in Name and choose int from the Return Type drop-down list.
In the lower part of the Add Operation dialog box, click Add and create a parameter of type int named i. Click OK. Click Add again and create a parameter of type int called j. Click OK and close the Enter Method Parameter dialog box.
Click OK at the bottom of the Add Operation dialog box.
Notice that the add method has been added to the Source Editor:
 @WebMethod
public int add(@WebParam(name = "i") int i, 
@WebParam(name = "j") int j) {
// TODO implement operation 
return 0;
} 
Change the add method to the following (changes are in bold):
@WebMethod(action="add")
public int add(@WebParam(name = "i") int i, 
@WebParam(name = "j") int j) {
int k = i + j;
 return k;
} 
Note: To ensure interoperability with Windows Communication Foundation (WCF) clients, you must specify the action element of @WebMethod in your endpoint implementation classes. WCF clients will incorrectly generate an empty string for the Action header if you do not specify the action element. 
Save the PlacoWS.java file.

4)	Configuring Realms And Users for HTTP BASIC Authentication

Earlier I said that Server B will host the service, and Server A will be the client. Before we can enable HTTP BASIC authentication in the web service, we need to create the username and password that will be used by the service client. Glassfish has several repositories for user accounts, called realms. We're going to create a new realm for our service, then add a user into it. To do this, log into Server B's Glassfish web console at http://serverB:4848 and log in as admin. The default password is adminadmin. 
Use the tree on the left to navigate to Configuration --> Security --> Realms. Click the New button to create a new realm and enter the following information:
Name	myRealm	
Class Name	com.sun.enterprise.security.auth.realm.file.FileRealm	
JAAS context	fileRealm	
Key File	${com.sun.aas.instanceRoot}/config/myRealm-keyfile	
Click OK. It will save your new realm and bring you back to the list of realms. Click on your new realm to bring up the Edit Realm screen. Click the Manage Users button. Next you will see an empty list of users. Click the New button to create a new user. Enter the following information:
User ID	testClient	
Group List	Users	
New Password	secret	
Confirm New Password	secret	
Note: You make up the group name. It does not come from a list somewhere else.
Press OK to save. We now have a new realm and user account that can be used for the service.

5)	Enabling SSL
To enable transport layer SSL security for this web service, you need to modify the deployment descriptor.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <security-constraint>        
        <display-name>SSL</display-name>
        <web-resource-collection>
            <web-resource-name>Everything</web-resource-name>
            <description/>
            <url-pattern>/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>PUT</http-method>
            <http-method>HEAD</http-method>
            <http-method>POST</http-method>
            <http-method>OPTIONS</http-method>
            <http-method>TRACE</http-method>
            <http-method>DELETE</http-method>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
</web-app> 

6)	Enabling HTTP BASIC Authentication
Next we're going to add HTTP BASIC authentication security. Earlier we had created a new security realm in Glassfish called myRealm and a new user inside the realm called testClient. We put testClient in a group called Users. To enable HTTP BASIC authentication we need to modify the deployment descriptor again:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 EJB 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-ejb-jar_3_0-0.dtd">
<sun-ejb-jar>
  <security-role-mapping>
    <role-name>AuthorizedClients</role-name>
    <group-name>Users</group-name>
  </security-role-mapping>
  <enterprise-beans>
    <ejb>
      <ejb-name>CentralData</ejb-name>
      <webservice-endpoint>
       <port-component-name>CentralData</port-component-name>
       <login-config>
         <auth-method>BASIC</auth-method>
         <realm>myRealm</realm>
       </login-config>
       <transport-guarantee>CONFIDENTIAL</transport-guarantee>
     </webservice-endpoint>
    </ejb>
  </enterprise-beans> 
</sun-ejb-jar>
The security-role-mapping section maps a role name that you make up for use by your web service to a group name used by real user accounts in the application server. The role name could be exactly the same as the group name for simplicity; but I chose a different name to demonstrate how it can be used.
If this service was a servlet endpoint in a web project instead of an EJB endpoint, then the web.xml deployment descriptor would have been updated like this:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <security-constraint>        
        <display-name>SSL</display-name>
        <web-resource-collection>
            <web-resource-name>Everything</web-resource-name>
            <description/>
            <url-pattern>/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>PUT</http-method>
            <http-method>HEAD</http-method>
            <http-method>POST</http-method>
            <http-method>OPTIONS</http-method>
            <http-method>TRACE</http-method>
            <http-method>DELETE</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>AuthorizedClients</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
    <login-config>
        <auth-method>BASIC</auth-method>
        <realm>myRealm</realm>
    </login-config>
    <security-role>
        <role-name>AuthorizedClients</role-name>
    </security-role>
</web-app> 
The web.xml deployment descriptor does not have a security-role-mapping section so you need to enter that information into the application server specific deployment descriptor (sun-web.xml for Glassfish). The sun-web.xml file would like look this: <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Servlet 2.5//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd">
<sun-web-app error-url="">
    <security-role-mapping>
        <role-name>AuthorizedClients</role-name>
        <group-name>Users</group-name>
    </security-role-mapping>
    <context-root>/CentralDataService</context-root>
    <class-loader delegate="true"/>
    <jsp-config>
        <property name="keepgenerated" value="true">
            <description>Keep a copy of the generated servlet class' java code.</description>
        </property>
    </jsp-config>
</sun-web-app> 
The last step is to specify which methods you would like to secure with HTTP BASIC authentication. You can use the @RolesAllowed annotation on a per-method basis, or for the whole class. In this example we'll use it per method.
package com.ryandelaplante.centraldata.service;

import com.ryandelaplante.domain.Reservation;
import javax.annotation.security.RolesAllowed;
import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

@Stateless()
@WebService()
public class CentralData {
    @WebMethod
    @RolesAllowed("AuthorizedClients")
    public Reservation[] findReservations(@WebParam(name = "lastName")
            String lastName) {
    
        Reservation[] results = { new Reservation(), new Reservation() };
        
        results[0].setConfNumber("0001");
        results[0].setFirstName("John");
        results[0].setLastName("Doe");
        
        results[1].setConfNumber("0002");
        results[1].setFirstName("Jane");
        results[1].setLastName("Doe");
        
        return results;
    }    
} 
Note that you can have a different role per method. If you would like to include multiple roles, then use the following syntax:
@RolesAllowed( { “Role1”, “Role2” } )