【转】一个关于用AOP实现权限控制的问题,不知道大家怎么想?
遇到一个权限验证的问题。就是说,对于任何一个操作,需要判断这个人对于这份资源是否有权进行这项操作。这是一个典型的AOP场景,但是试图横切的时候遇到了困难。
“权限验证”这个aspect需要三项信息:操作者(userId)、被操作对象(departmentId、resourceFamilyId……)、操作(组件名+方法名)。“操作”的信息是可以在aspect中直接获得的;“操作者”的信息无法直接获得,但也可以在web层先用filter做一次拦截,将 userId放进ThreadLocal,然后在aspect中取出。最麻烦的就是“被操作对象”的信息。譬如“删除部门”操作,被操作对象就是部门的 ID;“修改portlet”操作,被操作对象就是portlet的注册ID。对于各种各样不同的service方法,如何在aspect中拦截出被操作对象的信息?
一种办法是约定将被操作对象ID放在参数列表的特定位置,譬如每个service方法的第一个参数就是被操作对象的ID,然后aspect始终到这个位置去拿到这个ID,判断是否有权限进行此操作。但这就等于给service方法加上了另一层约束,而且这种约束还无法在类型系统中体现出来,一则容易犯错(譬如忘了这个约定,把ID放到第二个参数了),二则多个aspect的约定还有可能冲突或者混淆。
有没有办法清晰地描述这种“aspect对组件的约束”?或者还有没有更好的办法?要不然,还真是不太敢多用AOP。