Spring安全性中最佳实现'Access'用户

时间:2017-03-01 08:27:45

标签: spring spring-security acl hdiv

我在应用程序中实现安全性时遇到问题... 我有自定义身份验证并使用@PreAuthorize来处理我的用户授权。这很好用。现在我想为每个用户实现访问控制,这意味着在我的应用程序中,两个用户“Admin”和“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'只能看到他的同学! 所有用户都可以调用此方法(@PreAuthorize不适合),但他们的Access是如何限制的? 现在有一般方法吗?

是ACL最佳方式吗?(有最好的例子吗?)

HDIV框架可以帮我解决我的问题吗?

什么是最佳解决方案?

2 个答案:

答案 0 :(得分:1)

分别为Admin和John ROLE_ADMIN,ROLE_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
    }
}

答案 1 :(得分:1)

您想查看@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();
}
hasPermission ACL中的

@PostFilter将在hasPermission中调用MyPermissionEvaluatorfilterObject指的是列表中的各个项目。如果您的代码返回false,它将从列表中删除该项目。