本文转载自微信公众号《JAVA日知录》,作者单音。转载本文请联系JAVA日知录公众号。访问控制,或访问控制,广泛应用于各种系统中。抽象地讲,一定的主体需要对一定的客体实施一定的操作,而系统对这种操作的限制就是权限控制。在网络中,为了保护网络资源的安全,一般通过路由设备或防火墙建立基于IP和端口的访问控制。在操作系统中,对文件的访问也受到访问控制。例如,在Linux系统中,可以对文件进行的操作分为三种:“读”、“写”、“执行”。这三个操作同时对应三个主体:文件所有者和文件所有者所属的用户组、其他用户,主体、客体、操作的对应关系构成了一个访问控制列表。在Web应用中,根据不同的访问对象,可以通过解决以下目标问题来实现通用的访问控制:他是谁?他只能访问已经授权给他的接口!他不能查看别人的数据!下面我们以前后端分离项目为例,说明如何解决这些目标问题:他是谁?在前后端分离的项目中,后端服务会在前端用户登录后给前端用户颁发一个token,比如大家熟知的JWT(JSONWebToken),然后前端每次-end请求后端接口,会带上这个token。由于JWT中会包含用户信息,此时我们要做的就是验证这个token对应的用户是否是系统的合法用户。他只能访问已经授权给他的接口!仅仅知道他是系统的合法用户是不够的。Web应用还必须保证当前用户只能访问他有权限的接口。比如有一个查询工资的接口,在业务中只允许部门领导角色访问。如果系统不管,张三知道工资查询接口,然后用自己的token调用这个接口,就可以知道所有员工的工资了。我们称这种问题为“未授权访问”。一种广泛使用的处理这个问题的方法是“基于角色的访问控制(RBAC:Role-BasedAccessControl)”,也称为“垂直权限管理”。RBAC会预先在系统中定义不同的角色,不同的角色有不同的权限。角色实际上是权限的集合。系统的所有用户都会被赋予不同的角色,一个用户可能有多个角色。当用户使用token请求后端服务时,我们要通过token查询当前用户的角色,然后根据角色查询用户的所有权限。权限框架SpringSecurity和Shiro都很好地支持RBAC控制。他查不到别人的资料!张三和李四都是部门领导,都可以查员工的工资。但他们都只能查看自己部门员工的工资。张三知道接口调用规则,所以他可以通过修改调用参数获取到李四所在部门员工的工资。当然,这种情况是不允许的。在RBAC模型下,系统只验证用户A是否属于角色RoleX,而没有判断用户A是否可以访问只属于用户B的数据DataB,所以会出现越权访问。我们称这种问题为“横向权限管理问题”。目前,数据级权限管理没有通用的解决方案,通常是针对具体问题具体解决。简单的方法是在接口请求中加入秘钥,通过接口参数+当前系统登录人加密后发送给后台服务,后台收到请求后对加密内容进行解密,并根据约定的规则对用户信息进行分析,并发送给后台服务。与登录用户匹配,如果匹配则正常访问,如果不匹配则拒绝访问。
