Spring Security实现基于RBAC的权限表达式动态访问控制的操作方法

下面是Spring Security实现基于RBAC的权限表达式动态访问控制的操作方法的完整攻略:

步骤一:初始化Spring Security

使用Spring Security提供的依赖,在pom.xml文件中配置以下依赖项:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>5.2.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>5.2.2.RELEASE</version>
</dependency>

完成后,需要在Spring应用程序的配置文件中启用Spring Security:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
     @Override
     protected void configure(HttpSecurity http) throws Exception {
         http.authorizeRequests()
             .antMatchers("/admin/**").hasRole("ADMIN")
             .antMatchers("/user/**").hasRole("USER")
             .and()
             .formLogin();
     }

     @Override
     public void configure(WebSecurity web) throws Exception {
         web.ignoring()
             .antMatchers("/resources/**");
     }

     @Override
     public void configure(AuthenticationManagerBuilder auth) throws Exception {
         auth.inMemoryAuthentication()
             .withUser("admin").password("{noop}admin").roles("ADMIN")
             .and()
             .withUser("user").password("{noop}user").roles("USER");
     }
}

步骤二:配置基于RBAC的权限表达式

在Spring Security中使基于RBAC的权限表达式成为真正动态的,可以使用Spring EL,这样就可以对当前用户的角色进行动态处理。

首先,需要定义一个角色和对应的权限,可以将这些数据存储到数据库中:

CREATE TABLE Role (
  id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
  name TEXT NOT NULL,
  description TEXT DEFAULT NULL
);

CREATE TABLE Permission (
  id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
  name TEXT NOT NULL,
  description TEXT DEFAULT NULL
);

CREATE TABLE Role_Permission (
  role_id INTEGER NOT NULL,
  permission_id INTEGER NOT NULL,
  PRIMARY KEY (role_id, permission_id),
  CONSTRAINT ROLE_PERM_ROLE_FK FOREIGN KEY (role_id)
    REFERENCES Role (id),
  CONSTRAINT ROLE_PERM_PERM_FK FOREIGN KEY (permission_id)
    REFERENCES Permission (id)
);

INSERT INTO Role (name, description) VALUES ('admin', '管理者');
INSERT INTO Role (name, description) VALUES ('user', '普通用户');

INSERT INTO Permission (name, description) VALUES ('create', '创建');
INSERT INTO Permission (name, description) VALUES ('read', '读取');
INSERT INTO Permission (name, description) VALUES ('update', '更新');
INSERT INTO Permission (name, description) VALUES ('delete', '删除');

INSERT INTO Role_Permission (role_id, permission_id) VALUES (1, 1);
INSERT INTO Role_Permission (role_id, permission_id) VALUES (1, 2);
INSERT INTO Role_Permission (role_id, permission_id) VALUES (1, 3);
INSERT INTO Role_Permission (role_id, permission_id) VALUES (1, 4);
INSERT INTO Role_Permission (role_id, permission_id) VALUES (2, 2);

接下来,需要在Spring Security的配置文件中添加以下代码来读取数据库中的角色和权限信息:

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AppConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private DataSource dataSource;

    @Bean
    public RoleHierarchyImpl roleHierarchy() {
        RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
        roleHierarchy.setHierarchy("ROLE_admin > ROLE_user");
        return roleHierarchy;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/*").access("hasRole('admin') or hasRole('user')")
            .antMatchers("/admin/**").access("hasRole('admin')").and().formLogin();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        JdbcUserDetailsManager userDetailsService = new JdbcUserDetailsManager();
        userDetailsService.setDataSource(dataSource);
        userDetailsService.setSqlUsersByUsernameQuery(
                "select username,password,enabled from users where username=?");
        userDetailsService.setSqlRolesByUsernameQuery(
                "select u.username, r.name from users u, user_roles ur, role r where u.id = ur.user_id and ur.role_id = r.id and u.username=?");
        auth.userDetailsService(userDetailsService);
    }
}

步骤三:添加角色和权限

在定义了角色和权限之后,需要为用户分配角色和权限:

ALTER TABLE users
ADD COLUMN enabled BOOLEAN DEFAULT TRUE NOT NULL;

CREATE TABLE user_roles (
  user_id INTEGER NOT NULL,
  role_id INTEGER NOT NULL,
  PRIMARY KEY (user_id, role_id),
  CONSTRAINT users_roles_users_FK FOREIGN KEY (user_id)
    REFERENCES users (id),
  CONSTRAINT users_roles_roles_FK FOREIGN KEY (role_id)
    REFERENCES Role (id)
);

INSERT INTO users VALUES (DEFAULT, 'admin', 'admin@example.com', 'password', TRUE);
INSERT INTO users VALUES (DEFAULT, 'user', 'user@example.com', 'password', TRUE);

INSERT INTO user_roles VALUES (1, 1);
INSERT INTO user_roles VALUES (2, 2);

示例一:使用Spring EL动态控制页面访问权限

首先,创建一个基本的Spring MVC控制器:

@Controller
public class HomeController {

    @GetMapping("/")
    @PreAuthorize("hasRole('USER')")
    public String index(Model model) {
        return "index";
    }

    @GetMapping("/admin")
    @PreAuthorize("hasRole('ADMIN')")
    public String admin(Model model) {
        return "admin";
    }
}

在访问/index时,只有拥有USER角色的用户可以查看,而在访问/admin时,只有拥有ADMIN角色的用户才能查看。

示例二:使用代码动态控制页面访问权限

在使用代码动态控制页面访问权限时,可以在Spring Security的配置文件中添加以下代码:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/user/**").access("hasRole('USER') or hasRole('ADMIN')")
            .antMatchers("/admin/**").access("hasRole('ADMIN')")
        .and()
            .formLogin();
    }
}

在访问/user/时,只有拥有USER或者ADMIN角色的用户可以查看,而在访问/admin/时,只有拥有ADMIN角色的用户才能查看。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security实现基于RBAC的权限表达式动态访问控制的操作方法 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Java实现JS中的escape和UNescape代码分享

    实现JS中的escape和unescape,其本质上是Java中的URL编码和解码,Java中提供了相关的API可以实现这一功能。下面是在Java中实现JS中的escape和unescape的完整攻略: 1. URL编码 URL编码,也称百分号编码,是用于在URL中表示非ASCII字符的方法,它的基本原理是将字符转换成它的ASCII码,并在前面加上%。 在J…

    Java 2023年5月23日
    00
  • 二十分钟 教你Ruby快速入门 图文教程第1/4页

    下面进行对“二十分钟 教你Ruby快速入门 图文教程第1/4页”的完整攻略的详细讲解。 攻略内容 1. 环境搭建 首先,你需要在自己的电脑中安装 Ruby 程序,可以到 Ruby官网 下载相应的安装包,根据自己电脑的操作系统选择适合自己的安装程序。 安装完成后,可通过命令行工具输入 ruby -v 进行检查,若返回了相应版本号则说明安装成功。 2. Hell…

    Java 2023年5月26日
    00
  • 浅谈JSP与Servlet传值及对比(总结)

    浅谈JSP与Servlet传值及对比(总结)是一篇比较详细介绍 JSP 和 Servlet 之间数据传递的文章。在该文章中,作者讲述了JSP和Servlet传值的几种方式以及它们在不同情况下的使用情况。 1. JSP与Servlet JSP和Servlet是相互联系的,JSP可以添加Java代码,Servlet可以生成HTML代码。JSP和Servlet重点…

    Java 2023年6月15日
    00
  • Java技巧函数方法实现二维数组遍历

    下面我来详细讲解“Java技巧函数方法实现二维数组遍历”的完整攻略,这里将以Java代码实现为例。 一、背景概述 在Java开发中,经常需要对二维数组进行遍历操作,遍历完成后可以通过对数组元素的操作达到目的。在这里,我将讲解如何使用函数方法实现二维数组遍历的方法。 二、函数方法实现二维数组遍历 函数方法是将实现某一特定功能的代码块封装成单独的代码单元,可以在…

    Java 2023年5月26日
    00
  • Java二维数组讲解

    Java二维数组讲解 什么是二维数组? Java中的二维数组是指由多个一维数组组成的数组。可以将其理解为一个表格,具有行和列两个维度。在Java中,二维数组是一种引用类型,需要通过new操作符进行初始化。 如何声明和初始化二维数组? 在Java中,可以使用如下方式声明和初始化二维数组: // 声明一个2 x 3的整型数组 int[][] arr = new …

    Java 2023年5月26日
    00
  • Hibernate识别数据库特有字段实例详解

    让我为您详细讲解“Hibernate识别数据库特有字段实例详解”的完整攻略。 在使用Hibernate进行开发时,有些时候我们需要识别一些数据库特有的字段,如MySQL中的ENUM类型、PostgreSQL中的ARRAY类型等。这些字段并不在Hibernate的基础数据类型中,所以我们需要进行额外配置。 下面是如何识别MySQL中的ENUM类型的示例: 首先…

    Java 2023年5月20日
    00
  • MySQL筑基篇之增删改查操作详解

    MySQL筑基篇之增删改查操作详解 一、准备工作 在开始进行MySQL的增删改查操作前,需要先做一些准备工作。首先需要安装MySQL数据库,可以通过官方网站下载,并安装在本地机器上。安装完成后,需要登录MySQL,创建数据库并创建数据表。 1.1 登录MySQL 在命令行或终端中输入以下代码,登录MySQL: mysql -u root -p 其中,root…

    Java 2023年5月26日
    00
  • 新欢乐时光代码分析

    下面为您详细讲解“新欢乐时光代码分析”的完整攻略。 新欢乐时光代码分析完整攻略 什么是新欢乐时光 新欢乐时光是一款在线编程学习网站,提供基于计算机科学和编程方面的在线培训课程。它的使命是通过免费、灵活、高质量的教育资源,为全球的学生和教育者带来变革性的教育体验。 在线代码分析工具使用教程 新欢乐时光提供了一款在线代码分析工具,允许用户输入自己的代码,然后自动…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部