4 Configuring Access Control Security (JAX-RPC Only)

The following sections describe how to configure security for your Web service:

Configuring Access Control Security: Main Steps

Access control security refers to configuring the Web service to control the users who are allowed to access it, and then coding your client application to authenticate itself, using HTTP/S or username tokens, to the Web service when the client invokes one of its operations.

You specify access control security for your Web service by using one or more of the following annotations in your JWS file:

  • weblogic.jws.security.RolesAllowed

  • weblogic.jws.security.SecurityRole

  • weblogic.jws.security.RolesReferenced

  • weblogic.jws.security.SecurityRoleRef

  • weblogic.jws.security.RunAs

    Note:

    The @weblogic.security.jws.SecurityRoles and @weblogic.security.jws.SecurityIdentity JWS annotations were deprecated as of WebLogic Server 9.1.

The following procedure describes the high-level steps to use these annotations to enable access control security; later sections in the chapter describe the steps in more detail.

Note:

It is assumed in the following procedure that you have already created a JWS file that implements a WebLogic Web service and you want to update it with access control security.

It is also assumed that you use Ant build scripts to iteratively develop your Web service and that you have a working build.xml file that you can update with new information.

Finally, it is assumed that you have a client application that invokes the non-secured Web service. If these assumptions are not true, see Getting Started With JAX-RPC Web Services for Oracle WebLogic Server.

  1. Update your JWS file, adding the @weblogic.jws.security.RolesAllowed, @weblogic.jws.security.SecurityRole, @weblogic.jws.security.RolesReferenced, or @weblogic.jws.security.SecurityRoleRef annotations as needed at the appropriate level (class or operation).

    See Updating the JWS File With the Security-Related Annotations.

  2. Optionally specify that WebLogic Server internally run the Web service using a specific role, rather than the role assigned to the user who actually invokes the Web service, by adding the @weblogic.jws.security.RunAs JWS annotation.

    See Updating the JWS File With the @RunAs Annotation.

  3. Optionally specify that your Web service can be, or is required to be, invoked using HTTPS by adding the @weblogic.jws.security.UserDataConstraint JWS annotation.

    See Configuring Transport-Level Security Via UserDataConstraint: Main Steps (JAX-RPC Only) for details. This section also discusses how to update your client application to use SSL.

  4. Recompile and redeploy your Web service as part of the normal iterative development process.

    See "Developing WebLogic Web Services" in Getting Started With WebLogic Web Services Using JAX-RPC.

  5. Using the Administration Console, create valid WebLogic Server users, if they do not already exist. If the mapping of users to roles is external, also use the Administration Console to create the roles specified by the @SecurityRole annotation and map the users to the roles.

    Note:

    The mapping of users to roles is defined externally if you do not specify the mapToPrincipals attribute of the @SecurityRole annotation in your JWS file to list all users who can invoke the Web service.

    See "Users, Groups, and Security Roles" in Securing WebLogic Resources Using Roles and Policies.

  6. Update your client application to use the HttpTransportInfo WebLogic API to specify the appropriate user and password when creating the Service object.

    See Setting the Username and Password When Creating the Service Object.

  7. Update the clientgen Ant task in your build.xml file to specify the username and password of a valid WebLogic user (in the case where your Web service uses the @RolesAllowed annotation) and the trust store that contains the list of trusted certificates, including WebLogic Server's (in the case you specify @UserDataConstraint).

    You do this by adding the standard Ant <sysproperty> nested element to the clientgen Ant task, and set the key attribute to the required Java property, as shown in the following example.

    Note:

    The example hard-codes the username and password; prompting for both provides more security. You need the username and password for @RolesAllowed, and trustStore if SSL must be used.
    <clientgen
        wsdl="http://example.com/myapp/myservice.wsdl"
        destDir="/output/clientclasses"
        packageName="myapp.myservice.client"
        serviceName="StockQuoteService" >
        <sysproperty key="javax.net.ssl.trustStore" 
                     value="/keystores/DemoTrust.jks"/> 
        <sysproperty key="weblogic.wsee.client.ssl.stricthostchecking" 
                     value="false"/> 
        <sysproperty key="javax.xml.rpc.security.auth.username" 
                     value="juliet"/> 
        <sysproperty key="javax.xml.rpc.security.auth.password" 
                     value="secret"/> 
    </clientgen>
    
  8. Regenerate client-side components and recompile client Java code as usual.

Updating the JWS File With the Security-Related Annotations

Use the WebLogic-specific @weblogic.jws.security.RolesAllowed annotation in your JWS file to specify an array of @weblogic.jws.security.SecurityRoles annotations that list the roles that are allowed to invoke the Web service. You can specify these two annotations at either the class- or method-level. When set at the class-level, the roles apply to all public operations. You can add additional roles to a particular operation by specifying the annotation at the method level.

The @SecurityRole annotation has the following two attributes:

  • role is the name of the role that is allowed to invoke the Web service.

  • mapToPrincipals is the list of users that map to the role. If you specify one or more users with this attribute, you do not have to externally create the mapping between users and roles, typically using the Administration Console. However, the mapping specified with this attribute applies only within the context of the Web service.

The @RolesAllowed annotation does not have any attributes.

You can also use the @weblogic.jws.security.RolesReferenced annotation to specify an array of @weblogic.jws.security.SecurityRoleRef annotations that list references to existing roles. For example, if the role manager is already allowed to invoke the Web service, you can specify that the mgr role be linked to the manager role and any user mapped to mgr is also able to invoke the Web service. You can specify these two annotations only at the class-level.

The @SecurityRoleRef annotation has the following two attributes:

  • role is the name of the role reference.

  • link is the name of the already-specified role that is allowed to invoke the Web service. The value of this attribute corresponds to the value of the role attribute of a @SecurityRole annotation specified in the same JWS file.

The @RolesReferenced annotation does not have any attributes.

The following example shows how to use the annotations described in this section in a JWS file, with the relevant sections shown in bold:

package examples.webservices.security_roles;
import javax.jws.WebMethod;
import javax.jws.WebService;
// WebLogic JWS annotations
import weblogic.jws.WLHttpTransport;
import weblogic.jws.security.RolesAllowed; 
import weblogic.jws.security.RolesReferenced; 
import weblogic.jws.security.SecurityRole; 
import weblogic.jws.security.SecurityRoleRef; 
@WebService(name="SecurityRolesPortType",
            serviceName="SecurityRolesService",
            targetNamespace="http://example.org")
@WLHttpTransport(contextPath="security", 
                 serviceUri="SecurityRolesService",
                  portName="SecurityRolesPort")
@RolesAllowed (  { 
    @SecurityRole (role="manager", 
                   mapToPrincipals={ "juliet","amanda" }), 
    @SecurityRole (role="vp") 
} ) 
@RolesReferenced ( 
    @SecurityRoleRef (role="mgr", link="manager") 
) 
/**
 * This JWS file forms the basis of simple Java-class implemented WebLogic
 * Web Service with a single operation: sayHello
 *
 */
public class SecurityRolesImpl {
  @WebMethod()
  public String sayHello(String message) {
    System.out.println("sayHello:" + message);
    return "Here is the message: '" + message + "'";
  }
}

The example shows how to specify that only the manager, vp, and mgr roles are allowed to invoke the Web service. The mgr role is actually a reference to the manager role. The users juliet and amanda are mapped to the manager role within the context of the Web service. Because no users are mapped to the vp role, it is assumed that the mapping occurs externally, typically using the Administration Console to update the WebLogic Server security realm.

See "JWS Annotation Reference" in WebLogic Web Services Reference for reference information on these annotations.

Updating the JWS File With the @RunAs Annotation

Use the WebLogic-specific @weblogic.jws.security.RunAs annotation in your JWS file to specify that the Web service is always run as a particular role. This means that regardless of the user who initially invokes the Web service (and the role to which the user is mapped), the service is internally executed as the specified role.

You can set the @RunAs annotation only at the class-level. The annotation has the following attributes:

  • role is the role which the Web service should run as.

  • mapToPrincipal is the principal user that maps to the role.

The following example shows how to use the @RunAs annotation in a JWS file, with the relevant sections shown in bold:

package examples.webservices.security_roles;
import javax.jws.WebMethod;
import javax.jws.WebService;
// WebLogic JWS annotations
import weblogic.jws.WLHttpTransport;
import weblogic.jws.security.RunAs; 
@WebService(name="SecurityRunAsPortType",
            serviceName="SecurityRunAsService",
            targetNamespace="http://example.org")
@WLHttpTransport(contextPath="security_runas",
                 serviceUri="SecurityRunAsService",
                 portName="SecurityRunAsPort")
@RunAs (role="manager", mapToPrincipal="juliet") 
/**
 * This JWS file forms the basis of simple WebLogic
 * Web Service with a single operation: sayHello
 *
 */
public class SecurityRunAsImpl {
  @WebMethod()
  public String sayHello(String message) {
    System.out.println("sayHello:" + message);
    return "Here is the message: '" + message + "'";
  }
}

Setting the Username and Password When Creating the Service Object

When you use the @RolesAllowed JWS annotation to secure a Web service, only the specified roles are allowed to invoke the Web service operations. This means that you must specify the username and password of a user that maps to the role when creating the Service object in your client application that invokes the protected Web service.

WebLogic Server provides the HttpTransportInfo class for setting the username and password and passing it to the Service constructor. The following example is based on the standard way to invoke a Web service from a standalone Java client (as described in Invoking Web Services in Getting Started With WebLogic Web Services Using JAX-RPC) but also shows how to use the HttpTransportInfo class to set the username and password. The sections in bold are discussed after the example.

package examples.webservices.sec_wsdl.client;
import weblogic.wsee.connection.transport.http.HttpTransportInfo; 
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.Stub;
/**
 * This is a simple standalone client application that invokes the
 * the <code>sayHello</code> operation of the SecWsdlService Web service.
 *
 * @author Copyright © 1996, 2008, Oracle and/or its affiliates. 
 * All rights reserved.
 */
public class Main {
  public static void main(String[] args)
      throws ServiceException, RemoteException{
    HttpTransportInfo info = new HttpTransportInfo(); 
    info.setUsername("juliet".getBytes()); 
    info.setPassword("secret".getBytes()); 
    SecWsdlService service = new SecWsdlService_Impl(args[0] + "?WSDL", info); 
    SecWsdlPortType port = service.getSecWsdlPort();
    try {
      String result = null;
      result = port.sayHello("Hi there!");
      System.out.println( "Got result: " + result );
    } catch (RemoteException e) {
      throw e;
    }
  }
}

The main points to note in the preceding example are as follows:

  • Import the HttpTransportInfo class into your client application:

    import weblogic.wsee.connection.transport.http.HttpTransportInfo;
    
  • Use the setXXX() methods of the HttpTransportInfo class to set the username and password:

    HttpTransportInfo info = new HttpTransportInfo();
    info.setUsername("juliet".getBytes());
    info.setPassword("secret".getBytes());
    

    In the example, it is assumed that the user juliet with password secret is a valid WebLogic Server user and has been mapped to the role specified in the @RolesAllowed JWS annotation of the Web service.

    If you are accessing a Web service using a proxy, the Java code would be similar to:

    HttpTransportInfo info = new HttpTransportInfo();
    Proxy p = new Proxy(Proxy.Type.HTTP, new  InetSocketAddress(proxyHost, Integer.parseInt(proxyPort)));
    info.setProxy(p);
    info.setProxyUsername(user.getBytes());
    info.setProxyPassword(pass.getBytes());
    
  • Pass the info object that contains the username and password to the Service constructor as the second argument, in addition to the standard WSDL first argument:

    SecWsdlService service = new SecWsdlService_Impl(args[0] + "?WSDL", info);
    

See "Invoking Web Services" in Getting Started With WebLogic Web Services Using JAX-RPC for general information about invoking a non-secured Web service.