春季安全中的最佳实现"访问"用户



我有一个问题可以在我的应用程序中实现安全性...我具有自定义身份验证,并使用@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中调用hasPermissionfilterObject指列表中的各个项目。无论您在何处返回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
    }
}

最新更新