How can I provide security in a web-application by jdbcRealm when I have few user tables

StackOverflow https://stackoverflow.com/questions/7040788

  •  24-12-2020
  •  | 
  •  

Question

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 changing database structure? Is it possible to use few jdbcRealms in a single application?

Était-ce utile?

La solution

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

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top