Security——角色和权限的区别
首先,看一下Security中一些可选的表达式
permitAll 永远返回true
denyAll 永远返回false
anonymous 当前用户是anonymous时返回true
rememberMe 当前用户是rememberMe用户时返回true
authenticated 当前用户不是anonymous时返回true
fullAuthenticated 当前用户既不是anonymous也不是rememberMe用户时返回true
hasRole(role) 用户拥有指定的角色权限时返回true
hasAnyRole([role1,role2]) 用户拥有任意一个指定的角色权限时返回true
hasAuthority(authority) 用户拥有指定的权限时返回true
hasAnyAuthority([authority1,authority2]) 用户拥有任意一个指定的权限时返回true
hasIpAddress('192.168.1.0') 请求发送的Ip匹配时返回true
实际使用Security过程中,明显的感觉到,角色和权限的概念似乎非常模糊;
调用授权的接口时,把角色传递进去也是对的,查看底层代码,就会发现,角色和权限最终调用的代码是一样的。
从源码上看,在底层代码中,Security 并没有严格区分角色和权限。
如果没有角色和权限的区别,只需要hasRole()函数就够了, hasAuthority()是做什么用的?
二者的区别
区别就是,hasRole()的权限名称需要用 "ROLE_" 开头,而hasAuthority()不需要,而且,这就是全部的区别。
这样设计的意义
判断 “用户是不是管理员”和判断 “是否拥有管理员权限”,代码逻辑上是完全一致的,就是判断授权码是否一致,因此,不需要设计两套代码。
只考虑权限实现方式,我们可以将角色视为权限的一种,但是,在实际业务中,这可能让逻辑变得不好理解,将二者进行区分,方便开发者从不同的维度去设计。
因此,尽管底层调用的是同一套代码,但是仍然分离出了两套接口。
Spring Security3 到 Spring Security4 的迁移文档:
http://docs.spring.io/spring-security/site/migrate/current/3-to-4/html5/migrate-3-to-4-jc.html#m3to4-role-prefixing
S.O. (Stack Overflow)网站对这个问题的描述:
https://stackoverflow.com/questions/19525380/difference-between-role-and-grantedauthority-in-spring-security
Think of a GrantedAuthority as being a "permission" or a "right". Those "permissions" are (normally) expressed as strings (with the getAuthority() method). Those strings let you identify the permissions and let your voters decide if they grant access to something.
You can grant different GrantedAuthoritys (permissions) to users by putting them into the security context. You normally do that by implementing your own UserDetailsService that returns a UserDetails implementation that returns the needed GrantedAuthorities.
Roles (as they are used in many examples) are just "permissions" with a naming convention that says that a role is a GrantedAuthority that starts with the prefix ROLE_. There's nothing more. A role is just a GrantedAuthority - a "permission" - a "right". You see a lot of places in spring security where the role with its ROLE_ prefix is handled specially as e.g. in the RoleVoter, where the ROLE_ prefix is used as a default. This allows you to provide the role names withtout the ROLE_ prefix. Prior to Spring security 4, this special handling of "roles" has not been followed very consistently and authorities and roles were often treated the same (as you e.g. can see in the implementation of the hasAuthority() method in SecurityExpressionRoot - which simply calls hasRole()). With Spring Security 4, the treatment of roles is more consistent and code that deals with "roles" (like the RoleVoter, the hasRole expression etc.) always adds the ROLE_ prefix for you. So hasAuthority('ROLE_ADMIN') means the the same as hasRole('ADMIN') because the ROLE_ prefix gets added automatically. See the spring security 3 to 4 migration guide for futher information.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· Blazor Hybrid适配到HarmonyOS系统
· 万字调研——AI生成内容检测
· 解决跨域问题的这6种方案,真香!
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库