Given a scenario, implement Java EE based web service web-tier and/or EJB-tier basic security mechanisms, such as mutual authentication, SSL, and access control.

[Note]

HTTP Basic Authentication

HTTP Basic Authentication requires that the server request a user name and password from the web client and verify that the user name and password are valid by comparing them against a database of authorized users. When basic authentication is declared, the following actions occur:

HTTP Basic Authentication

  1. A client requests access to a protected resource.

  2. The web server returns a dialog box that requests the user name and password.

  3. The client submits the user name and password to the server.

  4. The server authenticates the user in the specified realm and, if successful, returns the requested resource.

The following example shows how to specify basic authentication in your deployment descriptor:


<login-config>
    <auth-method>BASIC</auth-method>
</login-config>

					

HTTP basic authentication is not a secure authentication mechanism. Basic authentication sends user names and passwords over the Internet as text that is Base64 encoded, and the target server is not authenticated. This form of authentication can expose user names and passwords. If someone can intercept the transmission, the user name and password information can easily be decoded. However, when a secure transport mechanism, such as SSL, or security at the network level, such as the IPSEC protocol or VPN strategies, is used in conjunction with basic authentication, some of these concerns can be alleviated.

Example application that uses HTTP basic authentication in a JAX-WS service

  1. Annotate the Service

    Annotations are used to specify which users are authorized to access which methods of the service. In this simple example, the @RolesAllowed annotation is used to specify that users in the application role of basicUser are authorized access to the sayHello(String name) method. This application role must be linked to a group of users on the Application Server.

    The code snippet is as follows:

    import javax.jws.WebMethod;
    import javax.jws.WebService;
    import javax.annotation.security.RolesAllowed;
    
    @WebService()
    public class Hello {
        private String message = new String("Hello, ");
    
        @WebMethod()
        @RolesAllowed("basicUser")
        public String sayHello(String name) {
            return message + name + ".";
        }
    }							
    								

  2. Add Security Elements to the Deployment Descriptor

    To enable basic authentication for the service, add security elements to the application deployment descriptor, web.xml. The security elements that need to be added to the deployment descriptor include the security-constraint and login-config elements:

    
    <web-app version="2.5" ...>
    	<display-name>Basic Authentication Security Example</display-name>
    
    	<servlet>
    		<display-name>HelloService</display-name>
    		<servlet-name>HelloService</servlet-name>
    		<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
    	</servlet>
    
    	<servlet-mapping>
    		<servlet-name>HelloService</servlet-name>
    		<url-pattern>/hello</url-pattern>
    	</servlet-mapping>
    
    	<security-constraint>
    		<web-resource-collection>
    			<web-resource-name>WRCollection</web-resource-name>
    			<url-pattern>/hello</url-pattern>
    			<http-method>GET</http-method>
    			<http-method>POST</http-method>
    		</web-resource-collection>
    
    		<auth-constraint>
    			<role-name>basicUser</role-name>
    		</auth-constraint>
    
    		<user-data-constraint>
    			<transport-guarantee>NONE</transport-guarantee>
    		</user-data-constraint>
    	</security-constraint>
    	
    	<login-config>
    		<auth-method>BASIC</auth-method>
    	</login-config>
    
    	<security-role>
    		<role-name>basicUser</role-name>
    	</security-role>
    </web-app>
    								
    								

  3. Set Security Properties In The Client Code

    You can do the following:

    HelloService service = new HelloService();
    Hello proxy = service.getHelloPort();
    
    BindingProvider bindingProvider = (BindingProvider)proxy;
    
    bindingProvider.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "userfoo");
    bindingProvider.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "passbar");
    								

    BindingProvider.USERNAME_PROPERTY, BindingProvider.PASSWORD_PROPERTY are used primarily for service requests. When you instantiate Service, it fetches WSDL and the server is returning 401. You could try any one of the following solutions:

    • Use java.net.Authenticator class in your client application.

    • Provide a local access to the WSDL using catalog.

    • Configure web.xml to allow GET requests without authentication.

Mutual Authentication

With mutual authentication, the server and the client authenticate one another. There are two types of mutual authentication:

Certificate-Based Mutual Authentication

When using certificate-based mutual authentication, the following actions occur:

Certificate-Based Mutual Authentication

  1. A client requests access to a protected resource.

  2. The web server presents its certificate to the client.

  3. The client verifies the server's certificate.

  4. If successful, the client sends its certificate to the server.

  5. The server verifies the client's credentials.

  6. If successful, the server grants access to the protected resource requested by the client.

User Name- and Password-Based Mutual Authentication

In user name- and password-based mutual authentication, the following actions occur:

User Name- and Password-Based Mutual Authentication

  1. A client requests access to a protected resource.

  2. The web server presents its certificate to the client.

  3. The client verifies the server's certificate.

  4. If successful, the client sends its user name and password to the server, which verifies the client's credentials.

  5. If the verification is successful, the server grants access to the protected resource requested by the client.

Using JAX-WS-Based Web Services with SSL

  1. Write the Class for the Web Service Endpoint

    SSL has no impact on the Java code for the web service endpoint. The same code works for web services that use SSL or that don't use SSL.

    In Java EE 5, you can use annotations to easily construct a JAX-WS web service. Here's an example of a web service implemented as an EJB endpoint:

    import javax.annotation.Resource;
    import javax.ejb.Stateless;
    import javax.jws.WebService;
    import javax.xml.ws.WebServiceContext;
    
    @Stateless
    @WebService
    public class HelloEjb {
    
        @Resource 
        WebServiceContext wsContext;
    
        public String hello(String msg) {
            return "Ejb WS: " + wsContext.getUserPrincipal() + ": " + msg;
        }
    }
    								

    The @Stateless annotation marks the class as a stateless session bean, and the @WebService annotation marks the class as a web service. The @Resource annotation is used to declare resource dependencies that the class has - in essence, what resources the class needs. These resources are then injected into the endpoint implementation. In this example, the annotation identifies a resource dependency on the WebServiceContext. The class needs the WebServiceContext to get context information about requests, such as related security information.

    Here's the same web service implemented as a servlet endpoint:

    import javax.annotation.Resource;
    import javax.jws.WebService;
    import javax.xml.ws.WebServiceContext;
    
    @WebService
    public class HelloServlet {
        @Resource 
        WebServiceContext wsContext;
    
        public String hello(String msg) {
            return "Servlet WS: " + wsContext.getUserPrincipal() + ": " + msg;
        }
    }
    								

  2. Specify Security Information in Deployment Descriptors

    To use SSL in a web service that is implemented as an EJB endpoint, you need to specify security information in a vendor-specific deployment descriptor. For a web service implemented as a servlet, you need to specify the security information in the web.xml descriptor.

    One important aspect of secure communication through SSL is server authentication, that is, confirming the identity of the server to the client. Another aspect is client authentication, where the server confirms the identity of the client. In SSL, you can have either server authentication or the combination of server and client authentication (but not client authentication alone). We use the term "mutual authentication" to mean the combination of server and client authentication. (Note however that other documents might attach a different meaning to mutual authentication. For example, in some documents, the term client authentication is synonymous with mutual authentication).

    For SSL mutual authentication, you need to set the auth-method subelement of the login-config element to CLIENT-CERT. You also need to set the transport-guarantee element to CONFIDENTIAL.

    Add the appropriate security elements to the web.xml deployment descriptor:

    
    <?xml version="1.0"?>
    <web-app version="2.5" ...>
    	<display-name>Secure Mutual Authentication Example</display-name>
    
    	<security-constraint>
    		<web-resource-collection>
    			<web-resource-name>SecureHello</web-resource-name>
    			<url-pattern>/hello</url-pattern>
    			<http-method>GET</http-method>
    			<http-method>POST</http-method>
    		</web-resource-collection>
    		
    		<user-data-constraint>
    			<transport-guarantee>CONFIDENTIAL</transport-guarantee>
    		</user-data-constraint>
    	</security-constraint>
    	
    	<login-config>
    		<auth-method>CLIENT-CERT</auth-method>
    	</login-config>
    </web-app>
    								
    								

  3. Write the Client

    After deploying the web service, you can access it from a client program. The client program for a web service application that uses SSL is essentially the same as one that doesn't use SSL. The major difference is that instead of using HTTP as the internet protocol, you need to use HTTPS. In the client, you use the @WebServiceRef annotation to declare a reference to a web service. The value of the wsdlLocation parameter in @WebServiceRef is a URL that points to the location of the WSDL file for the service being referenced. So for a web service client that uses SSL, the wsdlLocation parameter in the @WebServiceRef annotation needs to specify an HTTPS URL.

    For example:

    @WebServiceRef(wsdlLocation="https://server.com:8080/HelloEjbService/HelloEjb?WSDL")
    private static HelloEjbService helloEjbService;
    								

    You can then access the port for the web service and invoke the web service:

    HelloEjb helloEjbPort = helloEjbService.getHelloEjbPort();
    helloEjbPort.hello("Hello World");
    								

    Client-side artifacts are generated by accessing the WSDL file through HTTPS. To do that, you need to specify the location of a truststore file for the server and its password in the environment variable. In SSL, you can use certificates to authenticate the server or for mutual authentication of both the server and client. The truststore file for the server contains the trusted certificates for the server and its keys.

  4. Set Up the Client Truststore and Keystore

    In addition to a truststore file for the server, you also need a truststore file for the client. The client validates the server certificate against a set of certificates in its truststore. For a secure connection to be made using SSL, the client-side truststore needs to trust the server certificate. For SSL mutual authentication, the server-side truststore also needs to trust the client certificate. If you modify the server-side truststore, you need to restart the server (this allows use of the new certificate). You might not need to do this in a production environment because production certificates are signed by a common Certificate Authority (CA).

    For SSL mutual authentication, you need to provide your own key in a client keystore (a file that contains the client's keys and certificates). You can use keytool, a key and certificate management utility in JDK 5.0, to generate the keystore.

    The certificate has to be loaded to the client, to achieve this, keytool command is used

    keytool -import -trustcacerts -alias FOO -file "FOO_PATH\foo.cer" -storetype JKS -keystore "FOO_PATH\foo.keystore"
    								

  5. Run the Client

    Before you run the client that access a web service with SSL, you need to set the value of the environment variable.

    For SSL mutual authentication, set the value to:

    												
    System.setProperty("javax.net.ssl.keyStore", "FOO_PATH/foo.keystore");
    System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
    System.setProperty("javax.net.ssl.keyStoreType", "JKS");
    System.setProperty("javax.net.ssl.trustStore", "FOO_PATH/foo.keystore");
    System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
    System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
    Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
    								

Professional hosting     Belorussian informational portal         Free SCWCD 1.4 Study Guide     Free SCDJWS 1.4 Study Guide     SCDJWS 1.4 Quiz     Free IBM Certified Associate Developer Study Guide     IBM Test 000-287. Enterprise Application Development with IBM WebSphere Studio, V5.0 Study Guide     SCDJWS 5.0 Quiz