SpringBoot配置security权限管理

2022-08-10 12:58:57

SpringBoot配置security权限管理

gitee:SpringBoot配置security权限管理

数据库表结构在gitee上面有

1. 目录结构

在这里插入图片描述

2. maven依赖

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.3.RELEASE</version></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><mybatis.version>2.0.1.RELEASE</mybatis.version><mysql.version>5.1.47</mysql.version></properties><dependencies><!-- 以下是>spring boot依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 以下是>spring security依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- 以下是jsp依赖--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><scope>provided</scope></dependency><!--jsp页面使用jstl标签 --><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><scope>provided</scope></dependency><!--用于编译jsp --><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId><scope>provided</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>io.easybest</groupId><artifactId>spring-data-mybatis-boot-starter</artifactId><version>${mybatis.version}</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency></dependencies>

3.配置文件application.yaml

server:port:8080servlet:context-path: /# 配置试图解析器地址,前后缀spring:application:name: springboot-securitymvc:view:prefix: /WEB-INF/view/suffix: .jspdatasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/spring_securityusername: rootpassword: root

4.entity

用户信息表实体

importlombok.Data;/**
 * @author 黔程似景
 * @description 用户信息表
 * @date 2021/12/11 14:40
 **/@DatapublicclassUserDto{privateInteger id;privateString username;privateString password;privateString mobile;}

权限表实体

importlombok.Data;/**
 * @author 黔程似景
 * @description 权限表
 * @date 2021/12/11 14:54
 **/@DatapublicclassPermissionDto{privateString id;privateString code;privateString description;privateString url;}

5.配置类

配置登录页面WebConfig

importorg.springframework.context.annotation.Configuration;importorg.springframework.web.servlet.config.annotation.ViewControllerRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;/**
 * @author 黔程似景
 * @description 配置web启动器
 * @date 2021/12/11 12:55
 **/@ConfigurationpublicclassWebConfigimplementsWebMvcConfigurer{/**
     * 重写视图
     * @param registry 视图控制
     */@OverridepublicvoidaddViewControllers(ViewControllerRegistry registry){//使用security自带的登录页面
        registry.addViewController("/").setViewName("redirect:/login");//自定义登录页面//        registry.addViewController("/").setViewName("redirect:/login-view");//        registry.addViewController("/login-view").setViewName("/login");}}

配置用户认证权限管理WebSecurityConfig

importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.security.authentication.dao.DaoAuthenticationProvider;importorg.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;importorg.springframework.security.core.userdetails.UserDetailsService;importorg.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;importorg.springframework.security.crypto.password.PasswordEncoder;importjavax.annotation.Resource;/**
 * @author 黔程似景
 * @description 配置security权限认证
 * @date 2021/12/11 13:00
 **/@Configuration@EnableGlobalMethodSecurity(securedEnabled=true, prePostEnabled=true)//开启权限注解扫描publicclassWebSecurityConfigextendsWebSecurityConfigurerAdapter{@ResourceprivateUserDetailsService userDetailsService;/**
     * 密码编码器
     * 1. 不使用加密算法 NoOpPasswordEncoder.getInstance()
     * @return 加密编码格式
     */@BeanpublicPasswordEncoderpasswordEncoder(){returnnewBCryptPasswordEncoder();}/**
     * 将密码编码器交给UserDetailsService进行使用
     */@BeanpublicDaoAuthenticationProviderdaoAuthenticationProvider(){DaoAuthenticationProvider daoAuthenticationProvider=newDaoAuthenticationProvider();
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        daoAuthenticationProvider.setUserDetailsService(userDetailsService);return daoAuthenticationProvider;}/**
     * 安全拦截机制
     */@Overrideprotectedvoidconfigure(HttpSecurity http)throwsException{
        http.exceptionHandling().accessDeniedPage("/error.html");//配置没有权限访问跳转的自定义页面
        http.csrf().disable()//需要屏蔽掉csrf安全机制,也可以在前端进行屏蔽.authorizeRequests().antMatchers("/r/**").authenticated()//所有/r/**的请求必须通过认证(必须在子配置之后,否则会出现经过此次权限认证后,不在进行验证).anyRequest().permitAll()//除了/r/**的都可以不认证访问.and().formLogin()//允许表单登录//                .loginPage("/login-view")//使用自带的不需要在指定登录页面.loginProcessingUrl("/login").successForwardUrl("/login-success").defaultSuccessUrl("/login-success")//自定义退出.and().logout().logoutUrl("/logout")//配置退出地址//                .logoutSuccessUrl("/login-view?logout");//退出成功返回页面(使用自带的,删除此行)}}

6.mapper

importcom.qq.entity.PermissionDto;importcom.qq.entity.UserDto;importorg.apache.ibatis.annotations.Param;importorg.apache.ibatis.annotations.Select;importjava.util.List;/**
 * @author 黔程似景
 * @description 用户mapper
 * @date 2021/12/11 14:37
 **/publicinterfaceUserMapper{/**
     * 根据用户名查询用户信息,只取第一条
     *
     * @param username 用户名
     * @return 用户详情
     */@Select("SELECT * FROM t_user WHERE username = #{username} ORDER BY id ASC LIMIT 1")UserDtogetUserDtoByUsername(@Param("username")String username);/**
     * 获取用户权限
     */@Select("SELECT * FROM t_permission WHERE id in ("+"SELECT permission_id from t_role_permission WHERE role_id in ("+"SELECT role_id FROM t_user_role WHERE user_id = #{userId}"+")"+")")List<PermissionDto>getPermissionListByUserId(@Param("userId")Integer userId);}

7.service

importcom.qq.entity.PermissionDto;importcom.qq.entity.UserDto;importcom.qq.mapper.UserMapper;importorg.springframework.security.core.userdetails.User;importorg.springframework.security.core.userdetails.UserDetails;importorg.springframework.security.core.userdetails.UserDetailsService;importorg.springframework.security.core.userdetails.UsernameNotFoundException;importorg.springframework.stereotype.Service;importjavax.annotation.Resource;importjava.util.ArrayList;importjava.util.List;/**
 * @author 黔程似景
 * @description 进行用户信息注入,权限注入操作
 * @date 2021/12/12 9:42
 **/@ServicepublicclassUserDetailsServiceImplimplementsUserDetailsService{@ResourceprivateUserMapper userMapper;@OverridepublicUserDetailsloadUserByUsername(String username)throwsUsernameNotFoundException{//根据用户名获取用户信息UserDto userDto= userMapper.getUserDtoByUsername(username);//权限String[] permissionArray=this.getPermissionList(userDto.getId());//设置返回值UserDetails userDetails=null;if(userDto!=null){
            userDetails=User.withUsername(username).password(userDto.getPassword()).authorities(permissionArray).build();}return userDetails;}/**
     * 获取权限数组
     */privateString[]getPermissionList(Integer userId){List<PermissionDto> permissionDtoList= userMapper.getPermissionListByUserId(userId);List<String> permissionList=newArrayList<>();if(permissionDtoList!=null){
            permissionDtoList.forEach(permissionDto-> permissionList.add(permissionDto.getCode()));}String[] permissionArray= permissionList.toArray(newString[]{});return permissionArray;}}

8.controller

importorg.springframework.security.access.prepost.PreAuthorize;importorg.springframework.security.core.Authentication;importorg.springframework.security.core.context.SecurityContextHolder;importorg.springframework.security.core.userdetails.UserDetails;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;/**
 * @author 黔程似景
 * @description 有关于登录,测试接口
 * @date 2021/12/11 13:17
 **/@RestControllerpublicclassLoginController{@GetMapping("/login-success")publicStringloginSuccess(){//提示登录成功return"登录成功!";}@GetMapping("/r/r1")@PreAuthorize("hasAnyAuthority('p1')")//拥有P1权限才可以访问publicStringr1(){returngetUserName()+"访问资源1";}@GetMapping("/r/r2")@PreAuthorize("hasAnyAuthority('p2')")//拥有P2权限才可以访问publicStringr2(){returngetUserName()+"访问资源2";}//获取当前用户信息privateStringgetUserName(){String username;//当前认证通过的用户信息Authentication authentication=SecurityContextHolder.getContext().getAuthentication();//用户身份Object principal= authentication.getPrincipal();if(principal==null){
            username="匿名";}if(principalinstanceofUserDetails){UserDetails userDetails=(UserDetails) principal;
            username= userDetails.getUsername();}else{
            username= principal.toString();}return username;}}

9.自定义登录页面

登录页面

<%@ page contentType="text/html;charset=UTF-8" pageEncoding="utf-8" %>
<html>
<head>
    <title>用户登录</title>
</head>
<body>
<form action="login" method="post">
    用户名:<input type="text" name="username"><br>
    密&nbsp;&nbsp;&nbsp;码:
    <input type="password" name="password"><br>
    <input type="submit" value="登录">
</form>
</body>
</html>

权限不足页面

<%@ page contentType="text/html;charset=UTF-8" pageEncoding="utf-8" %>
<html>
<head>
    <title>不拥有此权限</title>
</head>
<body>
<h5>权限不够!联系管理员</h5>
</body>
</html>

10.启动类

importorg.mybatis.spring.annotation.MapperScan;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;/**
 * springboot项目 启动类
 */@SpringBootApplication@MapperScan("com.qq.mapper")publicclassSecurityApplication{public
  • 作者:qian黔景
  • 原文链接:https://blog.csdn.net/weixin_64007696/article/details/121962405
    更新时间:2022-08-10 12:58:57