1 2 Previous Next


25 posts

GlassFish V 3.1  Blog

Posted by kumarjayanti Mar 16, 2011

I posted my blogs on GlassFish V3.1 Security  at http://blogs.sun.com/gfsecurity/  due to the non-availability of java.net during the V3.1 release.



 GlassFish users who make use of CLIENT-CERT authentication with SSL  in their JavaEE applications  should consider upgrading to JDK1.6.0_22. The good news is that JDK1.6.0_22 contains a full fix for  the renegotiation protocol flaw in SSL (The IETF issued RFC 5746 ).  A fix which implements RFC 5746 and supports secure renegotiation.

More details are here : http://www.oracle.com/technetwork/java/javase/documentation/tlsreadme2-176330.html

The GlassFish Certificate Realm in V2.X and V3.0 releases is somewhat limiting. Many users expressed the need to able to do some custom authentication based on the client-certificate (or extensions within)  in a Mutual-SSL scenario. And subsequently do custom group assignment's which ultimately affect the authorization results. With V2.X/V3.0 the only two  things that were possible are :

1. Developer can specify a Single CertificateRealm with fixed name "certificate" to be used with CLIENT-CERT authentication mechanism. No LoginModule was allowed for this realm.

 2. Developer's can make use of the assign-groups functionality whereby every client that had a valid certificate (that is also trusted by the server) could be assigned a list of  group(s).

What is now possible with the latest V3.1 builds on the Trunk is the following

a.  The restriction (1) above of a single "certificate" realm remains. However one can now configure a LoginModule for the realm. The LoginModule would have access to the client certificate-chain and it is possible for the developer to do  application specific custom authentication of the client certificate.

b.  Do custom group assignment based on attributes and extensions present in the client certificate.

My team member sudarsan has created a detailed post on this with a sample loginmodule.

Embedded GlassFish v3 is a delivery vehicle of GFv3 so that applications and tools can use GFv3 just as a library, inside their JVM.  More details on this can be found  on the separate project page that has been created for  Embedded GlassFish.  

One would thus expect that even secure applications which use security annotations on an EJB or security-constraints in a web application to work on the Embedded Server.  My team member Nithya has created two posts which show

1. how to run an EJB App that uses  security annotations such as @RolesAllowed in the Embedded Server.

 2. how to run a Web App that  uses security-constraints and BASIC authentication in the Embedded Server.





Many users often ask the question :  Can i use a custom  JAAS Login Module instead of the Proprietary GlassFish Custom Realms for user authentication ?.

The JSR-196 Login Bridge Profile allows a Server Authentication Module (SAM) to delegate some security processing to JAAS LoginModules. My  team member sudarsan has created a nice blog-post  on this with a sample netbeans  project showing the use of the Login Bridge Profile.  The sample can be plugged in as a ServerAuthentication Module for a webapplication on both GlassFish V2.X and V3.

GlassFish  includes implementations of a number of HTTP layer authentication mechanisms such as Basic, Form, and Digest authentication. JSR-196 support in GlassFish  allows developers to implement and configure new authentication mechanisms or make alternative implementations of the provided ones. The following tech-tip provides all the details for doing this.

So to answer the question at the top, if you have a SAM that implements an Authentication Mechanism (say BASIC), then you can use the Login Bridge Profile to configure a JAAS LoginModule in GlassFish that will be invoked by the SAM. The JAAS Login Module can then perform custom username-password authentication and communicate the resulting  Principal and Group information to GlassFish by making use of standard JSR-196 defined callbacks (which are supported by the GlassFish CallbackHandler supplied to the SAM as an argument).  

The important thing to note is that the LoginModule and the CallbackHandler (if any that the LoginModule uses) need  not have any proprietary Glassfish Code. In other words the JAAS LoginModule is suitable for use with other containers as well.  And if the Non-Glassfish Container supports JSR-196 then the developer essentially is freed from the task of figuring out how to set the Principal and Group information into the target Container, the JSR-196 CallbackHandler supplied by the Container would handle it for the user. 

This is in contrast to the Realm which is a proprietary GlassFish artifact. Though the Realm in GlassFish essentially makes use of  a corresponding LoginModule to do its authentication, it requires use of Glassfish specific code to ensure it communicates the Principal and Group membership information to the container in the right manner.

Shing Wai's post explains the @ServletSecurity annotation that has been introduced newly in JavaEE 6 (Servlet 3.0 specification). The @ServletSecurity annotation provides an alternative mechanism for defining access control constraints equivalent to those that could otherwise have been expressed declaratively via security-constraint elements in the portable deployment descriptor. There is also a Programmatic approach for adding security (via ServletRegistration.Dynamic API) that has been introduced newly in JavaEE 6, i will talk about it in another post.

Using the @ServletSecurity annotation one can now have a descriptor free secure WebApplication in Glassfish V3. And using the fact that the default mode in calls to enterprise beans from web applications is for the security identity of a web user to be propagated to the EJB container, we can actually have a secure enterprise application without any security information in the portable deployment descriptors.

So let us define an example Servlet which invokes a Secure EJB (A currency converter bean). The ServletSecurity annotation on the servlet below is such that any authenticated user in role "TutorialUser" or "guest" is allowed access to the Servlet. However the Converter EJB would only allow a user in role "TutorialUser" to access its methods. The ServletSecurity annotation below is equivalent to the following <security-constraint> element.


package test;

import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.HttpConstraint;
import javax.servlet.annotation.ServletSecurity;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name="TutorialServletBASIC", urlPatterns={"/TutorialServletBASIC"})
//for all HTTP methods, auth-constraint requiring membership in Role TutorialUser or guest
@ServletSecurity(@HttpConstraint(rolesAllowed = {"TutorialUser", "guest"}))
public class TutorialServletBASIC extends HttpServlet {
    private ConverterBean converterBean;
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        try {
            out.println("<title>Servlet TutorialServletBASIC</title>"); 
            BigDecimal result = converterBean.dollarToYen(new BigDecimal("1.0"));
            out.println("<h1>Servlet TutorialServlet result of dollarToYen= " + result + "</h1>");
        } finally {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);


Now let's look at the NoInterface Converter EJB, which only allows TutorialUser roles to invoke its methods.


package test;

import java.math.BigDecimal;
import javax.ejb.*;
import java.security.Principal;
import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RolesAllowed;

public class ConverterBean {

    SessionContext ctx;
    private BigDecimal yenRate = new BigDecimal("96.0650");
    private BigDecimal euroRate = new BigDecimal("0.0078");

    public BigDecimal dollarToYen(BigDecimal dollars) {
        BigDecimal result = new BigDecimal("0.0");
        Principal callerPrincipal = ctx.getCallerPrincipal();
        if (ctx.isCallerInRole("TutorialUser")) {
            result = dollars.multiply(yenRate);
            return result.setScale(2, BigDecimal.ROUND_UP);
        } else {
            return result.setScale(2, BigDecimal.ROUND_UP);

    public BigDecimal yenToEuro(BigDecimal yen) {
        BigDecimal result = new BigDecimal("0.0");
        Principal callerPrincipal = ctx.getCallerPrincipal();
        if (ctx.isCallerInRole("TutorialUser")) {
            result = yen.multiply(euroRate);
            return result.setScale(2, BigDecimal.ROUND_UP);
        } else {
            return result.setScale(2, BigDecimal.ROUND_UP);


 We are done with the application, there is no need to add any security information to any deployment descriptors. You will ofcourse need to go to the admin console and enable the "Default Principal to Role Mapping" feature  (Configuration -> Security tab) and create two file-users who are assigned to groups named "guest" and "TutorialUser" respectively.


Then build the attached project using Netbeans 6.8 M2 (or latest 6.8 builds) and deploy on GlassFish V3. Then you can try accessing the Servlet URL :


Your browser would then pop-up the BASIC authentication username-password dialog.  You will see that if you specify a user in group TutorialUser as the username then the servlet can successfully invoke the Converter Bean and return a result, but when you login as  user in the "guest" group,  it would throw the following exception when the servlet tries to invoke the  EJB.


Caused by: javax.ejb.AccessLocalException: Client not authorized for this invocation.
        at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1801)
        at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:188)


One question that would come to mind is where did we specify BASIC authentication for the Servlet . The answer is that the RI establishes BASIC authentication as the default when no auth-method is specified, but the request is for an auth-constrained resource.

In this post i would like to provide a brief summary of some of the Propietary Features and implementation details of SAAJ 1.3.4 that are not necessarily related to the SAAJ API specifications. 

Creating SOAPMessages with Very Large XML Payload

The JavaDoc  of the API method SOAPMessage.saveChanges() poses a problem for the implementation by specifying that "All MIME headers in a  message that is created for sending purposes are guaranteed to have  valid values only after saveChanges  has been called".  Specifically the RI would try to set the Content-Length header after a  saveChanges() call and for that it would try to buffer the message contents. This prevents the RI from creating a message with a huge payload. There would be an exception of the following form  when the test method below is executed :

Caused by: java.lang.OutOfMemoryError: Java heap space
        at com.sun.xml.messaging.saaj.util.ByteOutputStream.ensureCapacity(ByteOutputStream.java:111)
        at com.sun.xml.messaging.saaj.util.ByteOutputStream.write(ByteOutputStream.java:95)
        at com.sun.xml.messaging.saaj.util.JAXMStreamSource.<init>(JAXMStreamSource.java:63)
        at com.sun.xml.messaging.saaj.soap.SOAPPartImpl.setContent(SOAPPartImpl.java:243)
        at com.sun.xml.messaging.saaj.soap.MessageImpl.init(MessageImpl.java:406)

So SAAJ 1.3.4  has introduced a System Property : saaj.lazy.contentlength which would allow the RI to set the Content-Length header lazily when the SOAPMessage is finally being serialized. While setting this property lazily violates the SAAJ API javadoc statement above, it would allow handling of large payloads by the RI.

 public static void testSAAJIssue50() throws Exception {
        System.setProperty("saaj.lazy.contentlength", "true");
        MessageFactory mf = MessageFactory.newInstance();
        MimeHeaders hdrs = new MimeHeaders();
        hdrs.addHeader("Content-Type", "text/xml");
        //bigmessage.xml is a BIG SOAP Envelope
        SOAPMessage created = mf.createMessage(hdrs, new FileInputStream(new File("bigmessage.xml")));
        String[] cls = created.getMimeHeaders().getHeader("Content-Length");
        if (cls != null) {
           System.out.println("After saveChanges() Content-Length =" + cls[0]);
        } else {
           System.out.println("After saveChanges() Content-Length =" + 0);
        created.writeTo(new FileOutputStream(new File("bigmessage1.xml")));
        cls = created.getMimeHeaders().getHeader("Content-Length");
        System.out.println("After writeTo() Content-Length =" + cls[0]);

Executing the above test after setting the System property will produce an output as follows :

After saveChanges() Content-Length =0
After writeTo() Content-Length =77376973

Note: The SAAJ RI design did not have any Configuration support and due to the lack of time i resorted to the use of  system properties for enabling this proprietary behavior. In future i may think of adding some Configuration support though it is again unlikely to be something in the standard SAAJ-API specification.

Enhancements in the RI for Handling Very Large MIME Messages

SAAJ RI by default cannot handle incoming SOAP Messages having Large Attachments. See issue 31 for more details. The MimeMultipart representation in SAAJ RI borrowed from the original JavaMail implementation cannot handle very large MimeParts since it stores them in Memory and the SAAJ API AttachmentPart directly refers to the MimePart. The SAAJ API is also streaming un-friendly since it has a methods  SOAPMessage.getAttachments()  and SOAPMessage.getAttachments(...).  So what was required was a MimeMultipart implementation that can handle large Mime Parts. The MimePull project uses several smart techniques including the use of the File-System and split-representation (part memory and part file-system) to handle large Mime-Parts.  In SAAJ RI 1.3.4 one can instruct the SAAJ RI runtime to use the MimePull parser by setting the system property   "saaj.use.mimepull" to "true".  This would allowing handling of  large attachments in incoming messages. The comments in  issue 31 shows a sample test code which makes use of this property. 

One thought was to make the use of MimePull the default in SAAJ RI,  however i heard from the MimePull project lead that one thing it does not handle right now is any kind of non-default Content-Transfer-Encoding (such as base64 for example).  Furthermore the MimePull API is meant purely for parsing incoming Mime Messages (and not for creating a Mime Package with Large Attachments) whereas one can do crazy things with the SAAJ API like setting the content of a received attachment part again and recreating a new SOAPMessage etc. While the latter issue has been handled the  issue of Content-Transfer-Encoding prevented me from making the use of  MimePull as the default. In future we should see the use of  MimePull as the default in SAAJ RI. 

The MimePull parser has configuration support that allows one to configure the Limits and Thresholds but the SAAJ RI just creates and uses a default configuration object. In future we could consider exposing the MimePull parser configuration in SAAJ RI.

When using the MimePull feature make sure that you close the InputStream of the Large AttachmentPart after you are done with it, this should allow the MimePull runtime to release any resources that the MimePart associated with this attachment is holding onto. For example :

AttachmentPart ap = ..... //get the attachment part from the SOAPMessage

InputStream is = ap.getRawContent();


InputStream is = ap.getDataHandler().getInputStream();

try {

//use the inputstream

} finally {

  //finally close the stream

    try {


   }catch (IOException e) {



When using getRawContentBytes() api, the SAAJ RI would close the inputStream. There was a bug that ap.clearContent() does not call close() on the MimePart. This has been fixed in the latest trunk after the 1.3.4 release and you can obtain the latest SAAJ 1.3.4 update bits  (saaj.1.3.4.zip) with this fix from here.

 As early as SAAJ 1.3.2,  the SAAJ RI introduced the use of the Boyer-Moore algorithm for efficient Mime-Boundary Parsing of a Mime Packaged Message. Prior to this SAAJ was using the Mime Parsing code present in JavaMail. The switch to Boyer-Moore provided 20-30%  improvement in Mime-Parsing performance. The Boyer-Moore algorithm was then re-implemented in JavaMail and lately the MimePull project uses the same Boyer-Moore implementation as in JavaMail.

However when i introduced the Boyer-Moore implementation in SAAJ 1.3.2 as the default, i was afraid of having missed some boundary conditions (not detected by our existing tests), especially i found that the original JavaMail implementation was somewhat lenient in that it accepted messages which had minor violations w.r.t  (RFC 2045), i cannot recollect exactly what they are now, need to dig up my old notes. So there is a System property in SAAJ  "saaj.mime.optimization" which has value "true" by default but can be set to "false" to switch-off Boyer-Moore and fallback to the old JavaMail Mime-Boundary parsing implementation. Ever since, we did have a few users report issues with the Boyer-Moore implementation and we fixed them.

SAAJ RI in its very early days was also trying to eagerly load all the attachments in an incoming message. We changed this behavior in SAAJ 1.3.2 timeframe but provided a way to fall back to the eager loading scheme incase someone needs it. For this one can set the system property "saaj.lazy.mime.optimization" to "false".  This optimization has limited utility in the absence of MimePull especially when seen in the context of  SOAPMessage.getAttachments()  and SOAPMessage.getAttachments(...) apis.  However it does help a scenario where an intermediate (SOAP Handler) recives a large MimeMessage but never needs to look at the Attachments (but only needs to read/manipulate the SOAP Envelope/Body) before resending the message to an ultimate recipient.

One property  which is only available in the latest builds  (saaj1.3.4.zip) is the system property   saaj.mime.multipart.ignoremissingendboundary  its default value is true and needs to be set to false to indicate that the SAAJ runtime should report an error if the Multipart Mime Package has a missing end boundary. This feature was requested by an end user recently on the lines of what is supported in Java Mail. Note that this feature does not work when one enables saaj.use.mimepull .   

Some Other Features of the SAAJ RI

The SAAJ RI makes use of a ParserPool (a pool of SAXParser's) and this provides upto 15% reduction in time taken when 1000's of messages are being parsed. There is a JAXP issue which prevents SAAJ RI from cleanly using a Pool of Parsers, and a workaround for this has been currently used in SAAJ RI 1.3.4. The issue was reported by one of the SAAJ users and more details are in Issue 46.  The Old implementation of the ParserPool itself was inefficient and was upgraded in 1.3.4 to make use of the BlockingQueue from the java.util.concurrent pacakge. This fix was provided by an external user (kevinconaway) as a patch.

The SAAJ RI has had support for handling incoming messages that are  Fast-Infoset encoded since SAAJ 1.3.2 and there is support for handling MTOM encoded messages as well.  Both MTOM with SOAP 1.1 and SOAP 1.2 are supported. There was an issue in MTOM handling and again that was fixed in SAAJ RI 1.3.4, a patch was provided by an external user (jeremyhuiskamp). This is primarily to support the SOAPHandlers in JAXWS 2.X. There is no way to actually create FI or MTOM encoded messages using the SAAJ API's directly.

There was an issue of poor performance with large payloads (Issue 42) and this was due to a Xalan issue (JAXP issue 48). People reading this post should make sure that they either use the steps mentioned in Issue 42 to solve this problem or get the right version of JDK Update release that has the fix for  JAXP Issue 48.

Metro Security has a pluggable architecture and it makes use of JSR 196  (SOAP Profile) to achieve this pluggability.   The use of JSR-196 provides a standard way to integrate Metro with the Authentication and Authorization Infrastructure of the underlying container.  Though not all containers  on which metro can run today support JSR 196, the idea is that as more and more containers adopt JSR-196, integrating the metro webservices stack with those container would become easy. The use of JSR-196 in metro is also based on the principle of  re-using what is already a standard inorder to avoid proliferation of proprietary API's.

  In the absence of JSR-196, when Metro is used on a Non-GlassFish container then developers of  Secure WebServices today are forced to configure a whole lot of things such as CallbackHandler's, Validator's, Keystore's, CertStore's etc, some of which can be non-trivial.  All of these configurations would not be necessary if  the container supported a publicly callable JSR-196 CallbackHandler that metro could use. 

When a Metro Secure WebService runs on GlassFish it automatically leverages  the Container's Authentication and Authorization Mechanisms by way of invoking the GlassFish JSR-196 CallbackHandler, so user's of metro on GlassFish would generally not have to configure  additional things inside the metro configuration file w.r.t security. Metro runtime would invoke the GlassFish JSR-196 CallbackHandler. The GlassFish CallbackHandler would use the container configured mechanisms to authenticate let's say the username-password and finally establish the container's representation of the caller principal in the Subject. This Subject would then be used during the Authorization process.

Metro bundles the JSR-196 API along with it so that one can use  Metro with JSR-196 enabled on any Container (not just GlassFish). So here are  some of the pluggability points that are enabled in metro due to the use of JSR 196 underneath.

  1.  At the lowest level one can specify  a JSR 196 CallbackHandler on the client and server side to be used by the metro configuration. A JSR 196 Callbackhandler is a callbackhandler that handles the callbacks defined by the JSR-196 specification. More details on how end-users can specify a JSR-196 callbackhandler  can be found in this post here (look for section : JMACCallbackHandler). This facility can be used only when running on GlassFish.  When specified it overrides the GlassFish default Callbackhandler.  
  3.  By default only JSR-109 WebServices on GlassFish make use of the JSR-196 path but one can enable the use of JSR-196 for Plain-JAXWS applications as well by placing the following (gf-196-hook.jar) into GlassFish lib directory. This maybe fixed in near future such that all webservices on glassfish would use JSR-196 path. However we get bitten by the same old backward-compatibility bug that prevents us from eagerly doing it.  
  5. The Metro WS-* implementation makes use of the  JAXWS Tubes SPI . This  allows composing different Tubes in a Tubeline in a certain order to make the different WS-* implementations work together and produce the desired transformation on the WebService Messages.  The Security Tube in Metro in turn uses JSR-196 and thereby allows someone to replace the default JSR-196 AuthConfigProvider in Metro with something of their own. This feature is used by the OpenSSO stack when it replaces the WS-Security Implementation in Metro with it's own implementation for a few product specific reasons. The use of JSR-196 decouples the Security Tube from the Specifics of the WS-Security Implementation thereby allowing a different WS-Security implementation to be plugged in (complete with its own configuration definitions etc).   This feature is available when Metro Stack in running on any container including GlasssFish. Again for backward-compatibility reasons this feature is currently not enabled by default in Metro, but can be enabled by placing (wsit-196-hook.jar) in the containers classpath (for example the lib directory in GlassFish V2). There is a META-INF/services entry inside  wsit-196-hook.jar named javax.security.auth.message.config.AuthConfigProvider  whose contents point to the default Metro AuthConfigProvider (ACP).  If someone needs to plugin their own ACP then they would need to update this entry with the classname of their ACP implementation classs.

When using Pluggability Option 3 above one has to be aware of (and handle) three Container/Environment specific issues.

  1. The Keying Infrastructure and Container's Representation of caller Principal/Groups differ from container to container and so the JSR-196 CallbackHandler comes to the rescue here.  There are a few limitations when it comes to the set of Callbacks defined in the JSR-196 standard versus those required in a typical WS-Security scenario (for example the JSR-196 callbacks do not have any callback to handle CertificateValidation which is generally an important thing in a Mutual Certificates Scenario). However the JSR-196 standard does not prevent CallbackHandlers to handle other proprietary callbacks. So metro defines a few extension callbacks to deal with this.   There is a  META-INF/services entry inside wsit-196-hook.jar named javax.security.auth.message.callback.CallbackHandler  whose contents by default point to the correct classname of the JSR-196 CallbackHandler for GlassFish V2. When running on a different container one would need to update this services entry with the right classname of the JSR-196 CallbackHandler to be used on that container.  

    2.  The place where the Metro Security-Tube needs to finally place the JSR-196 javax.security.auth.Subject object such that it gets used for Authorization decisions on the Container is again not defined in any standard. For example on GlassFish this subject is to be set into a  GlassFish specific SecurityContext object .  For other containers it maybe something else. So there is a META-INF/services entry inside wsit-196-hook.jar named com.sun.xml.ws.security.spi.SecurityContext.  The default value of this entry points to an implementation of the following SecurityContext interface that does the correct thing for GlassFish V2.

package com.sun.xml.ws.security.spi;  
import javax.security.auth.Subject;  

 * Provides  
 * 1. a way to obtain credentials from an  
 * encompassing runtime into the Metro Pipeline runtime  
 * 2. API to set the credentials after authentication as understood  
 * by the container  
public interface SecurityContext {  
     * @return the subject containing credentials from the encompassing runtime, null if none is available  
    public Subject getSubject();  
     * Set the subject after message authentication as understood by the container  
     * @param subject  
    public void setSubject(Subject subject);  

     3. Another thing which is again handled by appropriately defining  the META-INF/services entry for the above defined SecurityContext is the fact that when there are credentials established by the encompassing runtime under which the SOAP layer webservice interaction is happening  (for example an authetication at the transport layer or an SSO Token) then one needs to make the SecurityContext established by the encompassing runtime available to the SOAP layer interaction. Again there is no standard that defines how to obtain this information from the encompassing runtime and hence the mechanism differs from Container to Container (For example, in GlassFish it is again the same SecurityContext object that needs to be retrieved).  

  As stated above the JSR-196 path is not enabled by default for Non-GlassFish containers, and i mentioned backward-compatibility as the reason. There is some work involved to package the Non-196 path as a JSR-196 Authentication module and once that is done then pluggability option 3 above can be made the default in metro. We may do this in the near future.  

My previous post Security Token Configuration in Metro has exceeded the maximum limits (even after having used the extended entry) of a post and hence when i added some more details yesterday, i am seeing that the tail end of my post was truncated. So here is what was in the tail end...


    Here is  the complete abstract schema for CallbackHandlerConfiguration and ValidatorConfiguration elements in Metro. I decided to paste the complete configuration here because for these two elements the configuration has been shown in bits and pieces under different tokens (as relevant).  

<sc:CallbackHandlerConfiguration wspp:visibility="private" xmlns:sc="http://schemas.sun.com/2006/03/wss/{server  or client}"  
        timestampTimeout="{Timeout value in Second(s) : This value is used to compute the Expiry time of the WSU:Timestamp being sent in the message, value specified should be greater than zero}"  
        useXWSSCallbacks="{Value true indicates use XWSS Callbacks in place of Standard J2SE callbacks for Non-109 App. For 109 Apps a value true indicates passing RuntimePropertiesCallback as an Extra Callback to CallbackHandler}" >  
       <sc:CallbackHandler  name="usernameHandler" classname="{a callbackhandler classname that handles javax.security.auth.callback.NameCallback}"  
        default="{the default username value as a string, to be provided incase classname is  not provided}" />  
       <sc:CallbackHandler  name="passwordHandler"  classname="{a callbackhandler  classname that handles javax.security.auth.callback.PasswordCallback}"  
        default="{the default password value as a string, to be provided incase classname  
        is not provided}"  />  
       <sc:CallbackHandler  name="samlHandler"  classname="{a callbackhandler  classname that  handles com.sun.xml.wss.impl.callback.SAMLCallback}"/>

       <sc:CallbackHandler  name="jmacCallbackHandler" classname="{a callbackhandler  classname that  handles all the Standard JSR 196 Callbacks}" />  
       <sc:CallbackHandler  name="xwssCallbackHandler"  classname="{a callbackhandler  classname that  handles all the XWSS Callbacks}" />  

   <sc:ValidatorConfiguration wspp:visibility="private" xmlns:sc="http://schemas.sun.com/2006/03/wss/{server  or client}"  
sc:maxClockSkew="{The assumed maximum skew (milliseconds) between the local times of any two systems, runtime defaults used when not specified}"  
sc:timestampFreshnessLimit="{The period (milliseconds) for which a Timestamp is considered fresh, runtime defaults used when not specified }  
sc:maxNonceAge="{The length of time (milliseconds) a previously received Nonce value in a UsernameToken will be stored, runtime defaults used when not specified}"  
sc:revocationEnabled="{If this flag is true, the default certificate revocation checking mechanism of the underlying PKIX service provider will be used. If this flag is false, the default revocation checking mechanism will be disabled (not used).}">

<sc:Validator name= "usernameValidator"  classname={class name of a usernameToken Validator,  
    should implement com.sun.xml.wss.impl.callback.PasswordValidationCallback.PasswordValidator }/>  
    <sc:Validator  name="timestampValidator" classname ={class name of a Timestamp Validator,  
    should implement com.sun.xml.wss.impl.callback.TimestampValidationCallback.TimestampValidator,  a default Timestamp validator from Metro runtime used when not supplied} />  
    <sc:Validator  name="certificateValidator" classname ={class name of a certificate Validator,  
    should implement com.sun.xml.wss.impl.callback.CertificateValidationCallback.CertificateValidator,  
    default Certificate validator from XWSS runtime used when not supplied} />

<sc:Validator name="samlAssertionValidator" classname = {class name of a SAML Assertion Validator, should implement com.sun.xml.wss.impl.callback.SAMLAssertionValidator,  
    Partial validation (in the form of verifying enveloped signature) occurs on SAML Assertion within  the WSIT/XWSS 3.0 Runtime even if the validator is not specified} /> ?  

 How does Metro Pickup the Certificate to use for Response Encryption

With so many different ways of configuring things one might ask the question how does metro pickup the certificate for response encryption to the client.  So here are the abstract steps that metro uses in that order of preference :  
1. if peeralias is specified then use it (not practical in real world apps since a service would have many clients)  
2. if a certstore was specified then look for the cert in the certstore using the specified CertSelector  
3. if a truststore CertSelector was specified use that to locate the cert  
4. if the request contained a certificate use that certificate for the response  
5. Pick the first one from the truststore (this was a legacy feature from early metro days and it would work well when your truststore has just one cert that of the client :-), you never need to configure anything then, there is a TODO comment to remove this piece of code and we don't expect metro users to use this option)

On step 4 metro currently has a limitation that only if the Certificate of the client appears as a Binary Security Token in the message then metro tries to use it for response encryption. However this can  be improved since even an indirect reference to the client certificate should also cause metro to make use that certificate for response encryption. The opportunity is rare though because usually the server never stores the certificates of its client inside it's certstore/truststores.  


One of the design goals of Metro is to be able to run on any Application Server as a WebServices Stack. One project that i know levarages this ability is OpenSSO. The OpenSSO product is supported on several application servers.  

There are two methods in the JAXWS defined WebServiceContext interface which relate to the Caller Identity (getUserPrincipal()) and Role Membership (isUserInRole()) of the caller respectively. These methods cannot be implemented in a generic manner. This is because the container's representation of the caller principal differs between different application servers. If nothing else the Java Principal class itself would be a container specific one.  

When JSR 196 is enabled in Metro then it actually provides an opportunity to populate the containers representation of the caller principal. This is because Metro would invoke the JSR 196 defined CallerPrincipalCallback. However most usages of Metro on other containers has been without using JSR 196 underneath. So there is a need to override the method getUserPrincipal() on the WebServiceContext for the target container.

The other method which allows users to do programmatic access control is isUserInRole. Java EE specs do not enumerate how principals are to be mapped to roles for the simple reason that there is no unique way of doing this. Different application server's provide different ways of managing the principal to role mapping and there is no standard Java EE API to query the RoleMapping information, add to this the fact that Metro needs to work on Non JavaEE compliant containers such as Tomcat. So the method isUserInRole() on the WebServiceContext again needs to be overriden for the target container.

With latest Metro 2.0 builds you can thus override the default WebServiceContext implementation with a custom one.  The class should implement com.sun.xml.ws.api.server.WebServiceContextDelegate The implementing class should have a Constructor which accepts a delegate of type com.sun.xml.ws.api.server.WebServiceContextDelegate. Note that when Metro is running on GlassFish container there is no need to override WebServiceContext implementation for  JSR 109 webservices.  

Here is a sample, where i ovverride only the getUserPrincipal(). The idea is that one can delegate the implementation of all the other methods on this interface to the default implementation which is passed as a constructor argument and only handle the two security related methods in a container specific way.

import com.sun.xml.ws.api.message.Packet;

import com.sun.xml.ws.api.server.WSEndpoint;

import java.security.Principal;

import java.util.Set;

import javax.security.auth.Subject;

public class WebServiceContextDelegate implements com.sun.xml.ws.api.server.WebServiceContextDelegate {

private static final String AUTH_SUBJECT="javax.security.auth.Subject";

private com.sun.xml.ws.api.server.WebServiceContextDelegate delegate = null;

    public WebServiceContextDelegate(com.sun.xml.ws.api.server.WebServiceContextDelegate delegate) {

        this.delegate = delegate;


    public Principal getUserPrincipal(Packet packet) {

        Subject subject = (Subject)packet.invocationProperties.get(AUTH_SUBJECT);

        if (subject == null) {

             return null;


          Set set = subject.getPrincipals(Principal.class);

          if (set.isEmpty()) { return null; }

         return set.iterator().next();


    public boolean isUserInRole(Packet arg0, String arg1) {

        //TODO: implement isUserInRole as appropriate for the server

        return false;


    public String getEPRAddress(Packet arg0, WSEndpoint arg1) {

         return delegate.getEPRAddress(arg0, arg1);


    public String getWSDLAddress(Packet arg0, WSEndpoint arg1) {

     return delegate.getWSDLAddress(arg0, arg1);



The last step is to configure this WebServiceContext class name. This can be done on a per-application basis by specifying the following META-INF/services entry inside your application WAR. META-INF/services/com.sun.xml.ws.api.server.WebServiceContextDelegate The content of the file com.sun.xml.ws.api.server.WebServiceContextDelegate should be the fully qualified classname of your implementation class. And lastly it is expected that the implementation class is available inside WEB-INF/classes of your application WAR.

 If you are interested in knowing how JSR 196 can be enabled on non GlassFish containers send me a message. Metro has a pluggable security architecture where you can override the default JSR 196 AuthConfigProvider with one of your own. I will probably try to write about it some other day.  

Filter Blog

By date: