Spring Security 中如何让上级拥有下级的所有权限(案例分析)

yizhihongxing
  1. 什么是Spring Security

Spring Security是一个基于Spring框架提供的安全性解决方案,实现了通用的安全功能,例如身份验证、授权、加密等等。它提供了一组用于Web应用程序中的库和API,以便实现许多常见的安全场景,以及为自定义安全需求提供支持的扩展点。

  1. Spring Security中如何让上级拥有下级的所有权限

在Spring Security中实现让上级拥有下级的所有权限,可以通过以下步骤来实现:

  1. 自定义UserDetailsService并继承框架提供的JdbcDaoImpl
@Component
public class CustomUserDetailsService extends JdbcDaoImpl {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        List<UserDetails> users = loadUsersByUsername(username);

        if (users.size() == 0) {
            throw new UsernameNotFoundException("Username not found");
        }

        CustomUserDetails user = (CustomUserDetails) users.get(0);

        Set<GrantedAuthority> authorities = new HashSet<>();
        authorities.addAll(user.getAuthorities());
        addLowerAuthorities(user, authorities);

        List<GrantedAuthority> authoritiesList = new ArrayList<GrantedAuthority>(authorities);
        user.setAuthorities(authoritiesList);

        if (user.getPassword() == null) {
            throw new UsernameNotFoundException("User password not found");
        }

        return user;
    }

    /**
     * 递归授权
     *
     * @param user        用户实体
     * @param authorities 权限集合
     */
    private void addLowerAuthorities(CustomUserDetails user, Set<GrantedAuthority> authorities) {
        List<LowerAuthority> lowerAuthorities = user.getLowerAuthorities();
        for (LowerAuthority lowerAuthority : lowerAuthorities) {
            authorities.add(new SimpleGrantedAuthority(lowerAuthority.getAuthorityName()));
            addLowerAuthorities(lowerAuthority.getUser(), authorities); // 递归授权
        }
    }
}
  1. 自定义UserDetails实现,并继承User
public class CustomUserDetails extends User {

    private List<LowerAuthority> lowerAuthorities;

    public CustomUserDetails(String username, String password, Collection<? extends GrantedAuthority> authorities) {
        super(username, password, authorities);
    }

    public CustomUserDetails(String username, String password, boolean enabled, boolean accountNonExpired,
                             boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
        super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
    }

    public List<LowerAuthority> getLowerAuthorities() {
        return lowerAuthorities;
    }

    public void setLowerAuthorities(List<LowerAuthority> lowerAuthorities) {
        this.lowerAuthorities = lowerAuthorities;
    }
}
  1. 自定义LowerAuthority实现,用于实现上级和下级之间的关联
public class LowerAuthority {

    private String authorityName;

    private CustomUserDetails user;

    public LowerAuthority(String authorityName, CustomUserDetails user) {
        this.authorityName = authorityName;
        this.user = user;
    }

    public String getAuthorityName() {
        return authorityName;
    }

    public CustomUserDetails getUser() {
        return user;
    }
}
  1. 在WebSecurityConfigurerAdapter中指定UserDetailsService的实现
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService customUserDetailsService;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasRole("USER")
                .and().formLogin().loginPage("/login").defaultSuccessUrl("/")
                .and().logout().logoutUrl("/logout").logoutSuccessUrl("/login").invalidateHttpSession(true)
                .and().csrf().disable();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
  1. 在数据库中存储相应的用户和权限信息

示例1:用户John有权限管理Amy和Adam,Adam有权限管理Jess

插入User表记录

username password enabled
john $2a$10$E1N/BB9fR0U1fw5/S5Dtq.8vslLMBfBMo6/3LX1UT9kPAZjAEewb2 1
amy $2a$10$MrL8/0LwP0TiEE3LHRMbwOQ2I9l.x91DtnrRvJ1o52ckHAESHPFja 1
adam $2a$10$z2JAOzkddZTYOuNglmTuoeHeIKFEOhAQ8XZEDwYO/njAZ5Yo52yY. 1
jess $2a$10$mWxJ9GluA8q8loY7Ct0zVelvtVfBFzKoz/GIzY3ViJBMHjOzo1onz 1

插入Authorities表记录

username authority
john ROLE_ADMIN
john ROLE_USER
amy ROLE_USER
amy ROLE_AMY
adam ROLE_USER
adam ROLE_ADAM
adam ROLE_JESS

插入User_Lower_Authorities表记录

username authority
john ROLE_AMY
john ROLE_ADAM
adam ROLE_JESS

示例2:用户John是同级管理员,管理Amy和Adam

插入User表记录

username password enabled
john $2a$10$E1N/BB9fR0U1fw5/S5Dtq.8vslLMBfBMo6/3LX1UT9kPAZjAEewb2 1
amy $2a$10$MrL8/0LwP0TiEE3LHRMbwOQ2I9l.x91DtnrRvJ1o52ckHAESHPFja 1
adam $2a$10$z2JAOzkddZTYOuNglmTuoeHeIKFEOhAQ8XZEDwYO/njAZ5Yo52yY. 1

插入Authorities表记录

username authority
john ROLE_ADMIN
john ROLE_USER
amy ROLE_USER
amy ROLE_AMY
adam ROLE_USER
adam ROLE_ADAM

插入User_Lower_Authorities表记录

username authority
john ROLE_USER
john ROLE_AMY
john ROLE_ADAM
  1. 总结

通过以上步骤,我们可以实现Spring Security中让上级拥有下级的所有权限递归授权。这种方式适合在多级管理员、多部门权限管理或针对特殊用户的权限管理中使用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security 中如何让上级拥有下级的所有权限(案例分析) - Python技术站

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

相关文章

  • Spring Boot简介与快速搭建详细步骤

    SpringBoot简介与快速搭建详细步骤 什么是SpringBoot? SpringBoot是一个开源的Java框架,可用于构建可扩展的、高度可配置、轻量级的基于Spring的应用程序。它使用“使用约定优于配置”思想,目的是让程序员能够快速地搭建Spring程序,同时也降低了对Spring的配置需求。 SpringBoot的特点 基于Spring框架和其他…

    Java 2023年5月15日
    00
  • SpringBoot测试配置属性与web启动环境超详细图解

    在Spring Boot中,我们可以使用测试配置属性和web启动环境来进行单元测试和集成测试。以下是Spring Boot测试配置属性与web启动环境的完整攻略。 测试配置属性 1. 添加测试配置文件 我们可以在src/test/resources目录下添加一个application.properties文件,用于配置测试环境的属性。例如: spring.d…

    Java 2023年5月14日
    00
  • Java编程基础元素-运算符

    Java编程基础元素-运算符 介绍 在Java编程中,运算符是用于对数据进行操作的一种符号或关键字。Java编程语言支持以下类型的运算符: 算术运算符 关系运算符 位运算符 逻辑运算符 条件运算符 赋值运算符 这些运算符可以应用于不同的数据类型,例如整数、字符、浮点数、布尔值等。 算术运算符 算术运算符用于执行基本的算术操作,例如加、减、乘、除和取模运算。J…

    Java 2023年5月26日
    00
  • 用JavaScript和注册表脚本实现右键收藏Web页选中文本

    为了实现右键收藏Web页选中文本的功能,我们需要使用JavaScript和注册表脚本。 步骤如下: 创建一个新的注册表脚本文件,将其保存为 .reg 文件类型。 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\*\shell\Collect] @="收藏选中文本" [HKEY…

    Java 2023年6月15日
    00
  • spring boot系列之集成测试(推荐)

    下面为您详细讲解“Spring Boot系列之集成测试(推荐)”的完整攻略。 什么是集成测试? 集成测试是一项对系统不同部分集成后的整体运行进行测试的活动。这种测试的目的是确定应用程序不同单元之间的交互是否正常。通过集成测试,我们可以确认系统中的不同部分是否在正确的接口下合作。 在Spring Boot中,使用集成测试会包含众多的复杂性。要进行集成测试,您需…

    Java 2023年5月15日
    00
  • java 多线程的start()和run()的理解

    run()方法中是各个线程要执行的具体内容。所以当一个线程直接调用run()时那么直接开始执行方法体,这是在main线程中的多个线程只能时按照顺序的等待前面的线程结束run()方法的执行。 而调用start方法只是线程进入准备阶段(Ready),并没有真正执行,这需要JVM进行分配时间片进行轮转线程执行,当一个线程得到时间片时,那么JVM会使该线程自动的调用…

    Java 2023年4月27日
    00
  • PHP MVC模式在网站架构中的实现分析

    PHP MVC模式在网站架构中的实现分析 什么是MVC模式 MVC即Model-View-Controller,模型-视图-控制器,是一种常用的软件设计模式,通过将应用程序分成不同的三个部分,来实现分离关注点(Separation of Concerns),来提高代码的可维护性和可重用性。 模型(Model):负责处理数据的读取和存储,以及对其进行逻辑处理。…

    Java 2023年5月20日
    00
  • Java shiro安全框架使用介绍

    Java shiro安全框架使用介绍 概述 Java Shiro框架是一个简单易用的Java安全框架,它提供了身份验证、授权、会话管理等通用安全服务,可以轻松地集成到各种应用中。本文将介绍Java Shiro框架的使用方法和示例。 安装 Maven依赖 在pom.xml文件中添加以下依赖: <dependency> <groupId>…

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