springboot 数据权限_springBoot+springSecurity 数据库动态管理用户、角色、权限

985b393d0735f9de031451ea4bea8695.png

使用spring Security3的四种方法概述

那么在Spring Security3的使用中,有4种方法:

  1. 一种是全部利用配置文件,将用户、权限、资源(url)硬编码在xml文件中,已经实现过,并经过验证;
  2. 二种是用户和权限用数据库存储,而资源(url)和权限的对应采用硬编码配置,目前这种方式已经实现,并经过验证。
  3. 三种是细分角色和权限,并将用户、角色、权限和资源均采用数据库存储,并且自定义过滤器,代替原有的FilterSecurityInterceptor过滤器,
    并分别实现AccessDecisionManager、InvocationSecurityMetadataSourceService和UserDetailsService,并在配置文件中进行相应配置。
    目前这种方式已经实现,并经过验证。
    添加 Spring Security 配置类
    添加spring security到我们应用中第一步是要创建Spring Security Java 配置类。
    这个配置创建一个叫springSecurityFilterChain的Servlet过滤器,来对我们应用中所有的安全相关的事项(保护应用的所有url,验证用户名密码,表单重定向等)负责。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  
    @Autowired
    CustomSuccessHandler customSuccessHandler;
  
    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("bill").password("abc123").roles("USER");
        auth.inMemoryAuthentication().withUser("admin").password("root123").roles("ADMIN");
        auth.inMemoryAuthentication().withUser("dba").password("root123").roles("ADMIN","DBA");
    }
  
    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http.authorizeRequests()
        .antMatchers("/", "/home").access("hasRole('USER')")
        .antMatchers("/admin/**").access("hasRole('ADMIN')")
        .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
        .and().formLogin().loginPage("/login").successHandler(customSuccessHandler)
        .usernameParameter("ssoId").passwordParameter("password")
        .and().csrf()
        .and().exceptionHandling().accessDeniedPage("/Access_Denied");
    }
  
}

序:
本文使用springboot+mybatis+SpringSecurity 实现数据库动态的管理用户、角色、权限管理

本文细分角色和权限,并将用户、角色、权限和资源均采用数据库存储,并且自定义滤器,代替原有的FilterSecurityInterceptor过滤器,
并分别实现AccessDecisionManager、InvocationSecurityMetadataSourceService和UserDetailsService,并在配置文件中进行相应配置。

spring security的简单原理:

使用众多的拦截器对url拦截,以此来管理权限。但是这么多拦截器,笔者不可能对其一一来讲,主要讲里面核心流程的两个。

首先,权限管理离不开登陆验证的,所以登陆验证拦截器AuthenticationProcessingFilter要讲;
还有就是对访问的资源管理吧,所以资源管理拦截器AbstractSecurityInterceptor要讲;

但拦截器里面的实现需要一些组件来实现,所以就有了AuthenticationManager、accessDecisionManager等组件来支撑。

现在先大概过一遍整个流程,
用户登陆,会被AuthenticationProcessingFilter拦截(即认证管理),调用AuthenticationManager的实现,而且AuthenticationManager会调用ProviderManager来获取用户验证信息(不同的Provider调用的服务不同,因为这些信息可以是在数据库上,可以是在LDAP服务器上,可以是xml配置文件上等),
如果验证通过后会将用户的权限信息封装一个User放到spring的全局缓存SecurityContextHolder中,以备后面访问资源时使用。
访问资源(即授权管理),访问url时,会通过AbstractSecurityInterceptor拦截器拦截,
其中会调用FilterInvocationSecurityMetadataSource的方法来获取被拦截url所需的全部权限
在调用授权管理器AccessDecisionManager,这个授权管理器会通过spring的全局缓存SecurityContextHolder获取用户的权限信息,还会获取被拦截的url和被拦截url所需的全部权限,然后根据所配的策略(有:一票决定,一票否定,少数服从多数等),如果权限足够,则返回,权限不够则报错并调用权限不足页面。

471b00ee22357b72a3279d56dfc10148.png

重要


本文目录:
1:数据库表设计
2:权限表的业务
3:springSecurity 配置修改
4:修改home.html 文件
5:修改HomeController.Java 文件
6:测试检验

目录结构如下:

1:数据库表设计

由于本文增加了权限表所以本文的数据库表为5个分别是: 用户表、角色表、权限表、用户角色中间表、角色权限中间表

444d04892492fbe1c0d22d439f03b3ec.png

初始化数据

注意:Sys_permission 表的url通配符为两颗星,比如说 /user下的所有url,应该写成 /user/**;
    权限的名字可以随意起名
DROP TABLE IF EX
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的示例代码,演示如何使用Spring Security实现动态分配菜单权限数据权限。在本示例中,我们假设您已经创建了一个名为“menu”和一个名为“role”的数据库表。 首先,您需要定义菜单和角色的实体类: ```java @Entity @Table(name = "menu") public class Menu { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String url; private String icon; private Long parentId; // getter and setter } @Entity @Table(name = "role") public class Role { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String description; private String menus; // 存储菜单ID的字符串,以逗号分隔 // getter and setter } ``` 然后,您需要为这些实体类创建相应的Repository接口: ```java public interface MenuRepository extends JpaRepository<Menu, Long> { } public interface RoleRepository extends JpaRepository<Role, Long> { } ``` 接下来,您需要在Spring Security中配置角色权限: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomUserDetailsService userDetailsService; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/user/**").hasAnyRole("ADMIN", "USER") .anyRequest().authenticated() .and().formLogin().loginPage("/login").permitAll() .and().logout().logoutUrl("/logout").permitAll(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ``` 在上述配置中,我们定义了两个角色:“ADMIN”和“USER”,并将其与不同的资源进行关联。例如,只有拥有“ADMIN”角色用户才能访问“/admin/**”路径。 接下来,您需要实现自定义的UserDetailsService类,以根据用户角色动态生成菜单: ```java @Service public class CustomUserDetailsService implements UserDetailsService { @Autowired private UserRepository userRepository; @Autowired private RoleRepository roleRepository; @Autowired private MenuRepository menuRepository; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userRepository.findByUsername(username); if (user == null) { throw new UsernameNotFoundException("User not found with username: " + username); } List<GrantedAuthority> authorities = new ArrayList<>(); String[] roles = user.getRoles().split(","); for (String roleName : roles) { Role role = roleRepository.findByName(roleName); if (role != null) { authorities.add(new SimpleGrantedAuthority(role.getName())); } String[] menuIds = role.getMenus().split(","); for (String menuId : menuIds) { Menu menu = menuRepository.findById(Long.parseLong(menuId)).orElse(null); if (menu != null) { // 生成菜单 } } } return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), authorities); } } ``` 在上述代码中,我们首先获取用户所拥有的角色,然后根据角色获取对应的菜单。最后,我们将这些菜单生成为动态菜单,以供用户访问。 最后,您可以使用Spring Data JPA和Thymeleaf等技术实现动态生成菜单的功能。例如: ```html <ul class="sidebar-menu"> <li th:each="menu : ${menus}" th:class="${menu.parentId == null ? 'treeview' : ''}"> <a th:href="@{${menu.url}}"> <i th:class="${menu.icon}"></i> <span th:text="${menu.name}"></span> <i th:if="${menu.children.size() > 0}" class="fa fa-angle-left pull-right"></i> </a> <ul th:if="${menu.children.size() > 0}" class="treeview-menu"> <li th:each="child : ${menu.children}"> <a th:href="@{${child.url}}"> <i th:class="${child.icon}"></i> <span th:text="${child.name}"></span> </a> </li> </ul> </li> </ul> ``` 上述代码将根据用户所拥有的菜单动态生成侧边栏菜单。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值