lunedì 6 febbraio 2012

Security with jaas

Security is a big issue about enterprise web applications and involves many aspects like authentication, authorization and security of communication. Implementing by your own all these aspects is not a good idea so i choose to use the security tools offered by jboss that are based on jaas (Java Authentication and Authorization Security).

Every time that a resource receive a request this is forwarded to a security domain that has the purpose to check every security aspects.

From now on I will explain how configure the three main aspects cited before: authentication, authorization and communication security.

Authentication:


In my application I chose to use a form base authentication method:

first of all we need to create a form in our html/jsp page like the following:

<form action='j_security_check' name="loginForm" method="POST">
     <input type="text" name="j_username" id="username"/>
     <input type="password" name="j_password" id="password"/>
     <input type="submit" value="Login" name="Login">
</form>


Note that the action of the form must be 'j_security_check', the name of the username input 'j_username' and the name of the password input 'j_password'.


Then we need to define a security domain in jboss, in order to do it we have to edit the file login-config.xml, that we find in the conf folder of the jboss distribution, and add the following xml definition: 


1 <application-policy name="realm_name">
2   <authentication>
3     <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
4          <module-option name="unauthenticatedIdentity">AnonymousUser</module-option>
5          <module-option name="dsJndiName">java:/MySqlDS</module-option>
6          <module-option name="principalsQuery">SELECT password FROM User WHERE username=? </module-option>
7          <module-option name="rolesQuery">SELECT name, 'Roles' FROM Role, User  WHERE Role.id=User.role_id_ext              AND User.username=?</module-option>
8          <module-option name="hashAlgorithm">SHA-1</module-option>
9          <module-option name="hashEncoding">hex</module-option>
10    </login-module>
11  </authentication>
12 </application-policy>


The first row set the name of the security domain, while the third is used to specified that the verification of data inserted in the form are checked using data retrieved from a database.
In the row number 4 we set the name of the principal in the case of an unauthenticated user.
The row number 5 set the jndi name of the datasource of the database from wich we retrieve the data containing the users and the roles.
Rows number 6 and 7 represents the query used to retrive the password and the role from the database given the password and the username.
The rows 8 and 9 instead are used only if we use some encryption for the passwords.

ATTENTION: in the query for extract the roles the second field is used as group id, but even if we have no group id field in our table we have to specified and call it 'Roles', if you don't use exactly Roles, jaas will not be able to identify the role of the user so it fails in the authorization security!




After that we need to specify in our application that we use the security domain that we have previously specified, this is done in the jboss.xml file. So it should be like the following:


<?xml version="1.0" encoding="UTF-8"?>
<jboss>
     <security-domain flushOnSessionInvalidation="true"> realm_name </security-domain>
     <unauthenticated-principal>AnonymousUser</unauthenticated-principal>
</jboss>



NOTE: realm_name is the name of the security domain specified before in the login-config.xml in jboss.


Now in the web.xml file of our application we need to specified the login_config that indicates: the method used to authenticate the users, the security domain to use,  the login page and the error page to be forwarded in case of wrong credentials.



<login-config>
   <auth-method>FORM</auth-method>
   <realm-name>realm_name</realm-name>
   <form-login-config>
      <form-login-page>/login.html</form-login-page>
      <form-error-page>/loginFailed.html</form-error-page>
   </form-login-config>
</login-config>


Authorization:


In our case authorization is specified in the web application, so in the web.xml file we add the following code:



<security-constraint>
   <display-name>reader</display-name>
   <web-resource-collection>
        <web-resource-name>reader actions</web-resource-name>
        <description />
        <url-pattern>/restricted.html</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
        <http-method>HEAD</http-method>
        <http-method>PUT</http-method>
        <http-method>OPTIONS</http-method>
        <http-method>TRACE</http-method>
        <http-method>DELETE</http-method>
   </web-resource-collection>
   <auth-constraint>
      <role-name>reader</role-name>
   </auth-constraint>
   <user-data-constraint>
       <transport-guarantee>CONFIDENTIAL</transport-guarantee>
   </user-data-constraint>
</security-constraint> 


Whit this code we indicates the resource that the role can access, in this case the restricted.html page, the allowed methods, obviously the role associated to these constraints. With the <transport-guarantee> tag instead specified how  works the communication between the client and the server, in our case we set it ti CONFIDENTIAL, that means that the data exchanged must be encrypted.
Other option to use could be NONE, if no guarantee is needed, and INTEGRAL if we want ensure that nobody modify the data in transit in the channel.

Then the last thing that we need to do is to define the roles present in our application, an example of role definition is the following:

<security-role>
   <description>Administrator role.</description>
   <role-name>administrator</role-name>
</security-role>


COMMUNICATION SECURITY

Now I will explain how to use SSL in jboss, the thing to do to enable HTTPS are the following:
  • obtain a certificate for the server
  • insert this in the keystore of the server
  • define a connector for https
  • link the connector to the keystore
To obtain the certificate we can use keytool, so that we generate a self-signed certificate, to do that we need to execute the following code:

       keytool -genkey -alias myserver -keyalg RSA -validity 1500 -keystore server.keystore


and answer to the questions that will appear.
So now we get the keystore that must be place in the conf folder in jboss.

Then we need to create a connector for https and link it to the keystore, to do that we need to edit the file server.xml in jboss and add the connector definition in which we specified the keystore created before:

 <!--SSL/TLS Connector configuration using the admin devl guide keystore-->
      <Connector protocol="HTTP/1.1" SSLEnabled="true" 
           port="8443" address="${jboss.bind.address}"
           scheme="https" secure="true" clientAuth="false" 
           keystoreFile="${jboss.server.home.dir}/conf/myserver.keystore"
           keystorePass="myserver" sslProtocol = "TLS" />


LOGGING:

A suggestion that I can give you is to enable the logging in jboss-logging.xml for the security part:
in jboss 6.1 the file is located in the deploy folder, edit the file and add these definiton:


   <logger category="org.jboss.security">
      <level name="TRACE"/>
   </logger>

   <logger category="org.jboss.web.tomcat.security">
      <level name="TRACE"/>
   </logger>
      
   <logger category="org.apache.catalina">
      <level name="TRACE"/>
   </logger>

The log is stored in the log folder of jboss server and is named server.log


venerdì 3 febbraio 2012

Using external jars in GWT

In order to use external jars in GWT we need to make them available  to the GWT compiler as modules. This because if we simply add the jars to the class path only the java compiler complains about them while the GWT compiler not.

So the steps to do to solve this problem are the following:


  1. Create a gwt.xml file in the Java project / jar file that we want to use.
  2. Include the library inheriting the module created at the step before.
  3. Include in the jar the source files.
Example: if we have the package it.unitn.example.utils and we want ot inform the GWT compiler about the classes that it includes we need to create in the package  it.unitn.example the file utils.gwt.xml, containing the following code:

<module>
  <inherits name='com.google.gwt.user.User'/>
  <source path="utils"></source>
</module>

Then if we want to use this module in a GWT project we only need to inherits it as for the other modules:

package it.unitn.example.application.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;

import it.unitn.example.utils.ExUtilClass;

public class ModulTest implements EntryPoint {

 @Override
 public void onModuleLoad() {
  ExUtilClass utilClass = new ExUtilClass();
  // doing something with utilClass
 }

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.6.4//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.6.4/distro-source/core/src/gwt-module.dtd">
<module rename-to='it.unitn.example.application'>
  <!-- Inherit the core Web Toolkit stuff.                        -->
  <inherits name='com.google.gwt.user.User'/>

  <inherits name='com.google.gwt.user.theme.standard.Standard'/>
  <inherits name='it.unitn.example.utils'/>
  <!-- Other module inherits                                      -->

  <!-- Specify the app entry point class.                         -->
  <entry-point class='it.unitn.example.application.client.AppExample'/></module>

giovedì 2 febbraio 2012

GWT & EXT-GXT

To implement the web tier i will use the GWT library that allow us to crete rich internet application using javascript and XML, all starting from java code.
A good and well explained tutorial can be found at the home page of the Google Web Toolkit.

In this picture we can see how GWT works:

In few word the only thing that we need to implement are the two interfaces:

MyService: containing the methods that we want to implement, and
MyServiceAsync: containing the methods that can be called from the client-side

Obviously we only need to implement the class that implements the MyService interface since the asynchronous one, as we can see in the picture, is automatically generated by the library.
But here you can read more about it.

I will use also the gxt-ext library to implement the user interface part, since it allows to generate a lot of widgets. At this page there are a lot of examples that show the power of this library.