使用SpringSecurity设置角色和权限的注意点

 更新时间:2022年3月12日 22:44  点击:287 作者:张占岭

SpringSecurity设置角色和权限

概念

在UserDetailsService的loadUserByUsername方法里去构建当前登陆的用户时,你可以选择两种授权方法,即角色授权和权限授权,对应使用的代码是hasRole和hasAuthority,而这两种方式在设置时也有不同,下面介绍一下:

  • 角色授权:授权代码需要加ROLE_前缀,controller上使用时不要加前缀
  • 权限授权:设置和使用时,名称保持一至即可

使用mock代码

@Component
public class MyUserDetailService implements UserDetailsService {
  @Autowired
  private PasswordEncoder passwordEncoder;

  @Override
  public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
    User user = new User(name,
        passwordEncoder.encode("123456"),
        AuthorityUtils.commaSeparatedStringToAuthorityList("read,ROLE_USER"));//设置权限和角色
    // 1. commaSeparatedStringToAuthorityList放入角色时需要加前缀ROLE_,而在controller使用时不需要加ROLE_前缀
    // 2. 放入的是权限时,不能加ROLE_前缀,hasAuthority与放入的权限名称对应即可
    return user;
  }
}

上面使用了两种授权方法,大家可以参考。

在controller中为方法添加权限控制

 @GetMapping("/write")
  @PreAuthorize("hasAuthority('write')")
  public String getWrite() {
    return "have a write authority";
  }

  @GetMapping("/read")
  @PreAuthorize("hasAuthority('read')")
  public String readDate() {
    return "have a read authority";
  }

  @GetMapping("/read-or-write")
  @PreAuthorize("hasAnyAuthority('read','write')")
  public String readWriteDate() {
    return "have a read or write authority";
  }

  @GetMapping("/admin-role")
  @PreAuthorize("hasRole('admin')")
  public String readAdmin() {
    return "have a admin role";
  }

  @GetMapping("/user-role")
  @PreAuthorize("hasRole('USER')")
  public String readUser() {
    return "have a user role";
  }

网上很多关于hasRole和hasAuthority的文章,很多都说二者没有区别,但我认为,这是spring设计者的考虑,两种性质完成独立的东西,不存在任何关系,一个是用做角色控制,一个是操作权限的控制,二者也并不矛盾。

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中,似乎并没有严格区分角色和权限,

如果没有角色和权限的区别,只需要hasRole()函数就够了, hasAuthority()是做什么用的?

答:区别就是,hasRole()的权限名称需要用 "ROLE_" 开头,而hasAuthority()不需要,而且,这就是全部的区别。

在通常的系统设计中,我们区分角色和权限,但是,判断 “用户是不是管理员”,和判断 “是否拥有管理员权限”,在代码逻辑上,其实是完全一致的,角色是一种权限的象征,可以看做是权限的一种。因此,不区分角色和权限,本身就是合理的做法。

如果撇开别的问题不谈,只考虑权限的问题,我们可以将角色视为权限的一种,但是,角色是用户的固有属性,在用户管理上还是非常有必要的,在Security4中,处理“角色”(如RoleVoter、hasRole表达式等)的代码总是会添加ROLE_前缀,它更加方便开发者从两个不同的维度去设计权限。

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.

以上为个人经验,希望能给大家一个参考,也希望大家多多支持猪先飞。

原文出处:https://www.cnblogs.com/lori/p/10396302.html

[!--infotagslink--]

相关文章

  • 浅谈关于如何检测iOS14本地网络权限的一些思路

    这篇文章主要介绍了浅谈关于如何检测iOS14本地网络权限的一些思路,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-12-08
  • phpMyadmin创建数据库和设置用户权限图解

    phpmyadmin是一款很不错的WEB对mysql数据库管理软件,如果你想创建数据库与设置用户权限我们必须操作用户的很高的权限,如ROOT权限,下面我来给大家介绍介绍。 先来配...2016-11-25
  • C#判断程序是否是管理员权限运行的方法代码示例

    这篇文章主要介绍了C#判断程序是否是管理员权限运行的方法代码示例,本文直接给出实现代码例子,需要的朋友可以参考下...2020-06-25
  • Java类的访问权限关键字用法说明

    这篇文章主要介绍了Java类的访问权限关键字用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-29
  • Postgres 创建Role并赋予权限的操作

    这篇文章主要介绍了 Postgres 创建Role并赋予权限的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-16
  • Postgresql 数据库权限功能的使用总结

    这篇文章主要介绍了Postgresql 数据库权限功能的使用总结,具有很好的参考价值,对大家有所帮助。一起跟随小编过来看看吧...2021-02-05
  • MySQL验证用户权限的方法

    知识归纳因为MySQL是使用User和Host两个字段来确定用户身份的,这样就带来一个问题,就是一个客户端到底属于哪个host。 如果一个客户端同时匹配几个Host,对用户的确定将按照下面的优先级来排 基本观点越精确的匹配越优先...2015-11-08
  • 数据库写不进去IIS写入权限怎么设置

    后台内容无法更新,如基本设置保存不了,数据库写不进去,很有可能是Everyone权限问题,即Everyone 无权操作文件夹,按照下面的步骤操作即可...2016-01-27
  • mysql免安装没有任何root权限

    这篇文章主要介绍了mysql免安装没有任何root权限的安装与配置教程,本文图文并茂给大家介绍的非常详细,需要的朋友参考下...2017-01-22
  • PHP 获取文件目录权限函数fileperms介绍

    在php中要获取或目录权限我们可使用fileperms函数来获取,fileperms() 函数返回文件或目录的权限,。若成功,则返回文件的访问权限。若失败,则返回 false。 例子 1 ...2016-11-25
  • BlueHost跨站/跨目录权限解决方案

    本文章来给各位朋友介绍关于BlueHost跨站/跨目录权限解决方案,希望本文章对各位能带来帮助。 切换到PHP 5.3 (Single php.ini),点击Save保存,这时候FTP连接到BlueH...2016-10-10
  • 使用root权限运行自己所编译程序的解决方法

    本篇文章介绍了,使用root权限运行自己所编译程序的解决方法。需要的朋友参考下...2020-04-25
  • C# 使用相同权限调用 cmd 传入命令的方法

    本文告诉大家如何使用相同权限调用cmd并且传入命令,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友参考下吧...2020-06-25
  • Springboot+Vue+shiro实现前后端分离、权限控制的示例代码

    这篇文章主要介绍了Springboot+Vue+shiro实现前后端分离、权限控制的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-07-16
  • Windows下Apache 目录权限设置详解

    环境配置情况: apache安装目录:d:www-sapache php目录:d:www-sphp5 mysql目录:d:www-smysql 网站根目录:d:wwwhtdocs 专门为运行Apache运行所使用的用户:apache-u(可不隶属于任...2016-01-28
  • 采用C#代码动态设置文件权限

    在开发中,我们经常会使用IO操作,例如创建,删除文件等操作。在项目中这样的需求也较多,我们也会经常对这些操作进行编码,但是对文件的权限进行设置,这样的操作可能会手动操作,本文介绍一种采用代码动态对文件设置权限的操作。...2020-06-25
  • SpringBoot Shiro 权限注解不起作用的解决方法

    本文主要介绍了SpringBoot Shiro 权限注解不起作用的解决方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-07-29
  • MongoDB数据库用户角色和权限管理详解

    这篇文章主要给大家介绍了关于MongoDB数据库用户角色和权限管理的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-12-08
  • 解析PyCharm Python运行权限问题

    这篇文章主要介绍了PyCharm Python运行权限问题,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...2020-04-30
  • 帝国CMS请查看目录权限是否为0777,文件上传不成功解决办法

      帝国CMS网站后台上传附件提示“请查看目录权限是否为0777,文件上传不成功”,问题原因及解决办法有二:一、目录权限不对,检查d目录及子目录权限是否为0777。二、服务器php.in...2015-12-30