views:

79

answers:

2

I have a data access API that say looks something like:

public interface IDataAccess {
   void save(Doc doc);
   Doc retrieve(DocId id);
   void delete(Doc doc);
}

I need to restrict the operations a user can perform on a document based upon their permissions. The idea I had to do this was to create another API that mirrored the data access operations but also took in the user credential to validate them before performing the operations:

public interface IAuthDataAccess {

   // User is a previously authenticated user
   void save(Doc doc, User user) throws SecurityException;
   ...
}

public class AuthDataAccess implements IAuthDataAccess {
   IAuth auth = ...
   IDataAccess dataAccess = ...

   public void save(Doc doc, User user) throws SecurityException {
      if (auth.saveAllowed(doc, user)) {
         dataAccess.save(doc);
      } else {
         throw new SecurityException("access denied");
      }
   }
   ...
}

The IAuthDataAccess API would be used to access the data layer. Is there a better way to tie the authorization/authentication together with the data access layer?

+1  A: 

A better design would be incorporating aspect programming on your code. This can be achieved by using Annotation.

Example:

public interface IAuthDataAccess {

   @Restricted
   void save(Doc doc, User user) throws SecurityException;
   ...
}

Obviously, you have to create other code to do the real check.

nanda
+2  A: 

Your approach makes the interface pointless, as you're not actually implementing the methods - all it does is confuse. What about having the authorized accessor actually implement the interface? e.g. something like -

public class AuthorizedDataAccessor implements IAuthDataAccess { 

 public AuthorizedDataAccessor(User user){ .. }

  void save(Doc doc) { ... save if authorized ...}
}

so you could write

IAuthDataAccess a=new AuthorizedDataAccessor(user);
 a.save(doc);
Steve B.