Using GlassFish domain templates to easily create several customized domains

It might have happened to you to require some customization the GlassFish behavior after you create the domain in order to make the domain fit the  basic requirements that you have in your organization or for your development purpose. Some of the files that we usually manipulate to customize GlassFish includes logging.properties, keystore.jks, cacert.jks, default-web.xml, server.policy and domain.xml. These files can be customized through different asadmin commands, or JDK commands like keytool, policytool or manually using a text editor after you created the domain in the config directory of the domain itself.  But repeating the steps for multiple domains is a laborious task which can be prevented by changing the template files that GlassFish domains are created using them. The templates are located atAnd we can simply open them and edit the properties to make them more fit to our needs.

The benefit of modifying the templates rather than copy pasting the config directory of one domain to another is the domain specific behaviors like port numbers which have placeholders in the domain.xml to be filled by asadmin command. An example of a placeholder is %%%JMS_PROVIDER_PORT%%% which will be replaced by JMS provider port by asadmin command.

How REST interface covers for the absence of JMX/AMX administration and management interface in GlassFish 3.1

For sometime I wanted to write this entry and explain what happened to GlassFish JMX/AMX management and administration interface but being busy with other stuff prevented me from doing so. This article here can be an upgrade to my other article about GlassFish 3.0 JMX administration interface which I wrote while ago. Long story short, in GlassFish 3.1 the AMX/JMX is no longer available and instead we can use the REST interface to change the server settings and perform all administration/management and monitoring activities we need. There are fair number of articles and blog entries all over the web about the RESTful interface which I included them at the end of this blog. Firs of all the rest interface is available trough the administration console application meaning that we can access the interface using a URL similar to: http://localhost:4848/management/domain/ The administration console and the rest interface  are running on a separate virtual server and therefore a separate HTTP Listener and if required transport configuration. What I will explain here will be the following items:

  • How to use Apache HttpClient to perform administration tasks using GlassFish REST interface
  • How to find the request parameters for different commands.
  • GlassFish administration, authentication and transport security

How to use Apache HttpClient to interact with GlassFish administration and management application

Now back to the RESTful interface, this is a HTTP based interaction channel with the GlassFish administration infrastructure which basically allows us to do almost anything possible to do using asadmin trhough HTTP in a RESTful manner. We can use basically any programming language capable to writing on a socket to interact with the RESTFul interface. Here we will use Apache HTTPClient to take care of sending the commands to GlassFish RESTFul console. When using GlassFish REST management we can use any of the POST/GET and DELETE methods to perform the following tasks:

  • POST: create and partially update a resource
  • GET: get information like details of a connection pool
  • DELETE: to delete a resource

Following sample code shows how to use the  to perform some basic operations including updating a resource, getting some resources list, creating a resource and finally deleting it.

[java]
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.util.logging.Logger;

import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;

/**
*
* @author Masoud Kalali
*/
public class AdminGlassFish {

//change the ports to your own settng
private static final String ADMINISTRATION_URL = "http://localhost:4848/management";
private static final String MONITORING_URL = "http://localhost:4848/monitoring";
private static final String CONTENT_TYPE_JSON = "application/json";
private static final String CONTENT_TYPE_XML = "application/xml";
private static final String ACCEPT_ALL = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
private static final Logger LOG = Logger.getLogger(AdminGlassFish.class.getName());

public static void main(String args[]) throws IOException, HttpException, URISyntaxException {

//just chaning the indent level for the JSON and XML output to make them readable, for humans…
String prettyFormatRestInterfaceOutput = "{"indentLevel":2}";
String response = postInformation("/domain/configs/config/server-config/_set-rest-admin-config", prettyFormatRestInterfaceOutput);
LOG.info(response);
//getting list of all JDBC resources
String jdbcResources = getInformation("/domain/resources/list-jdbc-resources");
LOG.info(jdbcResources);

// creating a JDBC resource on top of the default pool
String createJDBCResource = "{"id":"jdbc/Made-By-Rest","poolName":"DerbyPool"}";
String resourceCreationResponse = postInformation("/domain/resources/jdbc-resource", createJDBCResource);
LOG.info(resourceCreationResponse);

// deleting a JDBC resource
String deletionReponse = deleteResource("/domain/resources/jdbc-resource/jdbc%2FMade-By-Rest");
LOG.info(deletionReponse);

}

//using HTTP get
public static String getInformation(String resourcePath) throws IOException, AuthenticationException {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpG = new HttpGet(ADMINISTRATION_URL + resourcePath);
httpG.setHeader("Accept", CONTENT_TYPE_XML);
HttpResponse response = httpClient.execute(httpG);
HttpEntity entity = response.getEntity();
InputStream instream = entity.getContent();
return isToString(instream);
}

//using HTTP post for creating and partially updating resources
public static String postInformation(String resourcePath, String content) throws IOException {
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(ADMINISTRATION_URL + resourcePath);
StringEntity entity = new StringEntity(content);

//setting the content type
entity.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, CONTENT_TYPE_JSON));
httpPost.addHeader("Accept",ACCEPT_ALL);
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost);

return response.toString();
}

//using HTTP delete to delete a resource
public static String deleteResource(String resourcePath) throws IOException {
HttpClient httpClient = new DefaultHttpClient();
HttpDelete httpDelete = new HttpDelete(ADMINISTRATION_URL + resourcePath);
httpDelete.addHeader("Accept",
ACCEPT_ALL);
HttpResponse response = httpClient.execute(httpDelete);
return response.toString();

}

//converting the get output stream to something printable
private static String isToString(InputStream in) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(in), 1024);
for (String line = br.readLine(); line != null; line = br.readLine()) {
sb.append(line);
}
in.close();
return sb.toString();
}
}
[/java]

You may ask how could one know what are the required attributes names, there are several ways to do it:

  • Look at the reference documents…
  • View the source code of the html page representing that kind of resource, for example for the JDBC resource it is like http://localhost:4848/management/domain/resources/jdbc-resource which if you open it in the browser you will see an html page and viewing its source will give you the names of different attributes. I think the label for the attributes is also the same as the attributes themselves.

  • Submit the above page and monitor the request using your browser plugin, for example in case of chrome and for the JDBC resource it is like the following picture

GlassFish administration, authentication and transport security

By default when we install GlassFish or we create a domain the domain administration console is not protected by authentication nor it is protected by HTTPS so whatever we send to the application server from through this channel will be readable by someone sniffing around. Therefore you may need to enable authentication using the following command:

./asadmin change-admin-password

You may ask now that we enabled the authenticaiton for the admin console, how we can use it by our sample code, the answer is quite simple,  Just set the credentials for the request object and you are done. Something like:

[java]
UsernamePasswordCredentials cred = new UsernamePasswordCredentials("admin", "admin");
httpget.addHeader(new BasicScheme().authenticate(cred, httpget));
[/java]

Make sure that you are using correct username and passwords as well as correct request object. In this case the request object is httpGet

Now about the HTTPs to have have encryption during the transport we need to enable the SSL for the admin HTTP listener. following steps show how to use the RESTFul interface through a browser to enable HTTPS for the admin console. When using the browser, GlassFish admin console shows basic HML forms for different resources.

  1. Open the http://localhost:4848/management/domain/configs/config/server-config/network-config/protocols/protocol/admin-listener in the browser
  2. Select true for security-enabled option element
  3. Click Update to save the settings.
  4. Restart server using http://localhost:4848/management/domain/restart

The above steps have the same effect as

./asadmin enable-secure-admin

This will enable the SSL layer for the admin-listener but it will use the default, self singed certificate. Here I explained how to install a GoDaddy digital certificate into GlassFish application server to be sure that none can listen during the transport of command parameters and on the other hand the certificate is valid instead of being self signed. And here I explained how one can use the EJBCA to setup and use an small inter-corporate certificate authority with GlassFish, though the manual is a little old but it will give you enough understanding to use the newer version of EJBCA.

If you are asking about how our small sample application can work with this dummy self signed certificate of GlassFish you need to wait till next time that I will explain how to bypass the invalid certificate installed on our test server.

In the next part of this series I will cover more details on the monitoring part as well as discussing  how to bypass the self signed Digital certificate during the development…

GlassFish security book contest: Here are the lucky winners

Thank you all who accepted the challenge and took the quiz. Now it is time to see who are the luckier ones winning the prizes which are copies of GlassFish Security book. To give you an statistic about the quiz participants,

GlassFish Security Book

I had 156 participants. though some of them, maybe 20 – 30 are quiz result submitted more than once by some of the participants.

Before we jump to the list of winners, I should explain the questions which I posted in the quiz.  The questions I selected for the quiz are mostly based on chapter 3 of the book which is available for free in packt website.

So the questions, the answers and the explanation about each question are as follow.


1. Which one of the following statements is correct?

A. We can specify which security realm we want our web module to use in the sun-web.xml.
B. We can specify which security realm we want our web module to use in the web.xml.
C. We can use sun-application.xml to specify which security realm we want our enterprise application to use
D. B and C are correct.

We can use both the web.xml and sun-application.xml to specify the security realm. In the web.xml we use the login-conf element as shown below:

<login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>LDAP_Realm</realm-name>
</login-config>

And in the sun-application.xml we can specify the application wide security realm as shown in the following snippet.

<sun-application>
    <realm>LDAP_Realm</realm>
</sun-application>

The realm is an immediate child of the sun-application element.


2. Which one of the following statements shows new security features included in Java EE 6?

A. The programmatic login and logout methods in logout in HttpServletRequest interface.
B. Inclusion of @ServletSecurity Annotation to annotate a Servlet and enforce security.
C. Inclusion of the authenticate method in the HttpServletRequest interface.
D. All of the above.

Yes, all of this new features are included in Java EE 6 to enhance the security APIs and ease their use.


3. Where we should place the login-config element?

A. In web.xml
B. In sun-web.xml
C. In sun-application.xml
D. In A and C

The login-conf element goes to web.xml to specify the security realm and the authentication method. To see an snippet about this look at the explanation of the first question


4. What are j_username and j_password when it come to Java EE security?

A. These are two per-defined filed names which we must use in FORM authentication to pass the username and the password to the container.
B. These are two per-defined filed names which we must use in BASIC authentication type to pass the username and the password to the container.
C. Both of A and B are correct.
D. None of the above items.

To see some snippet about how we can have FORM authentication, you can take a look at the GlassFish security book chapter 3 which is freely available.


5. When we talk about security, which of the following sequences is more accurate?

A. Identification, Authentication, Authorization
B. Authentication, Authorization, Identification
C. Authentication, Identification, Authorization
D. Authorization, Authentication, Identification

‌Before we try to authenticate a credential we should receive a credential showing who the requester is claiming to be. After we received the credentials, we should check the credentials validity and finally after we find that the credentials are valid we can check the access level of the provided credentials.


And now the winners
The paper copy goes to: Bruno Antunes
First ebook copy goes to: Alireza Haghighatkhah
Second ebook copy goes to: Deny Wuysan

I have not received replys from some of the participants about their country of residence so I put them into the second list. I will contact the winners to coordinate the distribution of the copies with them.

I am looking for a way to have more contest about GlassFish security book in the coming month. Specially small 2 question quiz which the winner will receive a e-book copy of the title.

JavaZone 2010 sessions I am going to attend

I will be attending JavaZone 2010 both as an speaker presenting NIO.2 and as an atendee sitting and learning new technologies other speakers kindly share. After looking at the list of sessions, here is the sessions I decided to attend. It is really hard to decided on which speaker and subject to choose. All speakers are known engineers and developers and selected subjects are exceptionally good.

I may change few of this items as JZ2010 staff updates the agenda but majority of the sessions will be what I have already selected. See you at JZ2010 and the JourneyZone afterward the conference itself.

8th of September:

  1. Emergent Design — Neal Ford
  2. JRuby: Now With More J! — Nick Sieger
  3. Howto: Implement Collaborative Filtering with Map/Reduce – Ole-Martin Mørk
  4. Building a scalable search engine with Apache Solr, Hibernate Shards and MySQL – Aleksander Stensby, Jaran Nilsen
  5. The not so dark art of Performance Tuning — Dan Hardiker, Kirk Pepperdine
  6. Creating modular applications with Apache Aries and OSGi — Alasdair Nottingham
  7. Java 7 NIO.2: The I/O API for Future — Masoud Kalali -> I am Speaking here
  8. The evolution of data grids, from local caching to distributed computing – Bjørn Vidar Bøe

9th of September:

  1. NOSQL with Java — Aslak Hellesøy
  2. CouchDB and the web — Knut O. Hellan
  3. Decision Making in Software Teams — Tim Berglund
  4. A Practical Introduction to Apache Buildr — Alex Boisvert
  5. Architecture Determines Performance — Randy Stafford
  6. Surviving Java Maintenance – A mini field manual — Mårten Haglind
  7. Using the latest Java Persistence API 2.0 features — Arun Gupta

JavaZone 2010, Oslo
JavaZone 2010, JavaZone logo

GlassFish Security book FAQ 1: Custom Security Realm in GlassFish

I decided to write down the answer for some questions which my book’s readers email me or ask me via twitter in my weblog so everyone can benefit from the answers. Here is the answer to the first question which involves custom security realms.

GlassFish supports 5 types of security realms out of the box which are sd follow:

  1. File Realm: Usefull for development and testing purposes. GlassFish provids a user/ group management interface for this realm. We can add user and groups using the administration console. When using this realm all usernames, passwords and groups are stored in a plain text file.
  2. JDBC Realm: In production environment we store user information including but not limited to username, passwords and groups in an RDBMS and then configure a JDBC realm to authenticate the given credentials againts the information stored in the datase.
  3. LDAP Realm: Sometimes we have all user details stored in an LDAP like Active Directory or Redhat Directory Server, OpenDS or Sun Java System Directory Server Enterprise Edition.
  4. Solaris Realm: This realm is used to authenticate users with a Solaris user directory.
  5. Certificate Realm: The certificate realm allows us to conduct mutual SSL authentication based on the client certificates.

Sometimes our users information is stored in a silo different than all of this mentioned storages and we need to use that source for authentication and access control. For example assume that we have our users information including username, passwords and group membership stored in an Object Database and we need to authenticate our enterprise application’s users with that storage. In such times we should either think about having a synchronized RDMBS keeping update user information and use JDBC realm for authentication and authorization or we should develop  a custom security realm which uses the object database as a source for authentication.

Setting up synchronization between the e.g object database and RDBS can be tricky while developing a custom authentication realm is much easier using GlassFish provided SPIs.

Second chapter of GlassFish security book discusses GlassFish security realms in details and discuss a sample application which uses these realms for authenticating and authorizing users. In the same chapter, developing custom security realms is discussed along with developing a sample realm.

In the same chapter GlassFish support for  JSR-196 (Java Authentication Service Provider Interface for Containers) is discussed to complete the ring of authentication and authorization in Java EE in general and GlassFish application server in particular.