我想创建一个具有自我注册用户的简单Web应用程序。换句话说,我希望用户能够注册,登录,管理其数据,注销,并在需要时删除其帐户。这是一个业余项目,只是为了学习新知识,我决定尝试使用最新的Java EE创建此网站,而我以前从未使用过。
我花了几个小时阅读有关JAAS,身份验证领域等的内容,我发现了许多方法可以根据服务器上定义的用户和角色(例如GlassFish)来实现安全性,但是我没有找到任何示例或如何实现解决方案的指针。用户只需在网页上填写注册表格即可成为系统中的用户。当然,我可以简单地创建一个包含用户名和密码哈希的数据库表,并手动实现所有功能,但这违背了目的。
因此,我的问题是:
谢谢!
最佳答案
J2EE在这方面不是很好。我已经在应用程序中做到了。
我在应用程序使用的(唯一的)数据库中有一个用户表,并且已经在Web应用程序的META-INF目录中的context.xml文件中声明了一个领域(我使用的是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"/>
数据源与该应用程序其余部分中使用的数据源相同,并在tomcat安装的server.xml中声明(以便我可以指向另一个数据库而无需更改.war文件)。
我已在web.xml文件中使用角色保护了位置,并确保将注册页面和登录页面保留为uprotected:
<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>
我指定了一个部分,其中FORM作为auth方法:
<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>
由于该领域被声明为使用MD5摘要,因此必须将密码的MD5存储在数据库中:
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());
}
}
在登录表单中,只要需要身份验证,tomcat就会显示,我在注册表单中添加了一个链接:
...
<form id="login-form" action="j_security_check" method="post">
<table>
<tbody>
<tr>
<td><label for="username">User name: </label></td>
<td><input type="text" name="j_username" id="username" /></td>
</tr>
<tr>
<td><label for="password">Password: </label></td>
<td><input type="password" name="j_password" id="password" /></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" id="submit" name="submit" value="Login"></td>
</tr>
<tr>
<td> </td>
<td><a href="../reg/create">I'm a new user</a></td>
</tr>
</tbody>
</table>
</form>
...
现在,提交注册表单后,我将用户存储在数据库中,并发送重定向以自动将用户登录:
...
response.sendRedirect(request.getContextPath()
+ "/j_security_check?j_username="
+ URLEncoder.encode(getEmail(), "UTF-8")
+ "&j_password="
+ URLEncoder.encode(password, "UTF-8"));
...
希望这会有所帮助