在大多数情况下,您希望用户只能访问用户自己创建的数据库中的实体.例如,如果存在由User1创建的日历,则只有User1应该能够在数据库中读取,更新或删除此特定日历及其内容.这不是一般的授权 - 在我的项目中,已经有一个基于角色的授权组件,它检查用户是否属于"日历编辑器"角色,但它不检查是否允许特定用户访问具体日历.
因此,最终必须在当前请求的用户标识和表示所请求日历的所有者的用户标识之间进行比较.但我想知道在哪里这样做.我的想法:
我可以在DAO级别上完成.但是,每个DAO方法都需要一个表示user-id的附加参数,这使得这些方法更加冗长并降低了可重用性.
例如
def findCalById(id: Int): Future[Option[Calendar]]
变
def findCalById(id: Int, ownerId: Int ): Future[Option[Calendar]]
优点是权限检查基本上在查询级别完成,这意味着如果用户无法访问日历,则不会从数据库返回日历.但话又说回来:如果在某些情况下没有返回日历,那么如何区分不存在的日历和当前用户无法访问的现有日历?两种不同的情景,产生相同的结果.
另一种选择可能是将DAO保持在此范围之外,并在服务层或类似的东西中进行检查.这意味着在DAO返回请求的日历之后执行检查.这种方法听起来比另一种方法更灵活,但它也意味着如果用户无法访问所请求的日历,则所请求的日历仍然消耗带宽和内存,因为在任何一种情况下都从数据库获取.
也许我还没有考虑其他选项.有没有最佳做法?
顺便说一下:我的网络应用程序中没有日历,这只是一个说明问题的例子.
database model-view-controller scala web-applications playframework
我有三个班级(这个数字将来可能会增长):
public inteface Base{ }
public class Select implements Base{ }
public class Ast implements Base{ }
public class Gt implements Base{ }
Run Code Online (Sandbox Code Playgroud)
我也需要List上课
BaseList extends ArrayList<Base>{
public boolean add(Base b){
throw new UnsupportedOperationException("You should use add%ConcereteBaseType% method instead");
}
public boolean add(Select s){ }
public boolean add(Ast a){ }
public boolean add(Gt g){ }
}
Run Code Online (Sandbox Code Playgroud)
我这样做的原因是我不希望任何人通过指针添加元素Base.在我的具体情况下,这将是不安全的.
但缺点是只能在运行时才能发现它.
我还需要迭代列表.
做这些事情是一种好习惯吗?