我有一个问题可以在我的应用程序中实现安全性...我具有自定义身份验证,并使用@preatuthorize来处理我的用户授权。这很好。现在,我想为每个用户实现访问控件,这意味着当两个用户" admin"one_answers" john"可以调用方法
时,这意味着在我的应用程序中。@RequestMapping(value = "/load/{id}", method = RequestMethod.GET)
@ResponseBody
public StudentYearViewModel load(@PathVariable long id) {
return ModelMapper.map(iStudentService.loadByEntityId(id), StudentViewModel.class);
}
'admin'可以在所有学生实例中使用此方法,但是'John'只能看到他的同学!所有用户都可以调用此方法(@preatuthorize不合适),但是他们的访问权限有限?现在有一般的方式吗?
ACL是最好的方法吗?(有最好的例子?)
HDIV框架可以帮助我解决我的问题?
什么是最好的解决方案?
您想查看@PostFilter
和@PreFilter
。它们的工作方式几乎像@PreAuthorize
,但可以从列表中删除结果。您还希望为您的用户分配不同的角色,假设您还没有这样做。
全局规则,例如管理员能够看到所有内容,您可以通过编写PermissionEvaluator
的具体实现来实现。然后,将其添加到MethodSecurityExpressionHandler
一个简单示例的时间。
此代码写在文本编辑器中。它可能不会编译,并且仅在这里显示所需的步骤
非常简单的PermissionEvaluator
public class MyPermissionEvaluator implements PermissionEvaluator {
private static final SimpleGrantedAuthority AUTHORITY_ADMIN = new SimpleGrantedAuthority('admin');
public boolean hasPermission(final Authentication authentication, final Object classId, final Object permission) {
boolean permissionGranted = false;
// admin can do anything
if (authentication.getAuthorities().contains(AUTHORITY_ADMIN)) {
permissionGranted = true;
} else {
// Check if the logged in user is in the same class
}
return permissionGranted;
}
@Override
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
Object permission) {
return false;
}
}
然后配置方法安全
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Bean
public MethodSecurityExpressionHandler methodSecurityExpressionHandler(final PermissionEvaluator permissionEvaluator){
DefaultMethodSecurityExpressionHandler securityExpressionHandler = new DefaultMethodSecurityExpressionHandler();
securityExpressionHandler.setPermissionEvaluator(permissionEvaluator);
return securityExpressionHandler;
}
@Bean
public PermissionEvaluator permissionEvaluator() {
return new MyPermissionEvaluator();
}
}
现在我们可以在方法上使用过滤器
@PostFilter("hasPermission(filterObject.getClassId(), 'READ')")
@Override
public List<Student> getAll() {
return querySomeStudents();
}
@PostFilter
ACL中的hasPermission
将在MyPermissionEvaluator
中调用hasPermission
。filterObject
指列表中的各个项目。无论您在何处返回false,它都会从列表中删除项目。
分别为admin和john cole_admin分配两个不同的角色,cole_user。然后检查控制器内部的角色,并调用相应的服务方法以根据其角色返回数据。
@RequestMapping(value = "/load/{id}", method = RequestMethod.GET)
@ResponseBody
public StudentYearViewModel load(HttpServletRequest request, Authentication authentication, @PathVariable long id) {
if (request.isUserInRole("ROLE_ADMIN")) {
return ModelMapper.map(iStudentService.loadByEntityId(id), StudentViewModel.class); //return all records
} if (request.isUserInRole("ROLE_USER")) {
String username = authentication.getName(); //get logged in user i.e. john
return ModelMapper.map(iStudentService.loadByEntityId(id, username), StudentViewModel.class); //return records by username
}
}