Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
最佳实施';访问';spring安全中的用户_Spring_Spring Security_Acl_Hdiv - Fatal编程技术网

最佳实施';访问';spring安全中的用户

最佳实施';访问';spring安全中的用户,spring,spring-security,acl,hdiv,Spring,Spring Security,Acl,Hdiv,我在应用程序中实现安全性时遇到问题。。。 我有自定义身份验证,并使用@PreAuthorize处理我的用户授权。这个很好用。现在我想为每个用户实现访问控制,这意味着在我的应用程序中,当两个用户“Admin”和“John”可以调用该方法时 @RequestMapping(value = "/load/{id}", method = RequestMethod.GET) @ResponseBody public StudentYearViewModel load(@PathVariable long

我在应用程序中实现安全性时遇到问题。。。 我有自定义身份验证,并使用@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不适用),但他们的访问权限有限。如何操作?? 现在有什么办法

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

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


最好的解决方案是什么?

分别为Admin和John ROLE\u Admin、ROLE\u 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
    }
}

您要查看
@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(“hasPermission(filterObject.getClassId(),'READ'))
@凌驾
公共列表getAll(){
返回querySomeStudents();
}

@PostFilter
ACL中的
hasPermission
将调用
MyPermissionEvaluator中的
hasPermission
<代码>过滤器对象
指列表中的单个项目。无论您的代码返回false,它都将从列表中删除该项。

感谢您的关注!我应该创造很多角色。。。。为了所有的学生!!这是最好的解决方案吗!!????谢谢你的解决方案好多了,但我有个问题。“filterObject.getClassId()”如何工作???这个表演好吗?这是获得所有列表的最佳方式,而不是删除某个列表吗??我想如果我用DB写这个过滤器是不好的???
filterObject
是由Spring使用内省获得的。绩效是一个非常相对的术语。我在很多地方使用它,没有任何性能问题。我的感觉是编写最干净、最容易维护的代码,并在出现性能问题时解决它们。从性能角度来看,如果您成功地命中了索引,则筛选数据库中的数据会“更好”。对数据库进行过滤还可以减少网络I/O。