Security

Security

Security can be added by adding a User table which contains a name, password and RoleType. For example:

User=$CREATE $CREATOR
readTable.0=User
readColumn.User.0=user INTEGER PRIMARY KEY
readColumn.User.1=loginName VARCHAR(20) NOT NULL
readColumn.User.2=password VARCHAR(128) NOT NULL
readColumn.User.3=retries INTEGER
readColumn.User.4=roleType VARCHAR(10) NOT NULL
readColumn.User.5=dateTimeStamp TIMESTAMP NOT NULL

In this example every user only has one role, you would have to create another table, or use an array type to handle that.

RoleType=$CREATE $ENUMCREATOR
RoleType.type.0=ADMIN,admin,Administrator
RoleType.type.1=USER,user,User
RoleType.find.0=all,ADMIN,USER

Note: the key (admin/user) will be set up on the web config file.

Jlogin

Security can be added orthogonally using a 'j_security_check' security form. This form is specificed by the following line in the default bdl.

jsight.elements.7=templates/elements/jlogin.jsp,env=jsight.jlogin,dest=$ROOT/login/jlogin.jsp

This line of code points to a login.jsp template in the java com.javelin.generator.jsp package and moves it to the /login directory

The line can be overrriden in the application bdl file to point to a different file

jsight.elements.7=C:/mydir/jlogin.jsp,env=jsight.jlogin,dest=$ROOT/login/jlogin.jsp

The image below illustrates the login form.

Here's the contents of the web page

<link rel="stylesheet" href="/admin/elements/default.css" type="text/css">
<html>
<head>
<title>Login</title>
</head>

<body>

<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td height=100 align="center" valign="center" class="jsightTableTitles" >LOGIN</td>
</tr>
<tr>
<td height=200 align="center" valign="center" >
<form action='j_security_check' method="POST" name="loginForm">
<input name="j_uri" type="hidden" value="admin/index.jsp">
<table width="300" height=100 cellspacing="0" cellpadding="0" class="jsightTableFields">
<tr>
<td width=10></td>
<td width="78">Name</td>
<td colspan="2"><input type="text" name="j_username"></td>
</tr>
<tr>
<td width=10></td>
<td>Password</td>
<td colspan="2"><input type="password" name="j_password"></td>
</tr>
<tr>
<td width=10></td>
<td></td>
<td width="102"><input name="Login" type="submit" class="button" value="Login"></td>
<td width="108"><input name="Cancel" type="reset" class="button" value="Cancel"></td>
</tr>
</table>
</form>
</td>
</tr>
</table>

</body>

JSight

The web server can be made to go through the jlogin form whenever the /admin directory is accessed. In resin the configuration is as follows:

<authenticator>
<class-name>com.caucho.http.security.XmlAuthenticator</class-name>
<init-param path='C:/javelin/expensys/web/WEB-INF/passwords.xml'/>
</authenticator>

<login-config>
<auth-method>FORM</auth-method>
<realm-name>default</realm-name>
<form-login-config>
<form-login-page>/login/jlogin.jsp</form-login-page>
<form-error-page>/login/jlogin.jsp</form-error-page>
</form-login-config>
</login-config>


<security-constraint>
<web-resource-collection>
<url-pattern>/admin/*.jsp</url-pattern>
</web-resource-collection>
<auth-constraint role-name='user'/>
</security-constraint>

The password in this configration is held in an XML file (C:/javelin/expensys/web/WEB-INF/passwords.xml). The webserver you use should also support access to a database. This could be a User table that you have defined.

Here’s the xml file – you could use a database realm etc. in tomcat

<authenticator>
<user name='expensys' password='password' role='user'/>
</authenticator>


 

Application

You can add different directories to the config file to protected them for different roles.

From a jsp/servlet perspective once this is done the servlet API will now have some User values set up.

The HttpRequest.getUserPrincipal() is now set up.

The Principal object just has a getName() (and hashcode,equals,toString) method which returns the j_username.

You can also do the call HttpRequest.isUserInRole( String role ) to check if the user has a role set (in this case the role is just user).

This role can be set up to be your role type,so you might call request.isUserInRole( (String)UserType.CLIENT.getKey() );

Digestion

The web server can be to digest (encrypt) the password when it is checked against the password store (i.e. database table). This means that you datastore must digest your password in the same way that your database will.

For Tomcat you can digest the password using the following method. In this case when you set up the tomcat config ensure to tell it you wish the password to be digested with the MD5 security algorithm.

password = org.apache.catalina.realm.RealmBase.Digest(password, “MD5”);

Digesting this password could be set in custom application forms in which case the programmer will have to ensure it is called before being set on the User bean.

Alternatively is could be digested inside the bean. To do this you can call the transformIn property as follows

User.password.transformIn=UserUtil.digestPassword( this, password )

Doing this however requires that you keep track of whether the password is digested, so that you don't digest the digested password, when you set and get the password.

To do this you could add a passwordDigested boolean property to the User table and check that before you digest the password.

readColumn.User.4=passwordDigested BIT NOT NULL

An example digestPassword method

public static String digestPassword( User user, String password )
{
if( password != null && !user.isPasswordDigested() )
{
password = org.apache.catalina.realm.RealmBase.Digest(password, “MD5”);
user.setPasswordDigested(true);
}
return password;
}

If you want to write a custom authentication there is a class called com.javelin.util.MD5Util that can be used to digest passwords for you.