How to implement self-managed web users with Java EE 6?

I want to create a simple web application in which there will be users with self-registration. In other words, I want users to be able to register, register, manage their data, log out and, if you want, delete their account. This is a kind of hobby project and just to learn something new, I decided to try to create this website using the latest Java EE, which I had not used before.

I spent several hours reading JAAS, authentication rules, etc., and I found many ways to implement security based on users and roles defined on the server (e.g. GlassFish), but I did not find examples or pointers to how to implement a solution in which users can simply fill out the registration form on the web page and become users in the system. Of course, I can just have a database table with usernames and passwords and implement everything manually, but that defeats the goal.

So my questions are:

  • Is the standard Java EE authentication and security environment suitable for implementing an application in which users can manage themselves? Or is it more of an β€œenterprise” and relies on external authentication and user management?
  • If it's easy to do what I need, give me some examples.

Thanks!

+8
java authentication
source share
2 answers

J2EE is not very good at that. However, I did this in the application. I have a user table in the database (only) used by my application, and I declared a scope in the context.xml file in the META-INF webapp directory (I use tomcat btw):

<Realm className="org.apache.catalina.realm.DataSourceRealm" dataSourceName="jdbc/fantastico" debug="99" localDataSource="true" digest="MD5" roleNameCol="ROLE" userCredCol="PASSWORD" userNameCol="USERNAME" userRoleTable="user_roles" userTable="active_users"/> 

the data source is the same as that used in the rest of the application and is declared in the server.xml file of the tomcat installation (so that I can point to another db without changing the .war file).

I protected the places with roles in the web.xml file, making sure that I had the registration page and the login page:

 <security-constraint> <display-name>Administrators</display-name> <web-resource-collection> <web-resource-name>admin</web-resource-name> <description>Admin</description> <url-pattern>/admin</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> <description>Allow access only to administrators</description> <role-name>admin</role-name> </auth-constraint> </security-constraint> 

I specified the <login-config> section with FORM as the auth method:

 <login-config> <auth-method>FORM</auth-method> <realm-name/> <form-login-config> <form-login-page>/login/</form-login-page> <form-error-page>/login/error</form-error-page> </form-login-config> </login-config> 

Since the scope is declared as using the MD5 digest, this is the MD5 password that must be stored in the database:

 private static final char HEX[] = "0123456789abcdef".toCharArray(); public static String hex(byte data[]) { char[] chars = new char[2*data.length]; for (int i=0; i < data.length; i++) { int low = data[i] & 0x0f; int high = (data[i] & 0xf0) >> 4; chars[i*2] = HEX[high]; chars[i*2 + 1] = HEX[low]; } return new String(chars); } public static byte[] hash(byte data[]) { synchronized (DIGEST) { DIGEST.reset(); return DIGEST.digest(data); } } public static String hash(String value) { try { byte data[] = hash(value.getBytes("UTF-8")); return hex(data); } catch (UnsupportedEncodingException e) { // Cannot happen: UTF-8 support is required by Java spec LOG.error("Failed to generate digest", e); throw new RuntimeException(e.getMessage()); } } 

In the login form, this tomcat will be displayed whenever authentication is required, I added a link to the registration form:

...

 <form id="login-form" action="j_security_check" method="post"> <table> <tbody> <tr> <td><label for="username">User name:&nbsp;</label></td> <td><input type="text" name="j_username" id="username" /></td> </tr> <tr> <td><label for="password">Password:&nbsp;</label></td> <td><input type="password" name="j_password" id="password" /></td> </tr> <tr> <td>&nbsp;</td> <td><input type="submit" id="submit" name="submit" value="Login"></td> </tr> <tr> <td>&nbsp;</td> <td><a href="../reg/create">I'm a new user</a></td> </tr> </tbody> </table> </form> 

...

Now that the registration form has been submitted, I store the user in the database and I submit the redirection for the user to automatically log in:

...

 response.sendRedirect(request.getContextPath() + "/j_security_check?j_username=" + URLEncoder.encode(getEmail(), "UTF-8") + "&j_password=" + URLEncoder.encode(password, "UTF-8")); 

...

Hope this helps

+1
source share

Alternatively, you can take a look at the Spring Security framework . I used it with my Grails projects the way you described, with user signatures on my own, and I found it easy to use.

0
source share

All Articles