Jakarta ee 当我只有很少的用户表时,如何通过jdbcRealm在web应用程序中提供安全性

Jakarta ee 当我只有很少的用户表时,如何通过jdbcRealm在web应用程序中提供安全性,jakarta-ee,security,jdbcrealm,Jakarta Ee,Security,Jdbcrealm,我在JavaEE中遇到了安全问题。 我有一个应用程序,应该是一种电子商店。我有三个实体: 未映射到数据库的用户类,以及映射到不同表的两个继承类-客户端和管理员: @MappedSuperclass @Inheritance(strategy= InheritanceType.TABLE_PER_CLASS) public class User implements Serializable {...} @Entity public class Client extends User {...}

我在JavaEE中遇到了安全问题。 我有一个应用程序,应该是一种电子商店。我有三个实体: 未映射到数据库的用户类,以及映射到不同表的两个继承类-客户端和管理员:

@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和standart登录页面使用表单身份验证:

<form action="j_security_check" method="POST"> <input type="text" name="j_username"/> <input type="password" name="j_password"/> <input type="submit" value="Login"/> </form> <form action=“j\u security\u check”method=“POST”> <input type=“text”name=“j\u用户名”/> <input type=“password”name=“j_password”/> <input type=“submit”value=“Login”/> </form>
但问题是jdbcRealm只引用一个表。而且不允许在web.xml中设置两个JDBCrealm。那么,如何在不更改数据库结构的情况下为客户端和管理员提供身份验证呢?可以在单个应用程序中使用几个JDBC领域吗?

您可以使用一个组合领域来组合两个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&amp;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&amp;password=dbpass"
           userTable="administrator" 
           userNameCol="user_name" userCredCol="user_pass"
           userRoleTable="user_roles" roleNameCol="role_name"/>
</Realm>

但是,在这种情况下,最好设置一个数据源并使用DataSourceAlm来访问表

<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>

这样,您只需要在数据源中设置连接字符串,而不需要在领域中进行复制


注意:就我个人而言,我会质疑是否有一个不同的管理员和用户表是一个好主意,因为如果您有一个既是客户机又是管理员的用户名,那么会发生什么情况,因此您必须确保不会发生这种情况,而仅对一个表进行约束会容易得多。

非常感谢您的帮助!我已经在这些不同的表中遇到了另一个问题,所以最好将所有数据放在一个表中。但我对JavaEE还不熟悉,这个项目更多的是用于培训。无论如何,如果我把管理员和客户机数据放在同一个表中,它会有很多空字段,因此会导致数据库的扩展。我说的对吗?如果您可以对表结构进行更改,那么使用InheritanceType.JOINED和@MappedSuperclass来拥有一个用户表(带有公共列,将在JDBCRealm中使用)以及一个管理员和客户机表可能值得一看。这些将由一个id列连接。见(第2.2.4.3节和第2.2.4.4节)