Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This example, shows us how to setup Tomcat JDBCRealm JDBCRealms to use it within of our your projects.This type of realm involves to register registering usernames, passwords and assigned roles inside a database and this information which is then used by authentication methods.

Next, we are going to explain step by step what we need to do.

For this example, we are The following steps explain how.implement this approach:

This example has been built using:

Tomcat Web Server Tomcat 7.0.20. You can download the latest version here.

DataBase MySQL Database - 5.0.45-community-nt. You can download the latest version here.

1.- Set up JDBCRealm JDBCRealms on Tomcat,  locate the server.xml configuration file in <TOMCAT_HOME>/conf/,  then, add the following lines where corresponds:

Code Block
langxml
<Realm className="org.apache.catalina.realm.JDBCRealm"
  driverName="com.mysql.jdbc.Driver"
  connectionURL="jdbc:mysql://localhost/smartgwt?user=smart&amp;password=smart"
  userTable="isg_users" userNameCol="user_name" userCredCol="user_passwd"
  userRoleTable="isg_users_roles" roleNameCol="role_name"/>

Note. You have to Please copy the jdbc library of MySql into MySql  jdbc library to <TOMCAT_HOME>/lib/.

2.- We have to create Create a new database and create with the following tables:

Code Block
langsql
create table `isg_roles` (
	`ROLE_NAME` varchar (60)
);
insert into `isg_roles` (`ROLE_NAME`) values('admin');
insert into `isg_roles` (`ROLE_NAME`) values('manager');
insert into `isg_roles` (`ROLE_NAME`) values('manager-gui');
insert into `isg_roles` (`ROLE_NAME`) values('manager-script');
insert into `isg_roles` (`ROLE_NAME`) values('manager-status');
insert into `isg_roles` (`ROLE_NAME`) values('tomcat');

create table `isg_users` (
	`USER_NAME` varchar (60),
	`USER_PASSWD` varchar (60)
);
insert into `isg_users` (`USER_NAME`, `USER_PASSWD`) values('tomcat','tomcat');
insert into `isg_users` (`USER_NAME`, `USER_PASSWD`) values('admin','admin');

create table `isg_users_roles` (
	`USER_NAME` varchar (60),
	`ROLE_NAME` varchar (60)
);
insert into `isg_users_roles` (`USER_NAME`, `ROLE_NAME`) values('admin','admin');
insert into `isg_users_roles` (`USER_NAME`, `ROLE_NAME`) values('admin','manager');
insert into `isg_users_roles` (`USER_NAME`, `ROLE_NAME`) values('admin','manager-gui');
insert into `isg_users_roles` (`USER_NAME`, `ROLE_NAME`) values('admin','manager-status');
insert into `isg_users_roles` (`USER_NAME`, `ROLE_NAME`) values('tomcat','tomcat');

3.- Create a user with all grants access rights on the created tables of the new database, in . In this example, the user is "smart" and the database name is "smartgwt"

4.- Set up the web.xml file of for the example to use the authentication method as Form based:

Code Block
langxml
    <login-config>
		<auth-method>FORM</auth-method>
		<realm-name>User Auth</realm-name>
			<form-login-config>
				<form-login-page>/login.html</form-login-page>
				<form-error-page>/error.html</form-error-page>
			</form-login-config>
    </login-config>
    <security-role>
		<role-name>*</role-name>
    </security-role>

   <security-constraint>
	  <web-resource-collection>
		  <web-resource-name>Sample Application</web-resource-name>
		  <url-pattern>*.html</url-pattern>
		  <url-pattern>/securitytomcat/sc/IDACall/*</url-pattern>
		  <http-method>POST</http-method>
		  <http-method>GET</http-method>
	  </web-resource-collection>

	  <auth-constraint>
		<role-name>*</role-name>
	  </auth-constraint>
    </security-constraint>

Here there is an example of a replacement login page with some attractive styling.

Until nowCurrently, all of the above steps were to setup JBDCRealm have related to setting up JBDCRealms on Tomcat.

As from the next step, we are going to explain some functionalities of this exampleThe following steps explain how to implement additional functionality:

5.- We create Create an interface for editing user and role assignments, this . This will only be only accessible to a user with role "admin", in other case. For any other roles, the system will throws throw an error.We are going to need 3

Create 3 new *.ds.xml files:

Code Block
langxml
titleusers.ds.xml
<DataSource
    ID="users"
    serverConstructor="com.smartgwt.sample.server.UsersDataSource"
>
    <fields>
        <field name="userName"        type="text"  title="User Name"      primaryKey="true" />
    </fields>
</DataSource>

...

After the user is authenticated, we are going to save the assigned roles of the user, this we make with a new servlet, which is named ServletLogin and the relevant code is the followingfor this user. Create a new servlet to do this (in this case we will call it ServletLogin).

The following code describes this new servlet:

Code Block
titleServletLogin.java
Principal principal = request.getUserPrincipal();
GenericPrincipal genericPrincipal = (GenericPrincipal) principal;
final String[] roles = genericPrincipal.getRoles();
String userRoles = "";
for (int i = 0; i < roles.length; i++) {
    userRoles = userRoles + roles[i]+",";
}
PrintWriter writer = response.getWriter();
writer.append(userRoles);

In the web.xml file, add the following lines:

Code Block
langxml
    <servlet>
	<servlet-name>ServletLogin</servlet-name>
	<servlet-class>com.smartgwt.sample.server.ServletLogin</servlet-class>
    </servlet>
    <servlet-mapping>
            <servlet-name>ServletLogin</servlet-name>
	 <url-pattern>/ServletLogin</url-pattern>
    </servlet-mapping>

In the client-side, the relevant code isside function, add this code to invoke the new servlet using the RPCManager:

Code Block
RPCRequest request = new RPCRequest();
request.setActionURL("ServletLogin");
RPCManager.sendRequest(request,new RPCCallback(){
public void execute(RPCResponse response, Object rawData, RPCRequest request) {
	        	 User.setRoles(rawData.toString());
       			 if (User.hasRole("admin")) {
	        		theTabs.addTab(tabRoles);
	        	 	theTabs.addTab(tabItems);
	        	 } else {
	        		 theTabs.addTab(tabItems);
	        	 }
	         }
	     });

SoIn the above snippet, if the authenticated user has the role admin, then the user will have access to the interface for editing user and role assignments.

Additionally, we need another class in on the client-side,  this .  This is the User Class , and the relevant code is the followingfor the actual user roles:

Code Block
        private static String roles;
	public static void setRoles(String ro) {
		roles = ro;
	}

	public static boolean hasRole(String role) {
		if (roles.contains(role)) {
			return true;
		}
		return false;
	}

Last, we show you a Finally, below are some screenshots of this example in action.

Picture 1.- Interface of edition editing for the user with admin role.

Picture 2.- Just to verify an error, in case Error validation example (where the user can has access to the interface of edition(this could be with editing interface via another role, (e.g. manager), but does not have the admin role ( required for editionediting).

6.- Display the effects of the configuration: editRequiresRole="admin" and viewRequiresRole="admin" in the .ds.xml file.

For this example,  we are going to need use the supplyItem.ds.xml file:

Code Block
langxml
titlesupplyItem.ds.xml
<DataSource
    ID="supplyItem"
    recordXPath="/List/supplyItem"
    dataURL="ds/test_data/supplyItem.data.xml"
>
    <fields>
        <field name="itemID"      type="sequence" hidden="true"       primaryKey="true"/>
        <field name="itemName"    type="text"     title="Item"        length="128"       required="true"
        	   editRequiresRole="admin" />
        <field name="SKU"         type="text"     title="SKU"         length="10"        required="true"
               editRequiresRole="admin" />
        <field name="description" type="text"     title="Description" length="2000"
               viewRequiresRole="admin" />
        <field name="category"    type="text"     title="Category"    length="128"       required="true"
               editRequiresRole="admin"
               foreignKey="supplyCategory.categoryName"/>
        <field name="units"       type="enum"     title="Units"       length="5" editRequiresRole="admin">
            <valueMap>
                <value>Roll</value>
                <value>Ea</value>
                <value>Pkt</value>
                <value>Set</value>
                <value>Tube</value>
                <value>Pad</value>
                <value>Ream</value>
                <value>Tin</value>
                <value>Bag</value>
                <value>Ctn</value>
                <value>Box</value>
            </valueMap>
        </field>
        <field name="unitCost"    type="float"    title="Unit Cost"   required="true" editRequiresRole="Admin">
            <validators>
                <validator type="floatRange" min="0" errorMessage="Please enter a valid (positive) cost"/>
                <validator type="floatPrecision" precision="2" errorMessage="The maximum allowed precision is 2"/>
            </validators>
        </field>
        <field name="inStock"   type="boolean"  title="In Stock" viewRequiresRole="admin" />
        <field name="nextShipment"  type="date" title="Next Shipment" viewRequiresRole="admin" />
    </fields>
</DataSource>

After the user is authenticated, we have some screenshots to see this example The following screenshots show editRequiresRole and viewRequiresRole in action.

Picture 3. This is the interface for the user with the For a  user with admin role access.

Picture 4. This is the interface for the For a user without the admin role access, hereIn this example, the fields with editRequiresRole="admin" will be read-only, and the fields with viewRequiresRole="admin", will not be visible.

Picture 5. This is the error in case that . Error validation example where the user does not have the Admin role access and wants to save data.

7.- Finally, we are going to show you how works below is an example  of how the re-login mechanism , this works. This occurs when the session of the user is invalidateinvalidated, si if the user wants to continue editing, they will be forced to re-authenticate.

Picture 6. The window re-login.

Picture 7. In case of the usernameUsername/password are incorrect validation check.

The following code is required inside of your the login page, to use the re-login mechanism.

...

While the user is being re-authenticateauthenticated, the requested operation is put on hold, if . If the re-authentication is successful, the operation on hold, just is released and continues as normal.

More information about You can find more information relating to the re-login mechanism here.

...