X

Technology insights, news and tips.

Recent Posts

Sun

Profiling GlassFish 3 with JProfiler

Recently, I investigated performance issues of GlassFish 3. I found that JProfiler 6 is a very handy tool.In this blog, I would like to share with you what I learnt. I would like to thank Dhiru Pandey and Suveen Nadipalli for their help.In the following, we will assume GlassFish 3 installed in $GLASSFISH_HOME and JProfiler 6 is running on Mac OS 10.5.8.Set up GlassFish 3Insert com.jprofiler.agent, com.jprofiler.agent.*, immediatelyafter ${eclipselink.bootdelegation}, in org.osgi.framework.bootdelegation property in $GLASSFISH_HOME/glassfish3/glassfish/osgi/felix/conf/config.properties.nojaxb. Note that if one were to debug the GlassFish Web Profile - they would need to change$GLASSFISH_HOME/glassfish3/glassfish/osgi/felix/conf/config.properties.Issue 12364is filed on this. Once this bug is fixed only config.properties will need to be modified.Set up JProfile 6 with GlassFish 3Launch JProfiler.In Quickstart menu, choose "An application server, locally or remotely".Choose integration wizard: choose "Glassfish V3".Choose profiled application located: "On this computer".JVM settings: (vendor/version/mode). (Note that GlassFish 3 uses JDK "1.6.x".)Choose "Wait for connection from the JProfiler GUI".Locate the config file: $GLASSFISH_HOME/glassfish3/glassfish/domains/domain1/config/domain.xml.Locate the start script: $GLASSFISH_HOME/glassfish3/glassfish/bin/asadmin.Choose the jprofiler port: 8849 (default).Click "No".JProfile create a script asadmin_jprofiler in $GLASSFISH_HOME/glassfish3/glassfish/bin. In Mac, you may like to double check that the script has execution permission. Run chmod u+x $GLASSFISH_HOME/glassfish3/glassfish/bin/asadmin_jprofiler if necessary.Click "Start Center" > "Open Session" > Double click "Glassfish V3 on localhost" > Session Startup: "Cancel"Click "Session Settings" > "Filter Settings" > "Excluded"Make sure that you do not exclude the classes that you want to profile. For instance, I remove "com.sun.", "org.glassfish.", "org.apache.", "org.jvnet". Click "OK" to save it. Click "Start" for start profiling GlassFish 3. For collecting performance data, "CPU Views" > Press to record CPU dataTips for Viewing and Analyzing DataFor a given class, the most time consuming method is the first one. In general, one may like to look at the most expensive operation first.If one only interests only in profiling certain package, then one can enter the package name in "View Filters" text box near the bottom of the JProfile screen.One can export the tree view of the data into html by clicking "Export" in top menu bar.One can save the data for later comparison by clicking "Save Snapshot".One can open and compare several snapshots at the same time as follows:"Session" > "Open Snapshot" > "New Window"Select the snapshot data file (with extension .jps) > "Open"Can we profile GlassFish 3 with JProfile 5?One can profile GlassFish 3 with JProfile 5. The setup for GlassFish 3 is the same.The setup for JProfile 5 is as follows:Launch JProfiler.Close Quickstart if necessary.Click "Start Center" > "New Session".Fill in the following information and click "OK".Enter the "Session name".Choose "Session Type": Local.Java VM: 1.6.xWorking Directory: $GLASSFISH_HOME/glassfishv3/glassfish/domains/domain1/configVM arguments:-Dcom.sun.aas.installRoot=$GLASSFISH_HOME/glassfishv3/glassfish -Dcom.sun.aas.instanceRoot=$GLASSFISH_HOME/glassfishv3/glassfish/domains/domain1Main class executable JAR: $GLASSFISH_HOME/glassfishv3/glassfish/modules/glassfish.jarThen repeat Step 12 to Step 15 of the setup for JProfile 6 above.Enjoy profiling GlassFish 3.

Recently, I investigated performance issues of GlassFish 3. I found thatJProfiler 6 is a very handy tool.In this blog, I would like to share with you what I learnt. I would like to thank Dhiru Pandey...

Sun

Change Session Id on Authentication in GlassFish

Session fixation attack is a security vulnerabiltiy wherethe victim is tricked to login using the session given bya hacker, then the hacker can use the session after that.Prior to GlassFish v3, one can mininize the exposure ofsession id in url encoding by specifying a session-propertiesin WEB-INF/sun-web.xml:<sun-web-app>  <session-config>    <session-properties>      <property name="enableURLRewriting" value="false" />    </session-properties>  </session-config></sun-web-app>In GlassFish v3,with the support of Servlet 3.0, onecan also achieve above by specifying the tracking-mode in WEB-INF/web.xml:<web-app ...>  ...  <session-config>    <tracking-mode>COOKIE</tracking-mode>  </session-config></web-app>Note that the default tracking-mode in GlassFish v3 is COOKIE and URL.In GlassFish 3.0.1 and GlassFish 3.1, a security feature is ported from Tomcat.One can configure a web application so that the session id will be changed afterauthentication. This mininizes the session fixation attack.One can achieve this by configuring META-INF/context.xml in war file. For instance,<?xml version="1.0" encoding="ISO-8859-1"?><Context>  <Valve className="org.apache.catalina.authenticator.FormAuthenticator" changeSessionIdOnAuthentication="true"/></Context>The above example used form based login. If BASIC is used, then the className should beorg.apache.catalina.authenticator.BaseAuthenticator.

Session fixation attack is a security vulnerabiltiy where the victim is tricked to login using the session given by a hacker, then the hacker can use the session after that. Prior to GlassFish v3, one...

Sun

Https outbound connection from GlassFish Enterprise Server v2 to Oracle GlassFish Server 3.0

Oracle GlassFish Server 3.0 is a Java EE 6 container.It uses JKS as keystore. In GlassFish Enterprise Server v2, it usesNSS.In this simple blog, we will show how to set up environments for https outbound connection fromGlassFish v2 to Oracle GlassFish Server 3.0.Export the certificate from Oracle GlassFish Server 3.0 from JKS.Change to domain config directory where one can find cacerts.jks and run the following command:keytool -export -rfc -alias s1as -file s1asv3.cert -keystore cacerts.jks -storepass changeitNote that one should let keytool prompt for password rather than using -storepass. It is used here for illustration.Import the certificate to GlassFish Enterprise Server v2.Note that one need to use a different alias name "s1asv3" as there is already a certificate of name "s1as" in NSS db. Change to the domain config directory where one can find cert8.db and run the following command:certutil -A -n s1asv3 -d . -i s1asv3.cert -t "T,c,c"Restart the GlassFish Enterprise Server.I find that the following jsp testing code is quite handy. It is included here for convenience:<%@page import="java.io.\*, java.net.\*, javax.net.ssl.\*" %><%    try {        String host = request.getParameter("host");        String port = request.getParameter("port");        String urlStr = "https://" + host + ":" + port;        out.println("Url = " + urlStr + "<hr>");        URL url = new URL(urlStr);        HttpURLConnection connection = (HttpURLConnection)url.openConnection();        BufferedReader in = null;        in = new BufferedReader(new InputStreamReader(connection.getInputStream()));        String line = "";        while ((line = in.readLine()) != null) {            out.println(line);            } catch(Throwable ex) {        out.println("<hr><pre>");        ex.printStackTrace(new PrintWriter(out));    }%> Note that one can read more about GlassFish Enterprise Server v2 and NSS in"Key Management and PKCS#11 Tokens in Sun Java System Application Server 8.1".

Oracle GlassFish Server 3.0 is a Java EE 6 container. It uses JKS as keystore. In GlassFish Enterprise Server v2, it usesNSS.In this simple blog, we will show how to set up environments for https...

Sun

Follow up on Servlet 3.0 Security Annotations

In May 2009, I discussed the Servlet 3.0 security annotations in one of my blogs,Servlet 3.0 Security Annotations.At that time, the annotations were defined similar to those in EJB. During the discussion in JSR 315 expert group, two issues were identified as follows:In JSR 250, type level annotations only apply to methods declared in that class, not those inherited. This is an issue for servlets as they extend javax.servlet.http.HttpServlet.The doGet method et al may not correspond to http method GET et al as the logic can be overrided in service method of the servlet.Thanks to Ronald Monzilo for discussions in Servlet 3.0 security.The following is the update on Servlet 3.0 security annotations:As in servlet 2.5, @DenyAll, @PermitAll, @RolesAllowed will not apply to servlets. @TransportProtected will not be added to JSR 250.The following new annotations will be added to javax.servlet.annotation:ServletSecurityHttpConstraintHttpMethodConstraint Note that @ServletSecurity is a type level annotation and the rests are used as parameters in @ServletSecurity.With the above new annotations, one can resolve the issue mentioned above. In addition, it covers the new use case where one want to have security constraint for extended http methods only, for instance FOO.In this blog, I will illustrate how those annotation work. For convenient of readers of my previous blogs, I will first illustrate the four scenarios mentioned in my previous blog, Servlet 3.0 Security Annotations with the new annotations. Then I have an additional example.Example 1: For all Http Methods@WebServlet("/myurl")@ServletSecurity(@HttpConstraint(rolesAllowed={"javaee"}))public class TestServlet extends HttpServlet {    ...}In this case, all http methods are protected and accessible only by users with role javaee.Example 2: Http Method Level@WebServlet("/myurl")@ServletSecurity(httpMethodConstraints={ @HttpMethodConstraint("GET"),    @HttpMethodConstraint(value="POST", rolesAllowed={"javaee"}),    @HttpMethodConstraint(value="TRACE", emptyRoleSemantic=ServletSecurity.EmptyRoleSemantic.DENY) })public class TestServlet extends HttpServlet {    protected void doGet(HttpServletRequest req, HttpServletResponse res)            throws IOException, ServletException {        ...    }    protected void doPost(HttpServletRequest req, HttpServletResponse res)            throws IOException, ServletException {        ...    }    protected void doTrace(HttpServletRequest req, HttpServletResponse res)            throws IOException, ServletException {        ...    }}The behaviors of the above servlet can be summarized as follows:Http methodBehaviorGETall can access GET methodPOSTonly authenticated users with role javaee can access POST methodTRACEno one can access TRACE methodExample 3: A General Constraint for all Http methods with some Exceptional Cases@WebServlet("/myurl")@ServletSecurity(value=@HttpConstraint(rolesAllowed={"javaee"}),     httpMethodConstraints={ @HttpMethodConstraint(value="POST", rolesAllowed={"staff"}),    @HttpMethodConstraint("TRACE") })public class TestServlet extends HttpServlet {    ...    protected void doPost(HttpServletRequest req, HttpServletResponse res)            throws IOException, ServletException {        ...    }    protected void doTrace(HttpServletRequest req, HttpServletResponse res)            throws IOException, ServletException {        ...    }}The behaviors of the above servlet can be summarized as follows:Http methodBehaviorPOSTonly authenticated users with role staff can access POST methodTRACEall can access TRACE methodmethods other than POST and TRACEonly authenticated users with role javaee can accessNote that in the previous definitions, the exceptional cases must be the standard http methods. There is no such restriction for the new annotations as illustrated by the Example 5 below.Example 4: Https and protected for a given role@WebServlet("/myurl")@ServletSecurity(value=@HttpConstraint(    transportGuarantee=ServletSecurity.TransportGuarantee.CONFIDENTIAL),     httpMethodConstraints={ @HttpMethodConstraint(value="TRACE", transportGuarantee=ServletSecurity.TransportGuarantee.NONE, rolesAllowed={"javaee"}) })public class TestServlet extends HttpServlet {    ...    protected void doTrace(HttpServletRequest req, HttpServletResponse res)        throws IOException, ServletException {        ...    }}The behaviors of the above servlet can be summarized as follows:Http methodBehaviorTRACEHttps is supported. It just is not required. Only authenticated users with role javaee can access TRACE methodmethods other than TRACErequire httpsExample 5: Protect FOO only@WebServlet("/myurl")@ServletSecurity(value=@HttpConstraint,    httpMethodConstraints={ @HttpMethodConstraint(value="FOO", rolesAllowed={"javaee"}) })public class TestServlet extends HttpServlet {    ...}The behaviors of the above servlet can be summarized as follows:Http methodBehaviorFOOonly authenticated users with role javaee can access POST methodmethods other than FOOall can access

In May 2009, I discussed the Servlet 3.0 security annotations in one of my blogs, Servlet 3.0 Security Annotations. At that time, the annotations were defined similar to those in EJB.During the...

Sun

Servlet 3.0 web-fragment.xml

In JSR 315: Java Servlet 3.0 Specification, web-fragment.xml is introduced for pluggability of library jars which arepackaged under WEB-INF/lib.The content of web.xml and web-fragment.xml are almost the same.One can define servlets, filters and listeners there. One can also specifymetadata-complete=true in a given web-fragment.xml.In the latter case, the annotation processing of classes in that jar would be skipped.With web-fragment.xml, library jars can be self-contained and provide webrelated metadata information.The basic differences of web.xml andweb-fragment.xml are summarized in the following table: web.xmlweb-fragment.xmlLocationWEB-INF of the war fileMETA-INF directory of JAR file inside WAR file's WEB-INF/libOrdering related element<absolute-ordering><ordering>Ordering of web fragmentsIf there are more than one web-fragment jars, then one may like to specify the order of processing web-fragment.xml and annotations.This is important. For instance, filters will be executed in the order specified inweb.xml.Similary for listeners. In Servlet 3.0, <absolute-ordering> is introduced inweb.xml and <ordering> is introduced in web-fragment.xml.The ordering of web-fragments is specified in the following priority:from <absolute-ordering> in web.xml if it existsfrom <ordering> for each web-fragment.xml if it existsotherwise unspecifiedabsolute-ordering in web.xmlThe <absolute-ordering> in web.xml provides a way to specifythe ordering of loading web-fragment.xml and annotation processingof web fragment.For instance, <web-app>    ...    <absolute-ordering>        <name>A</name>         <others/>        <name>B</name>    <absolute-ordering></web-app>In the above example, the web fragment A would be processed firstand web fragment B would be processed last.Note the name A and B are specified in name element ofweb-fragment.xml (see examples below).ordering in web-fragment.xmlIf there is no <absolute-ordering> in web.xml, then one would look at<ordering> in web-fragment.xml. The details are described insection 8.2.3 of Servlet 3.0 spec.Let us look at some examples.There is only one jar having <ordering> in web-fragment.xml. <web-fragment>    <name>A</name>    ...    <ordering>        <before>            <others/>        </before>    </ordering></web-fragment> In this case, web-fragment A would be processed first.There are two jars having <ordering> in web-fragment.xml, namelyweb-fragment A: <web-fragment>    <name>A</name>    ...    <ordering>        <before>            <others/>        </before>    </ordering></web-fragment> web-fragment B: <web-fragment>    <name>B</name>    ...    <ordering>        <before>            <others/>        </before>    </ordering></web-fragment> Both web-fragment A and B would like to be processed first. In this case, one only guarantee that both A and B are processed before other web-fragments. But the ordering of A and B are not determined, that is arbitrary in this case.There are two jars having <ordering> in web-fragment.xml, namelyweb-fragment A: <web-fragment>    <name>A</name>    ...    <ordering>        <before>            <others/>        </before>    </ordering></web-fragment> web-fragment B: <web-fragment>    <name>B</name>    ...    <ordering>        <after>            <name>A</name>        </after>        <before>            <others/>        </before>    </ordering></web-fragment> In this case, A would be processed first, then followed by B, and then other web-fragments.If one would like to have a deterministic ordering, then I would recommend to useabsolute-ordering in web.xml.

In JSR 315: Java Servlet 3.0 Specification,web-fragment.xml is introduced for pluggability of library jars which are packaged under WEB-INF/lib. The content of web.xml and web-fragment.xml are almost...

Sun

Servlet 3.0 Security Annotations

Update: The security annotations have been changed. The updated information can be found in my blog, Follow up on Servlet 3.0 Security Annotations.In Servlet 2.5, only @DeclareRoles and @RunAs are supported in servlets.And @DenyAll, @PermitAll, @RolesAllowed are only supported for EJBs.In JSR 315: Java Servlet 3.0 Specification,@DenyAll, @PermitAll, @RolesAllowed will be supported in servlets.Furthermore, it supportsJSR 250: Common Annotations for the Java Platform MR1:@TransportProtected, a new annotation indicates whether the transport is confidential or none.@DenyAll will also be available at the TYPE level.The mapping of the @DenyAll, @PermitAll, @RolesAllowed and @TransportProtected tosecurity constraint are described in Chapter 13.4.1 ofServlet 3.0 specification.These annotations can be applied to:the servlet classone of the following methods in HttpServlet:doDelete doGetdoHeaddoOptionsdoPostdoPutdoTraceNote that method level authorization annotations (@DenyAll, @PermitAll, @RolesAllowed) override those in class level for the associated http method.Similarly, method level @TransportProtected overrides the one in class level.In this blog, we illustrate the usages of these annotations by examples.Example 1: Type Level@WebServlet("/myurl")@RolesAllowed("javaee")public class TestServlet extends HttpServlet {    ...}In this case, all http methods are protected and accessible only by users with role javaee.Example 2: Method Level@WebServlet("/myurl")public class TestServlet extends HttpServlet {    @PermitAll    protected void doGet(HttpServletRequest req, HttpServletResponse res)            throws IOException, ServletException {        ...    }    @RolesAllowed("javaee")    protected void doPost(HttpServletRequest req, HttpServletResponse res)            throws IOException, ServletException {        ...    }    @DenyAll    protected void doTrace(HttpServletRequest req, HttpServletResponse res)            throws IOException, ServletException {        ...    }}The behaviors of the above servlet can be summarized as follows:Http methodBehaviorGETall can access GET methodPOSTonly authenticated users with role javaee can access POST methodTRACEno one can access TRACE methodExample 3: Type and Method Level@WebServlet("/myurl")@RolesAllowed("javaee")public class TestServlet extends HttpServlet {    ...    @RolesAllowed("staff")    protected void doPost(HttpServletRequest req, HttpServletResponse res)            throws IOException, ServletException {        ...    }    @PermitAll    protected void doTrace(HttpServletRequest req, HttpServletResponse res)            throws IOException, ServletException {        ...    }}The behaviors of the above servlet can be summarized as follows:Http methodBehaviorPOSTonly authenticated users with role staff can access POST methodTRACEall can access TRACE methodmethods other than POST and TRACEonly authenticated users with role javaee can accessExample 4: @TransportProtected and @RolesAllowed@WebServlet("/myurl")@TransportProtectedpublic class TestServlet extends HttpServlet {    ...    @TransportProtected(false)    @RolesAllowed("javaee")    protected void doTrace(HttpServletRequest req, HttpServletResponse res)        throws IOException, ServletException {        ...    }}The behaviors of the above servlet can be summarized as follows:Http methodBehaviorTRACEno https, only authenticated users with role javaee can access TRACE methodmethods other than TRACErequire https

Update: The security annotations have been changed. The updated information can be found in my blog, Follow up on Servlet 3.0 Security Annotations. In Servlet 2.5, only @DeclareRoles and @RunAs are...

Sun

Using Jetty Bayeux Client in GlassFish v3

In Cometd environment, one can access cometd services through simple Javascript,Java API for Bayeux Protoc,DOJO, etc.In the Grizzly Issue 174,developer amplus has contributed a first porting of Jetty Bayeux Java Client toGrizzly.A modification of the contribution has been checkin to Grizzly.The above client code is based on Jetty 6.1.11.Subsequently, various cometd bugs has been fixed in Grizzly 1.9.8 or later.In this blog, we will describe how to use the Jetty Bayeux client in Grizzly withGlassFish v3.Environment SettingIn this moment, comet support is turned off by default.The comet/cometd can be turned on in GlassFish v3 by adding the following property to corresponding http-listener. In our case, it is the http-listener-1.     <property name="cometSupport" value="true"> Note that it is recommended that one should set the above property by using asadmin rather than directly editing the domain.xml. For instance,     asadmin set server.http-service.http-listener.http-listener-1.property.cometSupport=trueDownload the following jars and put it under $GLASSFISH_HOME/domains/domain1/lib:grizzly-cometd-client-1.9.8.jarcometd-bayeux-6.1.11.jarjetty-6.1.11.jarjetty-client-6.1.11.jarjetty-util-6.1.11.jarThe first jar is from Grizzly repository.Note that you may like to get the correct Grizzly version working with your GlassFish v3.(For instance, one can find out the Grizzly version in MANIFEST.MF of web-glue.jar.)The remaining jars are fromJetty repository 6.1.11.Finally, we have to start the server.A Cometd client application using Jetty Bayeux clientIn our example, we will create a web Bayeux Client forCometd Chat Sample.It can be downloaded here.One need to import Jetty's classes as follows:     import org.mortbay.cometd.AbstractBayeux;    import org.mortbay.cometd.client.BayeuxClient;    import org.mortbay.jetty.client.HttpClient;    import org.mortbay.thread.QueuedThreadPool;    import org.mortbay.util.ajax.JSON;    import dojox.cometd.Bayeux;    import dojox.cometd.Client;    import dojox.cometd.Message;    import dojox.cometd.MessageListener;Then one need to create a BayeuxClient in as follows:Create a HttpClient.     httpClient = new HttpClient();    httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);    httpClient.setMaxConnectionsPerAddress(50);Create a QueuedThreadPool for the HttpClient.     QueuedThreadPool pool = new QueuedThreadPool();    pool.setMaxThreads(50);    pool.setDaemon(true);    httpClient.setThreadPool(pool);Start the HttpClient and create a BayeuxClient.     httpClient.start();    client = new BayeuxClient(httpClient, address, cometdUri) {        public void deliver(Client from, Message message) {            // do something            super.deliver(from, message);        }    };where address is an InetSocketAddress and cometdUri is the cometd service uri.Create a MessageListener for the BayeuxClient.     MessageListener listener = new MessageListener() {        public void deliver(Client fromClient, Client toClient, Message msg) {            Object data = msg.get(AbstractBayeux.DATA_FIELD);            if (data != null) {               // do something           }       }    };    client.addListener(listener);This listener is a no-op as we only use the client to send message in our case.Start the BayeuxClient and subscribe the channel.     client.start();    client.subscribe(channel);With the setup above, the JSON message can be published as follows:     Object msg=new JSON.Literal("{\\"user\\":\\"" + name + "\\",\\"chat\\":\\"" + chat + "\\"}");    client.publish(channel, msg, String.valueOf(mid.getAndIncrement()));where msg is a JSON object associated to data.Comparison with Java API for Bayeux ProtocolIn this section, we will compare Jetty Bayeux client with the Java API for Bayeux Protocol.For convenience, I will summarize the Java API for Bayeux Protocol as follows:Get the CometContext.     CometEngine context = CometEngine.getEngine().getCometContext(channel);Create the DeliverResponse.     Map map = new HashMap();    map.put(messageDataName, messageDataValue);    Data data = new Data();    data.setMapData(map);    DeliverResponse deliverResponse = new DeliverResponse();    deliverResponse.setChannel("/service/echo");    deliverResponse.setClientId(clientId);    deliverResponse.setData(data);    deliverResponse.setLast(true);    deliverResponse.setFollow(true);    deliverResponse.setFinished(true);Note that in this moment, one has to setFinished(true) in addition to setLast(true).Notify the deliverResponse    context.notify(deliverResponse); Jetty Bayeux ClientJava API for Bayeux ProtocolSetupmore involvedsimpleAccess Cometd Servicelocal and remotelocalClientin server and standlonein serverConstruction of JSON messagessome explicitlyall use API

In Cometd environment, one can access cometd services throughsimple Javascript,Java API for Bayeux Protoc, DOJO, etc. In the Grizzly Issue 174, developer amplus has contributed a first porting...

Sun

Servlet 3.0 Annotations

The JSR 315: Java Servlet 3.0 Specificationexpert group is in the process of makingPublic Review available. You can look at Rajiv's blog for more details.The reference implementation is availablein GlassFish v3 nightly build.In Servlet 3.0, for ease of development, several new annotations are defined.These annotations are resided in the package javax.servlet.annotation.They are intended to provide meta data only. In other words, one still needto extend the corresponding class or implement the corresponding interface.Now, one can have Servlet, Filterand ServletContextListener in a war file without web.xml.In this blog, I will discuss the following annotations:@WebServlet@ServletFilter@WebServletContextListenerServlet Annotation ( @WebServlet )In JSR 315, one can specify the servlet meta data by using @WebServlet.For instance,    @WebServlet(name="mytest",        urlPatterns={"/myurl"},        initParams={ @InitParam(name="n1", value="v1"), @InitParam(name="n2", value="v2") })    public class TestServlet extends javax.servlet.http.HttpServlet {        ....    }In this example, the class TestServlet is a servlet as itextends HttpServlet. The @WebServlet provides the following meta data:the name of the servlet, mytest, corresponds to <servlet-name> under <servlet> in web.xmlthe url pattern of the servlet, /myurl, corresponds to <url-pattern> under <servlet-mapping> in web.xmlinitialization parameters of the servlet, n1=v1, n2=v2, corresponds to <init-param> under <servlet> in web.xml  <init-param>    <param-name>n1</param-name>    <param-value>v1</param-value>  </init-param>  <init-param>    <param-name>n2</param-name>    <param-value>v2</param-value>  </init-param>Note that in this case, @InitParam is used to specify the name/value pairs.Servlet Filter Annotation ( @ServletFilter )One can specify the servlet filter meta data by using @ServletFilter.For instance,    @ServletFilter(urlPatterns={"/myurl"}.         initParams={ @InitParam(name="mesg", value="my filter") })    public class TestFilter implements javax.servlet.Filter {        ....        public void init(FilterConfig filterConfig) throws ServletException {            ....        }        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {            ....        }        public void destroy() {            ....        }    }In this example, the class TestFilter is a servlet filter as itimplements Filter.The @ServletFilter provides the following meta data:the url pattern of the filter applied, /myurlinitialization parameter of the filter, mesg=my filter, corresponds to <init-param> under <filter> in web.xmlNote that in this case, @InitParam is used to specify the name/value pairs.Servlet Context Listener Annotation ( @WebServletContextListener )One can specify the servlet content listener met data by using @WebServletContextListener. For instance,    @WebServletContextListener    public class TestServletContextListener implements javax.servlet.ServletContextListener {        ....        public void contextInitialized(ServletContextEvent sce) {            ....        }        public void contextDestroyed(ServletContextEvent sce) {            ....        }    }In this example, the class TestServletContextListener is a servletcontext listener as it implements ServletContextListener.The @WebServletContextListener provides the meta data that this is a servlet context listener in a given war file.

The JSR 315: Java Servlet 3.0 Specification expert group is in the process of making Public Review available. You can look at Rajiv's blog for more details. The reference implementation is availablein...

Sun

compression and compressionMinSize in GlassFish v3

In Enabling HTTP Compression in GlassFish,Jean-Francois discussed about compression inGlassFish.There are four properties to configure compression, namely:compressioncompressionMinSize (in OCTET)compressableMimeTypenoCompressionUserAgentsOne can turn compressionon and off by setting compression = force andcompression = off respectively.And one can also turn on the compressionif the content-length is unknown or known to be greater than a certain size.There are two properties related to this: compression and compressionMinSize.In this blog, we will discuss various ways to accomplish this scenarioin GlassFish v3.compression vs compressionMinSizepropertypossible value if setDefaultcompressionon, force, off, integeroffcompressionMinSizeinteger2048There are several possible combinations. We will summarize the behaviorsof GlassFish v3 in the below table.In the following, α and β are integers.compressioncompressionMinSizeResultonβcompression with min size βonnot setcompression with default min size (2048)forceβ or not setcompression with no size constraintαβ or not setcompression with min size α off or not setβ or not setno compression So, roughly speaking, whenever there is conflictinginformation between compression and compressionMinSize, thecompression property will take precedence.Since we use strict inequality to check for knowncontent length, the following are equivalent:compression = forcecompression = on and compressionMinSize = any negative integerHow to test it?If one has turned on compression in GlassFish, then one will get HTTPcompression if the HTTP request isusing HTTP 1.1with a HTTP header:    Accept-Encoding: gzipthe content-length is unknown or greater than the compression minimum size(or compression = force)One can confirm that there is a HTTP compression by using Firefox with Firebug.There will be a HTTP response header:Content-Encoding: gzipNote that one can also notice some changes in HTTP responsefor HTTP compression by using the http client posted in one of my previousblogs.

In Enabling HTTP Compression in GlassFish, Jean-Francois discussed about compression inGlassFish. There are four properties to configure compression, namely: compression compressionMinSize (in OCTET) co...

Sun

WEBDAV in GlassFish

WEBDAV (RFC 4918)protocol is a predecessor to HTTP/1.1 for management resources, etc.The WEBDAV code in GlassFishworkspace is based on Tomcat. Jean-Francois blogged about thisin 2006.WEBDAV Level 2 will be a supported feature in GlassFish v3.In this blog, we would provide additonal information about WEBDAV inGlassFish v3.Configuration of WebDAVServletWEBDAV can be enabled by specifying theorg.apache.catalina.servlets.WebdavServlet in web.xmlfor a given web application.Also, it can be enabled and configured globally indefault-web.xml.One can configure WebDAVServlet by specifying the init-param as follows:init-paramTypeDescriptionDefaultdebugintdebug level0 (no debug)listingsbooleanwhether one can list resourcesfalsereadonlybooleanwhether resources are readonlytrueIt is important to note thatwhen listings is set to trueor readonly is set to false, one mustset up security constraints and turn on security manager.WEBDAV ClientsI have verified that the following WEBDAV clients work with GlassFish v3:Microsoft Word 2002 and 2003  File > Open > the urlInternet Explorer 6 and 7  File > Open (check "Open as Web Folder") > the urlNote that under "Internet Options > Programs > HTML editor", we may like to set it to Microsoft Word above or Mircrosoft FrontPage. Hand-On Examples on WEBDAV protocolWEBDAV includes the following HTTP methods:PROPFINDPROPMATCHMKCOLGETHEADPOSTDELETEPUTCOPYMOVELOCKUNLOCKI find that it is a good exercise to send HTTP requests directly andsee what happens there. For instance,the following HTTP request copy index.html to index2.html:COPY /webdavtest/index.html HTTP/1.1Host: localhostDestination: http://localhost:8080/webdavtest/index2.htmlConnection: closethe following HTTP request delete the index2.html created above:DELETE /webdavtest/index2.html HTTP/1.1Host: localhostConnection: closeThere are many ways to send http client requests to server.I find that it is quite handy to have the following Ruby script.  #!/usr/bin/ruby    require "socket"  if ARGV.length != 3      puts "ruby httpclient.rb <host> <port> <http request file>\\n"      exit  end  host = ARGV[0];  port = ARGV[1].to_i;  filename = ARGV[2];  socket = TCPSocket.open(host, port)  file = File.new(filename)  while line = file.gets      command = line.chomp      puts command + "\\r\\n"      socket.write(command + "\\r\\n")  end  puts socket.readlines  socket.closeNote that you may like to update the path of ruby orrun the interpretator directly.

WEBDAV (RFC 4918) protocol is a predecessor to HTTP/1.1 for management resources, etc. The WEBDAV code in GlassFish workspace is based on Tomcat. Jean-Francois blogged about this in 2006.WEBDAV Level...

Sun

Common Gateway Interface in GlassFish

Common Gateway Interface (CGI)supports dynamic contents in web environment.CGI programs are executable programs in the server platform with specific output.It can be a Bourne shell script, Perl script or even a C binary executable.It was very popular before the the appearance of Servlet, JSP and PHP.The CGI code in GlassFishworkspace is based on Tomcat.In GlassFish v3, CGI will be a supported feature.Let us look at a very simple example.Create a CGI scriptIn our example, we have a simple Perl program,hello, to print a hello message and the timestampof the server.    #!/bin/perl    print "Content-type: text/html\n\n";    print "Hello World: ";    print scalar localtime;    print "\n";Enabling CGI processing and packaging the war fileThe CGI processing can be enabled in a war file by adding CGIServlet et al in web.xml as follows:  <web-app>    <servlet>      <servlet-name>cgi</servlet-name>      <servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>    </servlet>    <servlet-mapping>      <servlet-name>cgi</servlet-name>      <url-pattern>/cgi-bin/*</url-pattern>    </servlet-mapping>  </web-app>In this case, one need to package the hellounder the default cgiPathPrefix which is WEB-INF/cgi.For security, it is highly recommended that the contents / binaries of CGI programs should be prohibited from direct viewing or download.Alternatively, one can enable CGI by uncommenting the corresponding sectionsin default-web.xml.In our case, the CGI program can beinvoked through http://localhost:8080/YOUR_CONTEXT/cgi-bin/hello .Configuration of CGIServletOne can configure CGIServlet by specifying the init-param as follows:init-paramTypeDescriptionDefaultcgiPathPrefixStringsubdirectory containing the cgi programsWEB-INF/cgidebugintdebug level0 (no debug)executableStringexecutable for running the CGI scriptperlparameterEncodingStringencoding use for parameterSystem.getProperty("file.encoding", "UTF-8")passShellEnvironmentbooleanwhether to pass environment properties to CGI programfalseCGI with native executablesGlassFish v3 CGI can work with native executables as follows:set the init-param with name executable to be the empty String in web.xmlhas exploded directory structure for the war in a directory, say /export/cgitestmake sure those executables has the executable bits set correctlydeploy the "directory" (not the "war"), for instanceasadmin deploy /export/cgitestNote that one works with the exploded directory structure rather than war file as the executable bits information is lost during the process ofjar and unjar.

Common Gateway Interface (CGI) supports dynamic contents in web environment. CGI programs are executable programs in the server platform with specific output.It can be a Bourne shell script, Perl...

Sun

Server Side Include in GlassFish

Server Side Include (SSI)allows including dynamic contents in html.SSI and CGI were very popular before the the appearance of JSP and PHP.The SSI code in GlassFishworkspace is based on Tomcat.In GlassFish v3, SSI will be a supported feature.Let us look at a very simple example.Create a SSI fileIn our example, we create a index.shtml whichincludes the content of header.html,prints a Hello message with server side timestamp, andexecutes a command say, uname (or any command in your operating system).The page is as follows:     <!--#include virtual="header.html"-->    <br>Hello, it is <!--#echo var="DATE_LOCAL"-->.    <br>Result: <!--#exec cmd="uname"-->Note that the extension shtml is configurablein web.xml (see servlet-mapping below).Enable SSI processingThe SSI processing can be enabled in a war file by addingSSIServlet et al in web.xml as follows:  <web-app>    <servlet>      <servlet-name>ssi</servlet-name>      <servlet-class>org.apache.catalina.ssi.SSIServlet</servlet-class>    </servlet>    <servlet-mapping>      <servlet-name>ssi</servlet-name>      <url-pattern>*.shtml</url-pattern>    </servlet-mapping>    <mime-mapping>      <extension>shtml</extension>      <mime-type>text/html</mime-type>    </mime-mapping>  </web-app>One can find more details about the configuration of SSIServlet inthe section below.Alternatively, one can enable SSI by uncommenting the corresponding sectionsin default-web.xml.Note that the mime-mapping is to notify the browserthat the result of shtml file is of content-type: text/html.If you don't specify this, then GlassFish will try to get themime-type from default-web.xml orthe default in the system.Configuration of SSIServletOne can configure SSIServlet by specifying the init-param as follows:init-paramTypeDescriptionDefaultbufferedboolean (or String converted to boolean)whether the output should be bufferedfalsedebugintrepresents debug level0 (no debug)expiresLongexpiration time in secondsdo not set "Expires" header in Http ResponseinputEncodingStringencoding for SSI input if there is no URL content encoding specifiedserver platform encodingisVirtualWebappRelativeboolean (or String converted to boolean)whether the "virtual" path of "#include" directive is relative to content-rootfalse (means relative to the given SSI file)outputEncodingStringencoding for SSI outputUTF-8

Server Side Include (SSI) allows including dynamic contents in html. SSI and CGI were very popular before the the appearance of JSP and PHP. The SSI code in GlassFish workspace is based on Tomcat.In...

Sun

Java API for Bayeux Protocol

In Cometd environment, one communicates throughBayeux Protocol.The protocol is currently in 1.0 draft 1.GlassFish v3 hasincorporated implementation of Bayeux fromGrizzly.Jean Francois already has several good blogs on Cometd on Grizzly.In this blog, we are going to illustrate how to send a Bayeuxmessage to a Cometd client by using Java API without writingany JSON code.Basic set upDownload GlassFish v3 from GlassFish website.And add the following property to your http-listenerin domain.xml as follows:    <property name="cometSupport" value="true"/>Start the server by "one" of the following:asadmin start-domain domain1java -jar glassfish-10.0-SNAPSHOT.jarOne also need a Cometd web application. In this blog,we will use the grizzly-cometd-echo sample. Just download the war file and deploy as follows:    asadmin deploy grizzly-cometd-echo-1.7.3.2.warGenerate a Bayeux MessageIn our example, we will generate a cometd message in a servlet,TestServlet.java. The cometdmsgtest.war file and source codes are available here.As usual, one can get a CometContext as follows:    CometEngine engine = CometEngine.getEngine();    CometContext context = engine.getCometContext(contextPath);In our case, the contextPath is "/cometd/cometd" where the first "/cometd" is context root of the grizzly-cometd-echo.One construct a Bayeux response message by using classes in package com.sun.grizzly.cometd.bayeux. The classes that we need to use are DeliverResponse and Data. It is constructed as follows:    Map map = new HashMap();    map.put(messageDataName, messageDataValue);    Data data = new Data();    data.setMapData(map);    DeliverResponse deliverResponse = new DeliverResponse();    deliverResponse.setChannel("/service/echo");    //deliverResponse.setClientId("");    deliverResponse.setData(data);    deliverResponse.setLast(true);    deliverResponse.setFollow(true);Note that"/service/echo" is the channel name of grizzly-cometd-echo sample.If one is not using an updated version of GlassFish,then one may need to calldeliverResponse.setClientId("") to workaround a bug. deliverResponse.setLast(true) indicatesthat this is the last Bayeux message in this Http response.deliverResponse.setFollow(true) indicatesthat this is not the first Bayeux message in this Http response. In our case, the previous message is/meta/connect.Then one can send the Bayeux message as follows:    context.notify(deliverResponse);How to run the testUse browser A1 to access the grizzly sample application by http://localhost:8080/cometd. One can type a message on the text box and see that it is echoed through Bayeux protocol.Repeat the above in browser A2.Use browser B to access the cometd message application by http://localhost:8080/cometdmsgtest. One can type a message in the text box and see that it appears in browser A1 and browser A2.

In Cometd environment, one communicates throughBayeux Protocol. The protocol is currently in 1.0 draft 1.GlassFish v3 has incorporated implementation of Bayeux fromGrizzly.Jean Francois already has...

Sun

Follow up on A Simple Comet Example: Long Polling vs Http Streaming

In my previous comet blog,A Simple Comet Example: Hidden Frame and Long Polling",I illustrate comet by using a simple example of two frames.While it is good for illustration, there is a limitation.If you try to use two different browsers to access the counter and click really fast, then you may notice that one of the counter maybe updated and then immediately changes to blank.This is because the comet response may come before the response of the http post. This is more significant in the case of HttpStreaming.In this blog, we will explain how to resolve "blank problem" and change the example to use Http Streaming instead of Long Polling.One More FrameThe "counter blank" problem can be solved easily by extracting the post action and put it in a different frame (button.html). In other words, we only keep the display related stuff in count.html.In this case, post request is sent from button.html, not from count.html. And hence, count.html will only be updated by JavaScript only. (In contrast with my previous blog, the count.html can also be updated by Http Response.)Now, in index.html, there will three frames as follows:    <iframe name="hidden" src="hidden_comet" frameborder="0" height="0" width="100%"><iframe>    <iframe name="counter" src="count.html" frameborder="0" height="70%" width="100%"><iframe>    <iframe name="button"src="button.html" frameborder="0" height="30%" width="100%"><iframe>The next thing we need to do is to update one line of Java code in the doPost of the servlet to redirect back to button.html rather than count.html.    req.getRequestDispatcher("button.html").forward(req, res);You can download the updated sample here.Http StreamingHttp Streaming is different from Long Polling by keeping the connection (until expiration) between client and server even after it delivers the data.In general, this will perform better.With the fix in the previous section, we can modify our example easily to Http Streaming by commenting out the followingevent.getCometContext().resumeCometHandler(this); in HiddenCometHandle.javaIn this case, the server will not resume the connection.parent.hidden.location.href = "hidden_comet" in updateCount JavaScriptIn this case, the browser will not reload the hidden frame again.I have make a comment in the source codes. One can locate the above easily.

In my previous comet blog, A Simple Comet Example: Hidden Frame and Long Polling", I illustrate comet by using a simple example of two frames. While it is good for illustration, there is a limitation.I...

Sun

A Simple Comet Example: Hidden Frame and Long Polling

Recently, there is a great interest in Comet technology.One can find many interesting articles in Comet Daily.Comet allows server and client to keep a live connection for communication.This provides a mechanism for server to update clients, instead ofhaving classical polling.In this blog, I am going to share my experience about using Cometwith hidden frame and long polling inGlassFish v3 Technology Preview 2 builds.I try to make example as simple as possible to illustrate the basic interactions there. If you want to learn more about Comet, then I recommendJean-Francois' blogs.Set up GlassFish v3Download GlassFish v3 Technology Preview 2, unzip the file and start the server with jvm option v3.grizzlySupport=true to enable comet.    java -Dv3.grizzlySupport=true -jar glassfish-10.0-SNAPSHOT.jarWe need the above jvm-option in today's build. This will not be needed when comet is enabled by default.Comet Servlet CodeThe comet servlet code is adapted from grizzly sample comet-counter, which uses Ajax client. The details of our serlvet is as follows:In init(ServletConfig), one registers a context path to CometEngine,    ServletContext context = config.getServletContext();    contextPath = context.getContextPath() + "/hidden_comet";    CometEngine engine = CometEngine.getEngine();    CometContext cometContext = engine.register(contextPath);    cometContext.setExpirationDelay(30 \* 1000); where "/hidden_comet" is url-pattern of the comet servlet in web.xml. For testing purpose, one keeps the connection for 30 sec.In doGet(HttpServletRequest, HttpServletResponse), one looks up the CometContextand adds our CometHandler.    CounterHandler handler = new CounterHandler();    handler.attach(res);    CometEngine engine = CometEngine.getEngine();    CometContext context = engine.getCometContext(contextPath);    context.addCometHandler(handler);In doPost(HttpServletRequest, HttpServletResponse), one increments the counter and then invokes the CometContext.notify, which will trigger the CometHandler.onEvent above.    counter.incrementAndGet();    CometEngine engine = CometEngine.getEngine();    CometContext<?> context = engine.getCometContext(contextPath);    notify(null); In addition, it forwards to count.html page for displaying the count.    req.getRequestDispatcher("count.html").forward(req, res);Next, one need to have a class implementing CometHandler interface. Among methods in CometHandler,the most interesting one is onEvent(CometEvent).    public void onEvent(CometEvent event) throws IOException {        if (CometEvent.NOTIFY == event.getType()) {            int count = counter.get();            PrintWriter writer = response.getWriter();            writer.write("<script type='text/javascript'>parent.counter.updateCount('" + count + "')</script>\\n");            writer.flush();            event.getCometContext().resumeCometHandler(this);        }    } In our case, it writes a Javascript back to client side. This will invoke the Javascript function updateCount in count.html. The onEvent also invokes resumeCometHandler.This is necessary as the polling connection will be dropped once it is used.To compile the above Java code, one needs to include javax.javaee\*.jar and grizzly-comet\*.jar in classpath.Client CodeOn client side, I will illustrate the technique of hidden frame.Basically, the main page will have at least two frames. One of them does the long polling and is hidden from user. In our case, the index.html consists two frames as follows:    <iframe name="hidden" src="hidden_comet" frameborder="0" height="0" width="100%"><iframe>    <iframe name="counter" src="count.html" frameborder="0" height="100%" width="100%"><iframe>The first frame, which is hidden, is pointed to our Comet Servlet above through GET method.The second frame is to display the counter and submit buttonfor incrementing the counter. The Javascript in count.html is very simple as follows:    <script type='text/javascript'>        function updateCount(c) {            document.getElementById('count').innerHTML = c;            parent.hidden.location.href = "hidden_comet";         };    </script>How does it work?One can download the sources and war file from here,and deploy the war file.Using two browsers to access http://localhost:8080/grizzly-comet-hidden/index.htmland click on "Click" button on each browser separately. Then one sees that counts in both browsers will be updated whenever one clicks on one of them. The mechanism is outlined as follows:When the user accesses index.html, a browser will load two frames:The "hidden" frame accesses our Comet Servlet through GET method. This allows the client to start long polling with server.The "counter" frame loads a static count.html.When the user clicks on the button in count.html, it submits a POST request to our Comet Servlet.This triggers the CometHandler onEvent methodand redirects back to count.html to displaythe count. The onEvent triggers theupdateCount() JavaScript in "counter" frame, which willupdate the count andinvoke the Comet Servlet doGet for long polling in "hidden" frame, Note: There is a threading issue in the above sample code. I have posted the fix and other additional comments in another blog: Follow up on A Simple Comet Example: Long Polling vs Http Streaming.

Recently, there is a great interest in Comet technology. One can find many interesting articles in Comet Daily. Comet allows server and client to keep a live connection for communication.This provides...

Sun

Comparison of Security features in GlassFish and SJSAS 8.x EE

Security is very essential, especially in the enterpriseenvironment.In this blog, we will compare security of Profiles in GlassFish (GF) v2 and also note those feature availability in Sun Java System Application Server (SJSAS) 8.x Enterprise Edition.Note thatEnterprise Profile is not available in public yet and willbe in beta around July 2007. More information onProfiles in GlassFish v2 can be foundhere.Comparison of Security withGF and SJSAS 8.x EEFeatureGlassFishSJSAS 8.x EEv1v2 Development Profilev2 Cluster Profilev2 Enterprise ProfileSupport JSR 196noyesnoKeyStore for SSLJKSNSSKey/Certificate management toolskeytoolcertutil, pk12util, modutilJava Security Manageroff (default)on (default)onSupport JDBCRealmyesnoSingleSignOn (SSO)disable (default)enable (default)Virtual Server RealmsnoyesnoWith JDK 1.5 and NSS 3.11.4, Enterprise Profile inGlassFish v2 and SJSAS 8.x EE (but not available in GF v2 Cluster Profile) support the following:management of the PKCS#11 modules usingmodutilexplicit reference of keys in PKCS#11 providers for https or iiop/SSL listeners. (Note that with JDK 1.5 or later, one can add PKCS#11 providers to a given JDK. But those keys cannot be references by current server.)Elliptic Curve algorithm for SSL and other crypto operations (need Enterprise Profile GlassFish v2 and JDK 1.6)In SJSAS 8.2 EE and the coming GlassFish v2 Enterprise Profile,there is support for the use of private key in Solaris 10Softtoken. As an example, let us take a look at how to set upSolaris 10 Softtoken.Initialize Solaris 10 Softtoken password if you have not./bin/pktool setpinRegister the Solaris 10 Softtoken to NSS.modutil -dbdir $SJSAS_HOME/domains/domain1/config -force -add "Solaris 10 Softtoken" -libfile /usr/lib/libpkcs11.so -mechanisms RSA:DSAVerify that the token is added properly and find out the corresponding token name.modutil -dbdir $SJSAS_HOME/domains/domain1/config -listA sample output is as follows:Using database directory ....Listing of PKCS #11 Modules----------------------------------------------------------- 1. NSS Internal PKCS #11 Module slots: 2 slots attached status: loaded slot: NSS Internal Cryptographic Services token: NSS Generic Crypto Services slot: NSS User Private Key and Certificate Services token: NSS Certificate DB 2. Solaris 10 Softtoken library name: /usr/lib/libpkcs11.so slots: 1 slot attached status: loaded slot: Sun Crypto Softtoken token: Sun Software PKCS#11 softtoken-----------------------------------------------------------In this case, the token name is "Sun Software PKCS#11 softtoken". And this will be used in subsequent commands.Create a private key and certificate in Solaris 10 Softtoken.certutil -S -x -n mytestcert -t "u,u,u" -v 120 -s "cn=j2ee,ou=J2EE,o=Sun,L=Santa Clara,ST=California,C=US" -d $SJSAS_HOME/domains/domain1/config -h "Sun Software PKCS#11 softtoken" A sample output is as follows:Enter Password or Pin for "Sun Software PKCS#11 softtoken":A random seed must be generated that will be used in thecreation of your key. One of the easiest ways to create arandom seed is to use the timing of keystrokes on a keyboard.To begin, type keys on the keyboard until this progress meteris full. DO NOT USE THE AUTOREPEAT FUNCTION ON YOUR KEYBOARD!Continue typing until the progress meter is full:|\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*|Finished. Press enter to continue: Generating key. This may take a few moments...Change the cert-nickname to "Sun Software PKCS#11 softtoken:mytestcert" in your listeners.Restart the server, then it will prompt the password for Solaris 10 Softtoken as follows:Please enter password for NSS slot Sun Software PKCS#11 softtoken>

Security is very essential, especially in the enterprise environment. In this blog, we will compare security of Profiles in GlassFish (GF) v2 and also note those feature availability in Sun Java System...

Sun

JDBCRealm in GlassFish with MySQL

In these few months, there were several discussionsof using GlassFish JDBCRealm with MySQL. In this blog,I will share my experience about using GlassFishJDBCRealm with MySQL.Download the MySQL Community Server. I have downloaded the Solaris 10 (x86, 32 bit TAR package), version 5.0.37, of the "MySQL Community Server".Expand the download file.gunzip mysql-5.0.37-solaris10-i386.tar.gztar xf mysql-5.0.37-solaris10-i386.tarcd mysql-5.0.37-solaris10-i386 and read INSTALL-BINARY.Set up the grant table.scripts/mysql_install_dbStart the MySQL server.bin/mysqld_safeSet a password for the MySQL "root" userbin/mysqladmin -u root password YOUR_PASSWORDCreate database and table. The following is a sample command.bin/mysql -u root --password=YOUR_PASSWORDcreate database database01;use database01;create table usertable(userid varchar(10) primary key, password varchar(32) not null);create table grouptable(userid varchar(10) not null, groupid varchar(20) not null, primary key (userid, groupid));alter table grouptable add constraint FK_USERID foreign key(userid) references usertable(userid);commit;grant all privileges on *.* to 'root'@'YOUR_HOST' identified by 'YOUR_PASSWORD' with grant option;Note that you may like to replace YOUR_PASSWORD andYOUR_HOST in above.Populate user, group and passwor data. For the purpose of testing the database, you may try to use clear text password first as follows:insert into usertable values ('webuser', 'webuser');insert into grouptable values ('webuser', 'employee'); For MD5, please take a look at another blog on JDBCRealm.Download the JDBC driver from Connectors > Connector/J . I have downloaded mysql-connector-java-5.0.5-bin.zipUnpack the package and copy the JDBC driver to $GLASS_HOME/lib.unzip mysql-connector-java-5.0.5-bin.jarcd mysql-connector-java-5.0.5cp mysql-connector-java-5.0.5-bin.jar $GLASSFISH_HOME/libRestart the GlassFish server in order to pick up the JBDC driver.Create a Connector pool in Admin Console as follows:NameMySQLPoolResource Typejavax.sql.DataSourceDatabase VendorMySQLthen click "Next" and add the following properties:serverNameYOUR_HOSTport3306databaseNamedatabase01userrootpasswordYOUR_PASSWORDNote that different versions of the JDBC driver may have different properties. You may need to check the readme file there. Furthermore, you may need to remove extra default properties from Admin Console.Create a DataSource jdbc/mysql associated with the above pool.Create a JDBCRealm, named jdbcrealm with the following properties:datasource-jndijdbc/mysqluser-tableusertableuser-name-columnuseridpassword-name-columnpasswordgroup-tablegrouptablegroup-name-columngroupidjaas-contextjdbcRealmdigest-algorithmnone Note that if you are using MD5 for password data, then you need to set value of digest-algorithm to MD5.Now a JDBCRealm is ready and it can be used by specifying it in deployment descriptors. If there is anything wrong and cannot authenticate, then one can turn on security log to FINE level and check if there is any exception in server.log.

In these few months, there were several discussions of using GlassFish JDBCRealm with MySQL. In this blog, I will share my experience about using GlassFish JDBCRealm with MySQL. Download the MySQL Commu...

Sun

Multiple Private Keys in a GlassFish domain

GlassFish uses Java JKS for storing keys and certificates.Out of the box, the keyStore (keystore.jks) andthe trustStore (cacerts.jks) reside in$GLASSFISH_HOME/domains/domain1.Even though there are several CA root certificates incacerts.jks, there is only one private key inkeystore.jks.GlassFish supports the use of multiple private keys in a given domains. For instance, you may have two https listeners havingdifferent server private keys. This is a very useful scenarioespecially when one haveEC key.So, in a given domain, we can have one https listener usingRSA key for normal browser and one https listener using EC key for PDA.In this blog, we will discuss the configuration whenthere are multiple private keys in a given domain of GlassFish.In this case, one needs to specify the private key / certificateto be used for SSL communication. If the information isnot specified, then the server will pick up one which maynot be desirable.Since one wants to be more precise in security environment,one would like to specify the corresponding certificatenickname in order to pick up the correct key.There are two kinds of certificate nicknames: inbound,https outbound.Inbound Certificate NicknameOne needs to specify the inbound cert-nicknamefor a given listener in domain.xml. For instance,in http listener, it is as follows:    <http-listener ... security-enabled="true" ... />      <ssl cert-nickname="s1as" ... />      ...Instead of hand-crafting the domain.xml, it wouldbe a good idea to use Admin Console as follows:Configuration > HTTP Services > Http listeners > http-listener-2,and choose SSL tab and enter the valid alias value youwant in "Certificate Nickname" textbox.Then one needs to restart the given domain (if there is a changeof certificate nickname) in order to activate the change. Similarly for iiop listeners.Https Outbound Certificate NicknameGlassFish also supports the https outbound from server.A private key / certificate is used for https outbound mutual SSL authentication.In this case, we can specify the https outbound certificatenickname as jvm-options in domain.xml:    -Dcom.sun.enterprise.security.httpsOutboundKeyAlias=YOUR_ALIASOne can achieve this through Admin Console as follows:Application Server > JVM Settings > JVM Options >Add JVM option, and enter the above jvm option in thenew textbox. Then one needs to restart the server in order toactivate this change.

GlassFish uses Java JKS for storing keys and certificates. Out of the box, the keyStore (keystore.jks) and the trustStore (cacerts.jks) reside in$GLASSFISH_HOME/domains/domain1.Even though there are...

Sun

Browsing 196 AuthConfigProviders with AJAX

JSR 196,Java Authentication SPI for Containers, defines SPI forproviders plugging into containers for message authentication.It is currently under Proposed Final Draft (PFD) and GlassFish v2(b40 rc or above) has an implementation of PFD of this JSR.On the other hand, AJAXis another new and exciting technology in the Web 2.0 area.In this blog, I will share my experience with you aboutconstructing a web tool to browse 196 AuthConfigProvidersregistered in GlassFish by using AJAX tree.I find that it is very helpful to use jMaki pluginin NetBeans 5.5.1. A jMaki widget can be created in a jsp applicationby simply drag-and-drop. A very good tutorial can be found injMaki NetBeans 5.5 screencast.In the following, I will outline steps to create myweb application.Create a "Web Applicatons" project with namelistacp using NetBeans as described in above screencast.Open index.jsp if it is not already open. Then drag and drop a "jMaki Yahoo Tree" from the left Palette to the jsp. And the following code will be generated in the jsp:   <a:ajax name="yahoo.tree"/>This will create a AJAX Tree with the default data.We would like to construct the tree using data in JSON format from GlassFish server. In our case, the data is coming from acpdata.jsp. We need to modify the above as follows:   <a:ajax name="yahoo.tree" service="/acpdata.jsp"/>In acpdata.jsp, we need to get a complete list of AuthConfigProvider. This can achieved by getting a complete list of registration ID first.   AuthConfigFactory factory = AuthConfigFactory.getFactory();  if (factory != null) {    String[] regisIDs = factory.getRegistrationIDs(null); And for each registration ID, we can get RegistrationContext and AuthConfigProvider as follows:   RegistrationContext regContext = factory.getRegistrationContext(regisID);  if (regContext != null) {    String layer = regContext.getMessageLayer();    String appContext = regContext.getAppContext();    AuthConfigProvider provider = factory.getConfigProvider(layer, appContext, null);Then we need to output the data in corresponding JSON format. An example of the format from corresponding source of the Yahoo Tree Widget can be found injMaki Widget Gallery. For instance, in our case, acpdata.jsp outputs the data as   { root: {    title: '196 factory: com.sun.enterprise.security.jmac.config.GFAuthConfigFactory',    expanded: 'true',    children: [    {      title: 'registrationID = __2SOAP',      expanded: 'false',      children: [        { title: 'messageLayer = SOAP'},        { title: 'appContext = null'},        { title: 'description = WSIT AuthConfigProvider'},        { title: 'persistent = false'},        { title: 'provider = com.sun.xml.wss.provider.wsit.WSITAuthConfigProvider@14a8f44'}      ]    }    ,  ...Protect the web applicationSince the list of AuthConfigProviders will reveal what has been deployed in the given GlassFish installation, we would like to protect this web application so that only users of asadmin group ofadmin-realm can access it. We can achieve this by:Adding security setting in web.xml through NetBeans by navigating the Web application on panel of NetBeans:Web Pages > WEB-INF, open web.xml, and click Security, and modifying it as follows:  Login Configuration: Basic  Realm Name: admin-realm  Add Security Roles: admin  Add Security Constraint    Resource Name: secure resource    URL Pattern(s): /\*  Click on "Enable Security Constraint"     Role Names: adminThen, adding the security-role-mapping tosun-web.xml through "Edit As XML" mode:   <security-role-mapping>    <role-name>admin</role-name>    <principal-name>admin</principal-name>    <group-name>asadmin</group-name>  </security-role-mapping>If we package the war file and deploy, then we can access  http://your_host:your_port/listacp Enter your admin username and password. Everything works! The only drawback is the war file size is too big right now. In order to make it smaller, we have to remove unused AJAX libraries manually at this moment. (Try your best effort!) I hope the tool will only put in the required scripts in the future.One can download my sample AJAX 196 AuthConfigProvider browserhere.Note that we need to use a browser supporting AJAX (Firefox,Internet Explorer et al, not Mozilla 1.x) in order to run thisexample.

JSR 196, Java Authentication SPI for Containers, defines SPI for providers plugging into containers for message authentication. It is currently under Proposed Final Draft (PFD) and GlassFish v2(b40 rc...

Sun

Troubleshooting JAXWS Message Level Security in GlassFish

In Java EE 5,one can implement JAXWS Web Services through servlets and Ejbendpoints (JSR 109).GlassFish supports message level security for Web Services.You don't need to write special client and server Java code inorder to take advantages of the message level security. What youneed to do is specific a corresponding message-level-securityelement in sun-ejb-jar.xml, sun-web.xml,and sun-application.xml.For instance,  <webservice-endpoint>    <port-component-name>PingEjb</port-component-name>    <endpoint-address-uri>/PingEjbService/PingEjb</endpoint-address-uri>    <message-security-binding auth-layer="SOAP" provider-id="XWS_ServerProvider">      <message-security>        <message/>        <request-protection auth-source="sender"/>        <response-protection auth-source="content"/>      </message-security>    </message-security-binding>  </webservice-endpoint>Or you can turn on the default in domain.xml forserver side or sun-acc.xml for appclient.This blog will highlight some troubleshootings for JAXWSmessage level security. Read logsLook at client and server logs.The server log is located at $GLASSFISH_HOME/domains/your_domain/logs/server.log.If you want to see more SOAP level debug info, like corresponding SOAP messages, then you can turn on provider's debug.For server and embedded client, one can achieve this bynavigating from admin console: Configuration > Security >Message Security > SOAP > Providers:For server, choose the provider XWS_ServerProvider, change the debug property to true and save the configuration.For embedded client, choose the providerXWS_ClientProvider, change the debug property to true and save the configuration.For appclient, one need to change the debug propertyto true for the provider XWS_ClientProvider,and log-service level to INFO.Endpoint info mismatchFor message level security, one need to ensure that the samerequest-policy and response-policyare applied to both client and server. These info can bespecified in sun-\*.xml for a given applicationor domain.xml and sun-acc.xml for defaultprovider configuration (if default is on).If you see com.sun.xml.wss.impl.PolicyViolationException:Expected Signature Element as per receiver requirementsor there is no security processing in SOAP message in debug log,then most probably some of the info about endpoint insun-\*.xml is not correct. You may like to doublecheck each port-component-name (defined in JSR 109) andendpoint-address-uri inside message-security-binding in sun-\*.xmlare correct.Note:According to JSR 181, we have the following:ValueDefault@WebService.nameSimple name of the Java class or interface@WebService.serviceNameSimple name of the Java class + "Service"In GlassFish, the URL to access WebService andendpoint-address-uri in sun-\*.xml are related as follows:Endpoint TypeWebService URLServlethttp[s]://host:port/context-root/endpoint-address-uriEjbhttp[s]://host:port/endpoint-address-uriOne can also find out the port-component-name by checking thegenerated webservices.xml in admin console as follows:Web Services > YOUR_WEB_SERVICES > Webservices.xml,and then correct the port-component-name,repackage and redeploy your application if necessary.

In Java EE 5, one can implement JAXWS Web Services through servlets and Ejb endpoints (JSR 109).GlassFish supports message level security for Web Services.You don't need to write special client and...

Sun

Password echo of appclient in GlassFish?

In SJSAS 8.x, 9.0 and GlassFish v1, when one tries to access apassword protected EJB or Web Service through appclient,it will prompt user name and password if this is notspecified in command line or programmatically.By default the prompt will be a GUI dialog box.In remote environment, it may be desirable to have the promptin text mode. One can achieve this through appclient as follows:  appclient -client <location of the client jar> -textauthAnd username and password will be prompted and user's response will be as follows:  Enter Username:javaee  Enter Password:javaeeNote that the password is echoed in the console.This is highly undesirable from security point of view.In GlassFish v2 with JDK 6 environment, the password isno longer echoed in text password prompt. One can switch theJDK of GlassFish server by editing the AS_JAVAin config/asenv.conf for non-Windows systems andconfig/asenv.bat for Windows systems. If onereruns the above appclient command, then one will have  Enter Username:javaee  Enter Password:Note that the password is no longer echoed in the console.One may ask whether one can achieve this without modifyingthe JDK in whole installation. In GlassFish, one canpackage the appclient and install it in somewhere else.The command is as follows:  $GLASSFISH_HOME/bin/package-appclientThis will generate a appclient.jar . Then onecan copy this to the desired location and unjar the content.After that, one may need to update the following inside the unjar directories:change appclient script to execution mode ifnecessary. The command in unix is: chmod u+x appclient.update the content of asenv.conf orasenv.bat, sun-acc.xml, appclient as described inSJSAS package-appclient doc. For instance, if one want to use webservice in client, then one need to update AS_WEBSERVICE_LIB.In our case, one need to update AS_JAVA to pointto a JDK 6 installation.In this case, the GlassFish installation will still use the same JDK as before. Only the JDK of the new appclient hasbeen updated.

In SJSAS 8.x, 9.0 and GlassFish v1, when one tries to access a password protected EJB or Web Service through appclient, it will prompt user name and password if this is notspecified in command line or...

Sun

assign-groups in GlassFish Security realm

In the Java EE environment, roles are logical privilegeswhich convey/represent permission to operate on some particular set of resources in an application. The Sun Java System Application Server environmentconsists of several realms, which each contain a complete database of users and groups that identify valid users of an application. When the roles are mapped to users, the users are effectivelygranted the permissions conveyed/represented by the privilege. In Sun One Application Server 7.0, you can assign a role to allauthenticated users in all realms at the same time, andapplications can define authorization for that role. Thisaddresses the following common scenario in the LDAP environment: All authenticated users can access some subset of protectedresources within the application. It doesn't matter who you are,only that your identity has been established.The set of user groups is large or dynamic, but notspecific to the application.We wanted an ability to grant permission based on authenticationindependent of identity, in other words, we wanted a way to grantall authenticated identities to a role, or to define a role thatwould be understood to be mapped to all authenticated identities,and not to unauthenticated entities. In Sun Java System Application Server 8.x and GlassFish v1,various RFEs and issues have been filed requesting support of theabove scenario. Therefore, this scenario has been addressed inGlassFish v2.In GlassFish v2, the assign-groups property inCertificateRealm has been extended to FileRealm, LDAPRealm,SolarisRealm, and JDBCRealm. With this change,it is possible to configure all realms so that they assign oneor more common group principals as a result of successful authentication, and such that every user is effectively madea member of the common groups.Given that this is the case, mapping one or more of the groupprincipals to a role, either explicitly or by default, will allow the role to be used as an ANYONE role, a role that conveys/represents permission to operate on all resources which are accessible to any authenticated user. You can assignadditional groups to all authenticated users in a specific realmwithout having to add those groups to all authenticated usersin all realms. This gives us a finer control and allows us toresolve the issues with the above scenario as follows: Set the assign-groups property for agiven realm. All authenticated users of the given realm willassign additional groups as specified by theassign-groups property, for instance,    assign-groups=agroupMap additional groups to desired roles in Sun-specificdeployment descriptors. For instance, in sun-applicaton.xml,<sun-application>  <security-role-mapping>    <role-name>javaee</role-name>    <principal-name>javaee</principal-name>  </security-role-mapping>  <security-role-mapping>    <role-name>ANYONE</role-name>    <group-name>agroup</group-name>  </security-role-mapping></sun-application>

In the Java EE environment, roles are logical privileges which convey/represent permission to operate on some particular set of resources in an application.The Sun Java System Application Server...

Sun

在 Glassfish 中使用 JDBCRealm

原文:JDBCRealmin Glassfish作者:Shing Wai Chan译者:Cheng FangJDBC realm 在近几个月来颇受瞩目。这篇网志总结了 JDBC realm 在GlassFish实施中的演变,并解释其最新的实施运作。我要感谢 Jean-Baptiste 和 Richter对此所作的贡献和评论。开源社区成员的参与也很有帮助。我欢迎大家的反馈和参与, 帮助我们更好地实现这一性能。GlassFish 一直都支持 realm 插件。以下这篇文章描述了如何在 Sun Java System ApplicationServer EE 8.0 中实现 Custom Realm:AuthenticationUsing Custom Realms in Sun Java System Application Server。S1AS 7.x 也里有一个JDBC realm的示例。Jean-Baptiste 正式提出要求这一性能,并为 Glassfish 提供了一个以明文的方式实现的 JDBCRealm。Richter 也提供了另一个实施方案,因为当时GlassFish 中的 JDBCRealm 与Tomcat 不兼容。GlassFish 中最新的 JDBCRealm 是基于Jean-Baptiste 的实施,并包含了以下一些改动:增加 Message Digest 配置 增加对 Digest 的 encoding 配置 增加 charset 配置 增加 realm 中数据库用户和密码配置 解决为 EJB 获取连接的问题 在 GlassFish 中设计、实施 JDBCRealm 的过程中, 我们作出了以下一些决定:应该不应该支持明文密码? 我们决定支持明文密码,但不作为缺省存贮机制。在正常情况下, 密码不应该被明文地存放。 是不是应该与 Tomcat 和 JBoss 兼容?  我们决定在实施中尽量做到兼容, 但不作为一个要求。 我们想听听你对这两个方面的意见。GlassFish JDBCRealm下表概括了 GlassFish JDBCRealm 中可配置的属性:属性是否必须缺省备注 datasource-jndi是   user-table是   user-name-column是 和 Tomcat 一样, 我们假设 user-table 表和 group-table 表有这一栏 password-column是   group-table是   group-name-column是   jaas-context是 jdbcRealm db-user否沿用连接池配置如果连接池没有用户名或密码,在这里定义db-user和db-password。这能够让我们指定一个安全的资源,realm 可以通过用户名和密码来访问。 db-password digest-algorithm否MD5支持 JDK 中所有算法, 和 "none" encoding否如果有 digest-algorithm, 就用 Hex。如果没有定义 digest, 则不用 encoding。Hex, Base64, 不指定(没有 encoding) charset否 针对 digest 的 charset GlassFish 中的一个安全性能就是,你可以在 JDBCRealm 中, 而不是在连接池中,指定用户名和密码。这样,其它应用就无法查找 datasource,得到连接来浏览用户名和密码表。怎么在JavaEE 应用中使用JDBCRealm ?为 JDBCRealm 创建数据库表。 例如, 如果您使用 Derby, 您会创建如以下示例的数据库表:create table usertable(userid varchar(10) not null, password varchar(32) not null, primary key(userid));create table grouptable(userid varchar(10) not null, groupid varchar(20) not null, primary key(userid, groupid));alter table grouptable add constraint FK_USERID foreign key(userid) references usertable(userid);通过Admin 控制台创建 JDBCRealm。 例如, 你可以创建一个有以下属性的 JDBCRealm:Property NameProperty Value datasource-jndijdbc/security user-tableusertable user-name-columnuserid password-columnpassword group-tablegrouptable group-name-columngroupid jaas-contextjdbcRealm jdbc/security 是一个可以访问以上表格的 datasource。指定 JDBCRealm 是当前应用使用的 realm。这在配置描述器里指明: sun-application.xml(对于 EAR) 或, web.xml(对于 WAR) 或 sun-ejb-jar.xml (对于 EJB Jar) 。 确认 sun-\*.xml 文件里有 <security-role-mapping>。例如,   <security-role-mapping>     <role-name>Employee</role-name>     <principal-name>Calvin</principal-name>  </security-role-mapping> 在数据库中创建一名用户。没有为 JDBCRealm 创造用户的管理工具。以下是一个用来创建 JDBCRealm 用户程序例子:... private static final String userSql = "insert into usertable values(?, ?)"; private static final String groupSql = "insert into grouptable values(?, ?)"; private static String hashPassword(String password) throws Exception { ... //compute digest ... //encode the bytes... } public static void main(String args[]) throws Exception { ... Class.forName(driver); String hPassword = hashPassword(password); Connection conn = DriverManager.getConnection( jdbcUrl, dbUser, dbPassword); PreparedStatement userStmt = conn.prepareStatement(userSql); userStmt.setString(1, user); userStmt.setString(2, hPassword); userStmt.executeUpdate(); userStmt.close(); ... }  可以在这里找到这个例子。当运行这一程序时, 要确认 JDBC 驱动在 CLASSPATH 里,例如, $GLASSFISH_HOME/javadb/lib/derbyclient.jar关于迁移从 Tomcat 或者 JBoss 迁移到 GlassFish 时,应考虑到以下一些不同的地方:在 Tomcat 和 JBoss, 没有缺省值。这对应于 GlassFish 中的digest-algorithm="none"。 在GlassFish 和Tomcat 中, 如果有 digest 被定义,那么 encoding 缺省值就是 Hex。在JBoss 中, 如果有 digest 被定义,那么 encoding 缺省值就是 Base64。 註 : 根据意見, 我更新了数据库grouptable的SQL。

原文: href="http://blogs.oracle.com/roller/page/swchan?entry=jdbcrealm_in_glassfish">JDBCRealm in Glassfish 作者:Shing Wai Chan 译者:Cheng Fang JDBC realm 在近几个月来颇受瞩目。这篇网志总结了 JDBC realm 在GlassFish实施中的演变,并解释其最...

Sun

JDBCRealm in GlassFish

JDBC realm has a lot of attention in recent months.This blog summarizes the evolution of the JDBC realm implementationin GlassFish and explains how the latest implementation works.I would like to thank Jean-Baptiste, and Richter for their contributionsand comments.The participation from the open source community definitely helps everyone.I encourage all of you to give feedback, participate, and help evolvethis feature further.GlassFish always had the capability for anyone to plug-in a realm.Implementing a custom realm in the Sun Java System Application ServerEE 8.0 is described in the articleAuthentication Using Custom Realms in Sun Java System Application Server.In S1AS 7.x, there is a JDBC Realm bundled in sample.Jean-Baptiste formally filed an enhancementand provided a clear text version of JDBCRealm for GlassFish.Richter wrote another implementationbecause the GlassFish JDBCRealm at that time not compatible with Tomcat.The latest GlassFish implemtation started with the Jean-Baptiste'simplementation and includes the following modifications:add message digest configurationadd encoding configuration for digestadd charset configurationadd database user and password configuration in realmfix the issue with acquiring a connection for EJBFor the GlassFish implementation of the JDBCRealm, the following designdescisions were made:Should clear text passwords be supported? The decision was made to notto have clear text passwords as default storage mechanism. Under normalcircumstances, passwords should not be stored as clear text.Should this implementation be compatible with Tomcat and JBoss?The decision was made to attempt to implement this compatibility,but not require this compatibility. I would appreciate hearing from you on both of these topics.GlassFish JDBCRealmThe following table summarizes configurable properties for GlassFishJDBCRealm:PropertiesMandatoryDefaultRemarkdatasource-jndiY  user-tableY  user-name-columnY as in Tomcat, we assume that both user-table and group-table has this columnpassword-columnY  group-tableY  group-name-columnY  jaas-contextY jdbcRealmdb-userNfrom connection pool configurationIf the connection pool doesn't have username or password, define the db-user and db-password here. This allows us to specify a secure resource that is accessible by an realm with user and password specified.db-passworddigest-algorithmNMD5support all algorithms in JDK, and also "none"encodingNHex if there is a digest-algorithm, no encoding if digest is not definedHex, Base64, not specified (no encoding)charsetN charset for digestIn GlassFish, a security feature allows you to specify a username andpassword in the JDBCRealm instead of in the connection pool. By doing this, other applications cannot look up the datasource and geta connection to browse the user-name, password database tables.How to use JDBCRealm in a JavaEE application?Create database tables for the JDBCRealm.For example, if you are using Derby, you would create database tablesas shown in the following code example:create table usertable(userid varchar(10) not null, password varchar(32) not null, primary key(userid));create table grouptable(userid varchar(10) not null, groupid varchar(20) not null, primary key(userid, groupid));alter table grouptable add constraint FK_USERID foreign key(userid) references usertable(userid);Create a JDBCRealm using the Admin Console. For instance, one can create a JDBCRealm with the followingproperties:Property NameProperty Valuedatasource-jndijdbc/securityuser-tableusertableuser-name-columnuseridpassword-columnpasswordgroup-tablegrouptablegroup-name-columngroupidjaas-contextjdbcRealmwhere jdbc/security is a datasource can access the tables above.Specify that the JDBCRealm is the realm to be used as the realmfor the application. This is specified in the deployment descriptor:sun-application.xml (for EAR) or, web.xml (for WAR)or sun-ejb-jar.xml (for EJB JAR).Make sure that you have <security-role-mapping>in sun-\*.xml.For instance,  <security-role-mapping>    <role-name>Employee</role-name>    <principal-name>Calvin</principal-name>  </security-role-mapping>Create a user in database. There is no administration toolsfor creating users for JDBCRealm. A snapshot of a programthat can be used to create users in JDBCRealm is as follows: ... private static final String userSql = "insert into usertable values(?, ?)"; private static final String groupSql = "insert into grouptable values(?, ?)"; private static String hashPassword(String password) throws Exception { ... //compute digest ... //encode the bytes... } public static void main(String args[]) throws Exception { ... Class.forName(driver); String hPassword = hashPassword(password); Connection conn = DriverManager.getConnection( jdbcUrl, dbUser, dbPassword); PreparedStatement userStmt = conn.prepareStatement(userSql); userStmt.setString(1, user); userStmt.setString(2, hPassword); userStmt.executeUpdate(); userStmt.close(); ... }The sample program can be found in here.When we run the program, please make sure that the JDBC driveris included in CLASSPATH, for instance,$GLASSFISH_HOME/javadb/lib/derbyclient.jarNotes on MigrationConsider the following differnces when migrating applicationsfrom Tomcat and/or JBoss to GlassFish:In Tomcat and JBoss, there is no default. This corresponds to digest-algorithm="none" in GlassFish.In GlassFish and Tomcat, the default encoding is Hex if there is a digest defined. In JBoss, the default encoding is Base64 if there is a digest defined. Note: Based on comments, I have updated the SQL for creating grouptable.

JDBC realm has a lot of attention in recent months. This blog summarizes the evolution of the JDBC realm implementation in GlassFish and explains how the latest implementation works.I would like to...

Sun

Glassfish with ECC

As computer hardware is getting more and more powerful, there isa corresponding need to increase the encryption strength of thekey in cryptographic operations. There are several ways in whichthis can be accomplished:Increase the length of the encryption key. This may negativelyimpact performance. Use a different encryption algorithm, for example, Elliptic Curve Cryptography (ECC). In next-generation key technology, RSA will be2048 bits and ECC will be 224 bits. Note that these two type of keyshave the same ecnryption strength.In this blog, I will summarize the steps needed for using HTTPS with ECC with the following configuration:GlassFish orSun Java System Application Server 9 The latest version of JDK 6 (beta2 - b81 or later)The latest version of NSS 3.11.1.For WinXP, you can download NSS, and NSPR, and unzip it to the directory c:\\nss\\lib. For other platforms, you compile NSS libraries as describedin instructions.The following discussion assumes that GlassFish is installed inc:\\export\\glassfish, JDK 6 is installed inc:\\jdk6 and the NSS binaries are located in c:\\nss\\lib.Configure your operation environment to run the GlassFish, JDK 6, and NSS.For example in Windows, set the path variabled, as shown here:  set path=c:\\jdk6\\bin;c:\\nss\\lib;c:\\export\\glassfish\\bin;%path%For example, in Unix ksh, export these environment variables:  export PATH=/jdk6/bin:/export/glassfish/$PATH  export LD_LIBRARY_PATH=/nss/lib:$LD_LIBRARY_PATHCreate a provider configuration for NSS in c:\\ecc\\nss.cfg as follows:  name=NSS  nssLibraryDirectory=c:\\\\nss\\\\lib  nssDbMode=noDb  attributes=compatibilityAdd the NSS provider to the JDK 6 configuration by adding the following line in the file c:\\jdk6\\jre\\lib\\security\\java.security :  security.provider.10=sun.security.pkcs11.SunPKCS11 c:\\\\ecc\\\\nss.cfgCreate an ECC key in JKS keystore using keytool,where ${HOST} is hostname of your machine.  c:  cd \\export\\glassfish\\domains\\domain1\\config  keytool -genkeypair -alias myecc -keyalg EC -keysize 224 -keystore keystore.jks -storepass changeit -dname "CN=${HOST}, OU=ECC Test 224, O=GlassFish" -keypass changeitUpdate the version of the JDK used by GlassFish by updating the value of AS_JAVA in the file c:\\export\\glassfish\\config\\asenv.bat.Start the GlassFish server if necessary.  asadmin start-domain domain1Update the certificate nickname of the HTTP listenser http-listener-2 to myecc using theAdmin Console, which can be accessed by entering the followingURL in your browser: http://serverName:4848Stop and then restart the GlassFish server in order for thechanges to become effective  asadmin stop-domain domain1  asadmin start-domain domain1To access the HTTPS with ECC, install the latest versions ofweb browsers, as only the latest versions have support for ECC.The latest versions can be found in here.If you try access https://serverName:8181 using your existing browser, you will see an error message like this:  cannot communicate securely because they have no common encryption algorithms.Configure the latest version of the browser to use an ECC algorithm, for example,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, by followingthese steps:Open your web browser.Enter the following URL in the browser: accessing about:config.In this window, set Filter to security.Select and double clickssl3.ecdh_ecdsa_aes_128_shaNow, you can access https://serverName:8181, the browser will prompt for accepting the certificate and you can verify that this is the ECC certificate that you just created.A preliminary benchmark of HTTPS with ECC in GlassFish on theWindows XP platform shows that the performance of ECC is doublethat of RSA in next generation-key technology.More details on using JDK 6 with NSS can be found in Andreas's blog:Elliptic Curve Cryptography in Java.

As computer hardware is getting more and more powerful, there is a corresponding need to increase the encryption strength of the key in cryptographic operations. There are several ways in whichthis...

Sun

Enterprise Java Bean over SSL

Enterprise Java Bean provides a component based architecture for distributed business application. Security is very important in the enterprise environment. SSL/TLS provides security at the transport layer to meet the security requirement in an enterprise environment.In this blog, we discuss how to configure SSL for use with enterprise beansand how to access enterprise bean from a client.NoteIn the Java EE 5 SDK,Glassfish and theSun Java System Application Server (SJSAS),the keystore password and key passwords are the same, and the keystore and truststore passwords are the same for a given domain.The SJSAS EE uses NSS for keystore management. The SJSAS PE usesJKS keystores for keystore management. The application client containers,however, use JKS keystores for keystore management regardless of whetherthe Application Server is EE or PE.Running Enterprise Beans over SSLIn SSL/TLS, there are two kinds of authentication: SSL server authentication and SSL mutualauthentication. To specify SSL/TLS for an enterprise application, use the<transport-config> subelement of the corresponding<ejb> element in the runtime deployment descriptor,sun-ejb-jar.xml.The two options are specified in slightly different ways, as shown inthe following examples:SSL: Server AuthenticationIn this case, the client verifies the identity of the server by checkingits certificate in the truststore. When using sever authentication, make surethat the truststore of the client trusts the certificate of the server. To doSSL server authentication, set the integrity element and confidentialityelement to required. For instance,<sun-ejb-jar>  <enterprise-beans>    <ejb>      <ejb-name>SSLTheConverter</ejb-name>      <jndi-name>SSLconverter</jndi-name>      <ior-security-config>        <transport-config>          <integrity>required</integrity>          <confidentiality>required</confidentiality>          <establish-trust-in-target>supported</establish-trust-in-target>          <establish-trust-in-client>supported</establish-trust-in-client>        </transport-config>        <sas-context>          <caller-propagation>supported</caller-propagation>        </sas-context>      </ior-security-config>    </ejb>  </enterprise-beans></sun-ejb-jar>SSL Mutual authenticationIn this case, both the client and the server verify the identity of eachother by checking certificates in mutual truststores. Whenusing mutual authentication, make sure that the truststore of the clienttrusts the certificate of the server and the truststore of the server truststhe certificate of the client. To do SSL mutual authentication, set the integrity element,the confidentiality element, and theestablish-trust-in-client to required. For instance,<sun-ejb-jar>  <enterprise-beans>    <ejb>      <ejb-name>SSLTheConverter</ejb-name>      <jndi-name>SSLconverter</jndi-name>      <ior-security-config>        <transport-config>          <integrity>required</integrity>          <confidentiality>required</confidentiality>          <establish-trust-in-target>supported</establish-trust-in-target>          <establish-trust-in-client>required</establish-trust-in-client>        </transport-config>        <sas-context>          <caller-propagation>supported</caller-propagation>        </sas-context>      </ior-security-config>    </ejb>  </enterprise-beans></sun-ejb-jar>Using SSL with the Applicaton Client ContainerTo use SSL with the Application Client Container (ACC), you need to setVMARGS environment variable.Set environment variable VMARGS in shell.For example, in ksh or bash shell the command to set this environmentvariable would be: export VMARGS=" -Djavax.net.ssl.keyStore=${keystore.db.file} -Djavax.net.ssl.trustStore=${truststore.db.file} -Djavax.net.ssl.keyStorePassword=${ssl.password} -Djavax.net.ssl.trustStorePassword=${ssl.password}"Set the env element in the ant script. For instance,<target name="runclient">  <exec executable="${S1AS_HOME}/bin/appclient">    <env key="VMARGS" value=" -Djavax.net.ssl.keyStore=${keystore.db.file} -Djavax.net.ssl.trustStore=${truststore.db.file} -Djavax.net.ssl.keyStorePasword=${ssl.password} -Djavax.net.ssl.trustStorePassword=${ssl.password}"/>    <arg value="-client"/>    <arg value="${appClient.jar}"/>  </exec></target>Using SSL with Standalone ClientWhen the application client, the enterprise bean is looked up using theejb-ref-name element, as shown in the following examplesun-application-client.xml:<sun-application-client>  <ejb-ref>  <ejb-ref-name>ejb/SSLSimpleConverter</ejb-ref-name>  <jndi-name>SSLconverter</jndi-name>  </ejb-ref></sun-application-client>When using a standalone client, however, we use JNDI name for the lookup.So, in the standalone client class, we have:    context = new InitialContext();    obj = context.lookup("SSLConverter");To run the standalone client, make sure your classpath contains the following:appserv-rt.jar, this will have an implementation ORB with the implementation of CSIv2j2ee.jar in SJSAS 8.x or javaee.jar in Glassfishthe interfaces class of the corresponding EJBs and other library classes neededThe following ant target provides an example of how to configure anant target for running over SSL:<target name="run-standalone-client">  <java classname="${test.client}"      classpath="${test.classpath} failonerror="true" fork="true">    <jvmarg value="-Dorg.omg.CORBA.ORBInitialHost=${orb.host}"/>    <jvmarg value="-Dorg.omg.CORBA.ORBInitialPort=${orb.port}"/>    <jvmarg value="-Djavax.net.ssl.keyStore=${keystore.db.file}"/>    <jvmarg value="-Djavax.net.ssl.keyStorePassword=${ssl.password}"/>    <jvmarg value="-Djavax.net.ssl.trustStore=${truststore.db.file}"/>    <jvmarg value="-Djavax.net.ssl.trustStorePassword=${ssl.password}"/>  </java></target>Debugging SSL CommunicationTo enable debug messages for SSL communication, pass the jvm option-Djavax.net.debug=all, which will show all the information duringSSL communications.

Enterprise Java Bean provides a component based architecture for distributed business application. Security is very important in theenterprise environment. SSL/TLS provides security at the...

Sun

Troubleshooting Deployment in Glassfish

In Java EE 5,there are many new and exciting features. For example, developers can specifyannotations in Java files instead of putting metadata in deployment descriptors.In some cases, applications can be completely free of deployment descriptors.This simplifies the development of Jave EE applications.This blog describes two common troubleshooting scenarios for deployment in GlassFish.Runtime error due to annotations not correctly processed (if at all) during deployment.In this case, even though one may go through deployment, there willbe a runtime error. For instance, suppose you have the following resource injection    private @Resource(name="jdbc/__default") DataSource ds;then, you will have a NullPointerExceptionwhen you try to access the ds.Verify that the annotation is not processed by doing the following:turn on deployment log to FINE in the domain during deployment timeIn this case, you will see a FINE message in server.log as follows:    Annotation is not processed for this archive.Solution:Make sure that standard deployment descriptor files, such as ejb-jar.xml, web.xml,application-client.xml refer to the correct version of theXML schemas in the ear/war/jar files before deployment as the Java EE platformspec requires that annotations are only processed if the deployment descriptoruses the latest schema.Deployment DescriptorVersion of XSD ejb-jar.xml ejb-jar_3_0.xsd web.xml web-app_2_5.xsd application-client.xml application-client_5.xsdIf the descriptors mentioned above refer to the correct schemaversions, then please make sure that the full attribute is "false"or not specified there as the Java EE platform spec indicates that annotationsare only processed if the deployment descriptors using the latest schema havethe full attribute either specified as "false" or not specified. For instance,<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" full="false" version="3.0" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"><ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">If the above are correct and the annotation in application clientis still not processed, then please make sure that the application client jarfile has a MANIFEST.MF containing a Main-Class entrypointing to the fully qualified name of the app client main class. Note that,in general, one can specify the application client main class as an appclientcommand line argument. But in cases with annotation, one needs to have MANIFEST.MF withMain-Class entry.A library jar file is incorrectly treated as app client jar in adeployment descriptor free application. This is due to the fact that thegiven library jar file has a Main-Class entry inMANIFEST.MF file.Note that even though the application may be able to deploy, it may notbe as you desired. For instance, if the given ear does not have anapp client jar, deployment may interpret a library jar as an app client jar.One can verify this in admin GUI.Solution:Include application.xml and defined each module explicitly. In this case, the library jar is not mentioned in application.xml. For instance, <?xml version="1.0" encoding="UTF-8"?><application xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd>  <display-name>deployment-ejb30-ear-securityApp</display-name>  <module>    <ejb>deployment-ejb30-ear-security-ejb.jar</ejb>  </module>  <module>    <web>      <web-uri>deployment-ejb30-ear-security-web.war</web-uri>      <context-root>deployment-ejb30-ear-security</context-root>    </web>    </module>  <module>    <java>deployment-ejb30-ear-security-client.jar</java>  </module></application> Or remove the Main-Class entry in MANIFEST.MF if it is unnecessary for the library function properly.

In Java EE 5, there are many new and exciting features. For example, developers can specify annotations in Java files instead of putting metadata in deployment descriptors.In some cases, applications...

Sun

How to use Verisign cert in Glassfish and SJSAS 8.x?

This blog describes the steps needed to use Verisign certificates in GlassFish which can be downloaded from http://glassfish.dev.java.net/public/downloadsindex.html. These steps will also work with the SJSAS 8.x products.You will need to go to the Verisign website to get a certificate ifyou don't already have one.In the following, we will outline steps on how to use Verisign certificate in Sun Java System Application Server (SJSAS) 8.x PE and Glassfish.Steps On Using Verisign CertificateGenerate a private key in keystore resided in domains/your_domain/config/keystore.jks.keytool -genkey -alias myservkey -keysize 1024 -keyalg RSA -keystore keystore.jks -dname "CN=test.glassfish.com,OU=Testing,O=Java,L=Santa Clara,S=California,C=US"Note that there cannot be a space in the CN name. Verisign can only accept RSA at this time, DSA algorithm is not supported.the password for keystore and the key must be the samethe password for keystore.jks in default installation is changeitCreate a certificate request.keytool -certreq -alias myservkey -sigalg SHA1WithRSA -keystore keystore.jks -file myservkey.csr Backup your keystore. This is very important as no one can recover the private key if it is lost. Go to Verisign website http://www.verisign.com to process the certificate. Once the certificate is processed, Verisign will send an email to you with certificate inside the email. Please cut and paste the certificate and save it to a file, say, myservkeyveri.cer. Please make sure there is no extra whitespace in the file. Make sure root CA certificate is indomains/your_domain/config/keystore.jksdomains/your_domain/config/cacerts.jksin your browser if it is used as SSL client. If you are using a Verisign certificate, then root CA has already been there. But if you are using Verisign testing certificate, then you need to import the Verisign testing root CA certificate which can be found in hyperlink of email from Verisign. The commands for importing CA root certificate is as follows:keytool -import -v -trustcacerts -alias verisigntestroot -file vertestrootca.cer -keystore keystore.jkskeytool -import -v -trustcacerts -alias verisigntestroot -file vertestrootca.cer -keystore cacerts.jksImport the certificate to keystore.keytool -import -v -alias myservkey -file myservkeyveri.cer -keystore keystore.jksVerify that the certificate is imported correctly.keytool -list -v -alias myservkey -keystore keystore.jksUpdate the certificate alias from admin GUI:For https certificate alias:Configuration > HTTP Service > HTTP Listeners > http-listener-2    Input certificate alias name in Certificate NickName text box.    Enable SSL3, TLS, cipher suites if necessaryFor iiop certificate alias:Configuration > IIOP Listeners > SSL / SSL_MUTUALAUTH    Input certificate alias name in Certificate NickName text box.    Enable SSL3, TLS, cipher suites if necessaryRestart the server by using asadmin.Verify the server is using the certificate. If you are setting https as above, then you can use browser to access https://your_host:8181 and it will prompt to you to accept the certificate you have just imported.Troubleshootingkeytool -import -keystore keystore.jks -alias myservkey -file myservkeyveri.cer    Enter keystore password:     keytool error: java.security.cert.CertificateException: java.io.EOFExceptionPlease double check there is no extra whitespace in the file.keytool -import -v -alias myservkey -keystore keystore.jks -file myservkeyveri.cer    Enter keystore password:     keytool error: java.lang.Exception: Public keys in reply and keystore don't matchThe certificate reply does not match with the key in your keystore. You may need to check whether alias name is correct or get backup keystore having the private key.RemarkThe same procedure work for SJSAS EE by using certutil instead of keytool:use certutil -S to generate a keyuse certutil -R to import a certificateuse certutil -A to import a certificateuse certutil -L to list a certificateMore information on how to use certutil in SJSAS can be found in Key Management and PKCS#11 Tokens in Sun Java System Application Server 8.1, May 19, 2005.

This blog describes the steps needed to use Verisign certificates in GlassFish which can be downloaded from http://glassfish.dev.java.net/public/downloadsindex.html. These steps will also work with...

Oracle

Integrated Cloud Applications & Platform Services