How can I provide security in a web-application by jdbcRealm when I have few user tables
I have a problem with security in Java EE. I have an application that supposed to be a kind of e-shop. I have three entities: User class that is not mapped into database, and two inherited classes - Client and Administrator, that are mapped into different tables:
@MappedSuperclass
@Inheritance(strategy= InheritanceType.TABLE_PER_CLASS)
public class User implements Serializable {...}
@Entity
public class Client extends User {...}
@Entity
public class Administrator extends User {...}
Now I need to provide security for Client and Administrator resources. I use FORM authentication with jdbcRealm and standart login page:
<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>
But the problem is that jdbcRealm refers only to one table. And it's not allowed to set two jdbcRealms in web.xml. So how can I provide authentication for both Client and Administrator without chang开发者_运维技巧ing database structure? Is it possible to use few jdbcRealms in a single application?
You can use a combined realm to combine two JDBC realms:
In the $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>
However, in this instance it may be better to set up a datasource and use the DataSourceRealm to access the tables.
<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>
That way you only need to set up connection string in the datasource rather than having the duplication in the realm.
N.B. Personally, I would question whether it is a good idea to have a different ADMINISTRATOR and USER table, as what would happen if you've got a username that is both a client and an administrator, so you'd have to ensure that this doesn't happen, which is much easier by having a constraint on just one table.
精彩评论