As stated before you may implement your own way of providing access rules (i.e. via JDBC). You have to implement the interface net.sf.jpasecurity.security.rules.AccessRulesProvider and specify the property net.sf.jpasecurity.security.rules.provider in your persistence.xml with the classname of your implementation of the interface net.sf.jpasecurity.security.rules.AccessRulesProvider. Take a look at its javadoc documentation for further reference.

Accessing persistence properties

Your custom access rules provider may need additional configuration parameters. You can define them via the persistence properties in your persistence.xml. All you have to do, is to implement the interface net.sf.jpasecurity.persistence.PersistenceInformationReceiver. Then you will have the persistence properties injected when your persistence provider is initialized.

Implementing an Access Rules Provider

When you take a look at the methods of net.sf.jpasecurity.rules.AccessRulesProvider, you may notice that you need to create objects of type net.sf.jpasecurity.security.AccessRule. This objects may be created using a net.sf.jpasecurity.jpql.parser.JpqlParser in conjunction with an net.sf.jpasecurity.security.rules.AccessRulesCompiler, but you may subclass net.sf.jpasecurity.security.rules.AbstractAccessRulesProvider to inherit this functionality. Then you have to override initializeAccessRules and call compileRules from within.

Example

Implementing a JDBC access rules provider">

The following code shows how to implement an access rules provider that reads its access rules from a database. You may specify the needed parameters in your persistence.xml.

        
public class JdbcAccessRulesProvider extends AbstractAccessRulesProvider {

  public static final String ACCESS_RULES_JDBC_URL_PROPERTY = "net.sf.jpasecurity.security.rules.jdbc.url";
  public static final String ACCESS_RULES_JDBC_USERNAME_PROPERTY = "net.sf.jpasecurity.security.rules.jdbc.username";
  public static final String ACCESS_RULES_JDBC_PASSWORD_PROPERTY = "net.sf.jpasecurity.security.rules.jdbc.password";  
  public static final String ACCESS_RULES_JDBC_TABLE_PROPERTY = "net.sf.jpasecurity.security.rules.jdbc.table";
  public static final String ACCESS_RULES_JDBC_COLUMN_PROPERTY = "net.sf.jpasecurity.security.rules.jdbc.column";

  protected void initializeAccessRules() {
    Map<String, String> properties = getPersistenceProperties();
    String url = getPersistenceProperty(ACCESS_RULES_JDBC_URL_PROPERTY);
    String username = getPersistenceProperty(ACCESS_RULES_JDBC_USERNAME_PROPERTY);
    String password = getPersistenceProperty(ACCESS_RULES_JDBC_PASSWORD_PROPERTY);
    String table = getPersistenceProperty(ACCESS_RULES_JDBC_TABLE_PROPERTY);
    String column = getPersistenceProperty(ACCESS_RULES_JDBC_COLUMN_PROPERTY);
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;
    Collection<String> accessRules = new HashSet<String>();
    try {
      connection = DriverManager.getConnection(url, username, password);
      statement = connection.createStatement();
      resultSet = statement.executeQuery("SELECT " + column + " FROM " + table);
      while (resultSet.next()) {
        accessRules.add(resultSet.getString(1));
      }
      compileRules(accessRules);
    } catch (SQLException e) {
      throw new PersistenceException("Error reading access rules", e);
    } finally {
      close(resultSet);
      close(statement);
      close(connection);
    }
  }
  
  private String getPersistenceProperty(String propertyName) {
    String propertyValue = getPersistenceProperties().get(propertyName);
    if (propertyValue == null) {
      throw new PersistenceException("Error reading acces rules, property " + propertyName + " must be set");
    }
    return propertyValue;
  }
  
  private void close(ResultSet resultSet) {
    if (resultSet != null) {
      try {
        resultSet.close();
      } catch (SQLException e) {
        //ignore
      }
    }
  }

  private void close(Statement statement) {
    if (statement != null) {
      try {
        statement.close();
      } catch (SQLException e) {
        //ignore
      }
    }
  }

  private void close(Connection connection) {
    if (connection != null) {
      try {
        connection.close();
      } catch (SQLException e) {
        //ignore
      }
    }
  }
}
                  
      

In your persistence.xml you can specify the needed parameters like following.

        
<persistence ...>

  <persistence-unit name="..." ...>

    ...

    <properties>
      <property name="net.sf.jpasecurity.security.rules.jdbc.url" value="jdbc:your.db.url" />
      <property name="net.sf.jpasecurity.security.rules.jdbc.username" value="your_username" />
      <property name="net.sf.jpasecurity.security.rules.jdbc.password" value="your_password" />
      <property name="net.sf.jpasecurity.security.rules.jdbc.table" value="your_table_with_access_rules" />
      <property name="net.sf.jpasecurity.security.rules.jdbc.column" value="your_column_containing_the_access_rules" />
    </properties>

  </persistence-unit>
</persistence>