我在Java EE中遇到了安全问题。我有一个应用程序,应该是一种电子商店。我有三个实体:未映射到数据库的用户类,以及映射到不同表的两个继承类——Client和Administrator:
@MappedSuperclass
@Inheritance(strategy= InheritanceType.TABLE_PER_CLASS)
public class User implements Serializable {...}
@Entity
public class Client extends User {...}
@Entity
public class Administrator extends User {...}
现在我需要为客户端和管理员资源提供安全性。我使用jdbcRealm和标准登录页面的FORM身份验证:
<>之前<form action="j_security_check" method="POST">ltinput type="text" name="j_username"/>ltinput type="password" name="j_password"/>ltinput type="submit" value="Login"/> lt/form>之前但是问题是jdbcRealm只引用一个表。并且不允许在web.xml中设置两个jdbcrealm。那么,如何在不更改数据库结构的情况下为客户机和管理员提供身份验证呢?是否有可能在单个应用程序中使用几个jdbcRealms ?
您可以使用组合域来组合两个JDBC域:
在$CATALINA_BASE/conf/server.xml
<Realm className="org.apache.catalina.realm.CombinedRealm" >
<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://localhost/db?user=dbuser&password=dbpass"
userTable="client"
userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"/>
<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://localhost/db?user=dbuser&password=dbpass"
userTable="administrator"
userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"/>
</Realm>
但是,在这种情况下,最好设置一个数据源并使用DataSourceRealm来访问表。
<Realm className="org.apache.catalina.realm.CombinedRealm" >
<Realm className="org.apache.catalina.realm.DataSourceRealm"
dataSourceName="jdbc/authority"
userTable="clients" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"/>
<Realm className="org.apache.catalina.realm.DataSourceRealm"
dataSourceName="jdbc/authority"
userTable="administrators" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"/>
</Realm>
这样,您只需要在数据源中设置连接字符串,而不必在域中设置重复的连接字符串。
注意:就我个人而言,我怀疑拥有不同的ADMINISTRATOR和USER表是否是个好主意,因为如果您的用户名既是客户端又是管理员会发生什么,所以您必须确保不会发生这种情况,如果只对一个表进行约束,这要容易得多。