IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> springboot整合spring security -> 正文阅读

[Java知识库]springboot整合spring security

导入sql

/*
 Navicat Premium Data Transfer

 Source Server         : localhost
 Source Server Type    : MySQL
 Source Server Version : 80011
 Source Host           : localhost:3306
 Source Schema         : securitydemo

 Target Server Type    : MySQL
 Target Server Version : 80011
 File Encoding         : 65001

 Date: 18/11/2021 20:19:24
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for sys_menu
-- ----------------------------
DROP TABLE IF EXISTS `sys_menu`;
CREATE TABLE `sys_menu`  (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `menu_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜单名称',
  `parent_id` int(11) UNSIGNED DEFAULT 0 COMMENT '父级菜单ID',
  `order_num` int(11) UNSIGNED DEFAULT 0 COMMENT '显示顺序',
  `url` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '#' COMMENT '请求地址',
  `menu_type` int(11) UNSIGNED DEFAULT NULL COMMENT '菜单类型10:目录;20:菜单;30:按钮',
  `visible` int(11) UNSIGNED NOT NULL DEFAULT 10 COMMENT '菜单状态10:显示;20:隐藏',
  `perms` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '权限标识',
  `icon` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '#' COMMENT '菜单图标',
  `create_by` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '创建者',
  `create_time` timestamp(0) DEFAULT NULL COMMENT '创建时间',
  `update_by` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '更新者',
  `update_time` timestamp(0) DEFAULT NULL COMMENT '更新时间',
  `remark` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 105 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '菜单表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of sys_menu
-- ----------------------------
INSERT INTO `sys_menu` VALUES (1, '系统管理', 0, 1, '#', 10, 10, '', '#', 'admin', NULL, 'admin', NULL, NULL);
INSERT INTO `sys_menu` VALUES (10, '用户管理', 1, 1, '/system/user', 20, 10, 'user:view', '#', 'admin', NULL, 'admin', NULL, NULL);
INSERT INTO `sys_menu` VALUES (101, '用户查询', 10, 1, '#', 30, 10, 'user:list', '#', 'admin', NULL, 'admin', NULL, NULL);
INSERT INTO `sys_menu` VALUES (102, '用户新增', 10, 2, '#', 30, 10, 'user:add', '#', 'admin', NULL, 'admin', NULL, NULL);
INSERT INTO `sys_menu` VALUES (103, '用户修改', 10, 3, '#', 30, 10, 'user:update', '#', 'admin', NULL, 'admin', NULL, NULL);
INSERT INTO `sys_menu` VALUES (104, '用户删除', 10, 4, '#', 30, 10, 'user:delete', '#', 'admin', NULL, 'admin', NULL, NULL);

-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role`  (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `role_code` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '角色编号',
  `role_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '角色名称',
  `status` int(11) UNSIGNED NOT NULL DEFAULT 10 COMMENT '角色状态10:正常;11:停用',
  `del_flag` int(11) NOT NULL DEFAULT 0 COMMENT '删除标识0:未删除;1:已删除',
  `create_by` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '创建者',
  `create_time` timestamp(0) DEFAULT NULL COMMENT '创建时间',
  `update_by` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '更新者',
  `update_time` timestamp(0) DEFAULT NULL COMMENT '更新时间',
  `remark` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '角色表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of sys_role
-- ----------------------------
INSERT INTO `sys_role` VALUES (1, 'admin', '超级管理员', 10, 0, 'admin', NULL, 'admin', NULL, NULL);
INSERT INTO `sys_role` VALUES (2, 'user', 'user', 10, 0, NULL, NULL, NULL, NULL, NULL);

-- ----------------------------
-- Table structure for sys_role_menu
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_menu`;
CREATE TABLE `sys_role_menu`  (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `role_id` int(11) UNSIGNED NOT NULL COMMENT '角色ID',
  `menu_id` int(11) UNSIGNED NOT NULL COMMENT '菜单ID',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `role_id`(`role_id`) USING BTREE,
  INDEX `menu_id`(`menu_id`) USING BTREE,
  CONSTRAINT `sys_role_menu_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
  CONSTRAINT `sys_role_menu_ibfk_2` FOREIGN KEY (`menu_id`) REFERENCES `sys_menu` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '角色菜单表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of sys_role_menu
-- ----------------------------
INSERT INTO `sys_role_menu` VALUES (7, 1, 1);
INSERT INTO `sys_role_menu` VALUES (8, 1, 10);
INSERT INTO `sys_role_menu` VALUES (9, 1, 101);
INSERT INTO `sys_role_menu` VALUES (10, 1, 102);
INSERT INTO `sys_role_menu` VALUES (11, 1, 103);
INSERT INTO `sys_role_menu` VALUES (12, 1, 104);
INSERT INTO `sys_role_menu` VALUES (13, 2, 1);
INSERT INTO `sys_role_menu` VALUES (14, 2, 101);
INSERT INTO `sys_role_menu` VALUES (15, 2, 103);
INSERT INTO `sys_role_menu` VALUES (16, 2, 10);

-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user`  (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `user_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
  `real_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '真实名称',
  `password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码',
  `sex` int(11) NOT NULL DEFAULT 10 COMMENT '性别10:男;11:女;12:其他',
  `avatar` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '头像路径',
  `status` int(11) NOT NULL DEFAULT 10 COMMENT '状态10:正常;11:锁定;12:注销',
  `del_flag` int(11) NOT NULL DEFAULT 0 COMMENT '删除标识0:未删除;1:已删除',
  `create_by` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '创建者',
  `create_time` timestamp(0) DEFAULT NULL COMMENT '创建时间',
  `update_by` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '更新者',
  `update_time` timestamp(0) DEFAULT NULL COMMENT '更新时间',
  `remark` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES (3, 'admin', '超级管理员', '$2a$10$OyN3EJxYhJ/C9OJAEb8ZMOW9eh9RvrPNB1BZuFpeE.hMBokH8CCyS', 10, '', 10, 0, 'admin', '2020-09-30 08:34:18', 'admin', '2020-09-30 08:34:18', '');
INSERT INTO `sys_user` VALUES (4, 'user', 'vip', '$2a$10$OyN3EJxYhJ/C9OJAEb8ZMOW9eh9RvrPNB1BZuFpeE.hMBokH8CCyS', 10, NULL, 10, 0, NULL, NULL, NULL, NULL, NULL);

-- ----------------------------
-- Table structure for sys_user_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role`  (
  `id` int(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `user_id` int(20) UNSIGNED NOT NULL COMMENT '用户ID',
  `role_id` int(20) UNSIGNED NOT NULL COMMENT '角色ID',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `user_id`(`user_id`) USING BTREE,
  INDEX `role_id`(`role_id`) USING BTREE,
  CONSTRAINT `sys_user_role_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
  CONSTRAINT `sys_user_role_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户角色表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of sys_user_role
-- ----------------------------
INSERT INTO `sys_user_role` VALUES (2, 3, 1);
INSERT INTO `sys_user_role` VALUES (3, 4, 2);

SET FOREIGN_KEY_CHECKS = 1;

1.导入依赖

   <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--springSecurity-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.26</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.20</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
        </dependency>

    </dependencies>

2.采用mybaits-plus逆向工程生成工程,直接运行主方法

public class MybatisPlusGenerator {
    public static void main(String[] args) {
        AutoGenerator mpg = new AutoGenerator();
        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        //生成文件路径
        gc.setOutputDir("D:\\idea_work\\mc_parent\\security_demo\\src\\main\\java");
        gc.setAuthor("tt");
        gc.setOpen(false);
        mpg.setGlobalConfig(gc);
        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql:///securitydemo");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        mpg.setDataSource(dsc);
        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.it");
        pc.setEntity("pojo");
        pc.setMapper("mapper");
        pc.setService("service");
        pc.setServiceImpl("service.impl");
        pc.setController("controller");
        mpg.setPackageInfo(pc);
        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setSuperEntityClass("com.baomidou.mybatisplus.extension.activerecord.Model");
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        strategy.setEntityLombokModel(true);
        String tableNames = "sys_role,sys_role_menu,sys_menu,sys_user,sys_user_role";
        strategy.setInclude(tableNames.split(","));
        strategy.setControllerMappingHyphenStyle(true);
        //对应实体类去除前缀
        strategy.setTablePrefix("sys_");
        mpg.setStrategy(strategy);
        mpg.execute();

    }
}

3.编写返回结果和结果状态码类

package com.it.util;

import lombok.Data;

import java.util.HashMap;
import java.util.Map;

@Data
public class ResultData {
    /**
     * 是否成功
     */
    private Boolean success;
    /**
     * 返回编码
     */
    private Integer code;
    /**
     * 返回消息
     */
    private String message;
    /**
     * 返回数据
     */
    private Map<String, Object> data = new HashMap<String, Object>();

    public ResultData() {
    }

    /**
     * 成功静态方法
     *
     * @return
     */
    public static ResultData ok() {
        ResultData result = new ResultData();
        result.setSuccess(true);
        result.setCode(ResultCode.SUCCESS);
        result.setMessage("成功!");
        return result;
    }

    /**
     * 成功静态方法
     *
     * @return
     */
    public static ResultData ok(Integer code, String message) {
        ResultData result = new ResultData();
        result.setSuccess(true);
        result.setCode(code);
        result.setMessage(message);
        return result;
    }

    /**
     * 失败静态方法
     *
     * @return
     */

    public static ResultData error() {
        ResultData result = new ResultData();
        result.setSuccess(false);
        result.setCode(ResultCode.ERROR);
        result.setMessage("失败!");
        return result;
    }

    /**
     * 失败静态方法
     *
     * @return
     */
    public static ResultData error(Integer code, String message) {
        ResultData result = new ResultData();
        result.setSuccess(false);
        result.setCode(code);
        result.setMessage(message);
        return result;
    }

    public ResultData success(Boolean success) {
        this.setSuccess(success);
        return this;
    }

    public ResultData message(String message) {
        this.setMessage(message);
        return this;
    }

    public ResultData code(Integer code) {
        this.setCode(code);
        return this;
    }

    public ResultData data(String key, Object value) {
        this.data.put(key, value);
        return this;
    }

    public ResultData data(Map<String, Object> map) {
        this.setData(map);
        return this;
    }
}
package com.it.util;

public interface ResultCode {
    /**成功*/
    public static Integer SUCCESS = 20000;
    /**失败*/
    public static Integer ERROR = 20001;
    /**未授权(匿名)*/
    public static Integer UNAUTHORIZED_01 = 20002;
    /**未授权(认证后)*/
    public static Integer UNAUTHORIZED_02 = 20003;
}

4.编写前端静态页面

login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
<h3 align="center">用户登录 </h3>
<form action="/login" method="post">
    <table align="center" border="1px" cellspacing="0" bgcolor="#dfe8f6">
        <tr height="45px">
            <td>
                &nbsp;&nbsp;用户名:
            </td>
            <td>
                &nbsp;&nbsp;&nbsp;<input type="text" placeholder="请输入用户名" name="username"/>
            </td>
        </tr>
        <tr height="45px">
            <td>
                &nbsp;&nbsp;用户密码:
            </td>
            <td>
                &nbsp;&nbsp;&nbsp;<input type="password" name="password"/>
            </td>
        </tr>
        <tr height="45px">
            <td colspan="2" align="center">
                <input type="submit" value="登录"/>
                &nbsp;&nbsp;&nbsp;&nbsp;
                <input type="reset" value="重置"/>
            </td>
        </tr>
    </table>
</form>
</body>
</html>

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>登录成功!</h1>
<a href="/logout">退出</a><br/>
<a href="/user/list">用户列表</a><br/>
<a href="/user/add">新增用户</a><br/>
<a href="/user/update">修改用户</a><br/>
<a href="/user/delete">删除用户</a><br/>
</body>
</html>

5.编写UserDetailsService实现类

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MenuMapper menuMapper;
    @Autowired
    private RoleMapper roleMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", username);
        User currentUser = userMapper.selectOne(wrapper);
        if (currentUser == null) {
            throw new UsernameNotFoundException("用户不存在!");
        }
        System.out.println(currentUser);
        //获取用户角色和菜单权限
        List<GrantedAuthority> authorityList = new ArrayList<>();
        List<Role> roleList = roleMapper.selectRoleCodesByUserId(currentUser.getId());
        for (Role role : roleList) {
            //添加用户的角色名称
            SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_" + role.getRoleCode());
            authorityList.add(authority);
        }
        List<Menu> permsList = menuMapper.selectMenuPermsByUserId(currentUser.getId());
        System.out.println("permsList = " + permsList);
        for (Menu perm : permsList) {
            //添加用户所拥有的权限
            if(StringUtils.hasText(perm.getPerms())){
                SimpleGrantedAuthority authority = new SimpleGrantedAuthority(perm.getPerms());
                authorityList.add(authority);
            }

        }
        //注意区分自己定义的user类和security包下的user类
        return new  org.springframework.security.core.userdetails.User
        (currentUser.getUserName(), currentUser.getPassword(), authorityList);
    }

}

6.编写mapper接口的两个方法:

<mapper namespace="com.it.mapper.MenuMapper">
    <select id="selectMenuPermsByUserId" resultType="com.it.pojo.Menu">
         SELECT m.* from sys_menu m,sys_role_menu rm,sys_role r,sys_user_role ur where m.id=rm.menu_id and
         rm.role_id=r.id and r.id=ur.role_id and ur.user_id=#{id}
    </select>
</mapper>

?

<mapper namespace="com.it.mapper.RoleMapper">
<select id="selectRoleCodesByUserId" resultType="com.it.pojo.Role">
    SELECT r.* from sys_role r,sys_user_role ur where r.id=ur.role_id and ur.user_id=#{id}
</select>
</mapper>

7.编写认证失败、权限不够处理类

认证失败:

@Component
public class SecurityAuthenticationFailureHandler implements AuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        writer.write(JSON.toJSONString(ResultData.error(ResultCode.ERROR, "登录失败!")));
    }
}

未登录:

@Component
public class AuthenticationEntryPointHandler implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        writer.write(JSON.toJSONString(ResultData.error(ResultCode.UNAUTHORIZED_01, "匿名访问无权限!")));
    }
}

登录但无权限:

@Component
public class SecurityAccessDeniedHandler implements AccessDeniedHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        writer.write(JSON.toJSONString(ResultData.error(ResultCode.UNAUTHORIZED_02, "认证用户无权访问!")));
    }
}

8.编写security配置类

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsServiceImpl userDetailsService;
    @Autowired
    private AuthenticationEntryPointHandler authenticationEntryPointHandler;
    @Autowired
    private SecurityAccessDeniedHandler securityAccessDeniedHandler;
    @Autowired
    private SecurityAuthenticationFailureHandler securityAuthenticationFailureHandler;


    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //关闭csrf
        http.csrf().disable()
        //表单登录
        .formLogin()
        //登录页面
        .loginPage("/login.html")
        //登录访问路径,与页面表单提交路径一致
        .loginProcessingUrl("/login")
        //登录成功后访问路径
        .defaultSuccessUrl("/index.html").permitAll()
        //登录失败操作
        .failureHandler(securityAuthenticationFailureHandler)
        // 自定义登陆用户名和密码参数,默认为username和password
        .usernameParameter("username")
        .passwordParameter("password")
        .and()
        //认证配置
        .authorizeRequests()
        .antMatchers("/login.html", "/login").permitAll()
        //配置静态页面可以访问
        .antMatchers("/js/**", "/css/**", "/images/**", "/favicon.ico").permitAll()
        //任何请求
        .anyRequest()
        //都需要身份验证
        .authenticated();
        //配置无权限访问页面
        //http.exceptionHandling().accessDeniedPage("/uanuth.html");
        http
        //游客无权访问
        .exceptionHandling().authenticationEntryPoint(authenticationEntryPointHandler)
        //用户登录但无权访问
        .accessDeniedHandler(securityAccessDeniedHandler);
        //配置退出
        http.logout()
        //退出路径
        .logoutUrl("/logout")
        //退出后跳转页面
        .logoutSuccessUrl("/login.html");
    }

}

9.编写控制类

@RestController
@RequestMapping("/user")
public class UserController {
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('user:list')")
    public ResultData userList() {
        return ResultData.ok(ResultCode.SUCCESS, "访问用户查询界面成功!");
    }

    @GetMapping("/add")
    @PreAuthorize("hasAuthority('user:add')")
    public ResultData userAdd() {
        return ResultData.ok(ResultCode.SUCCESS, "访问用户新增界面成功!");
    }

    /**
     * 测试无权限访问,数据库中权限是user:update
     *
     * @return
     */
    @GetMapping("/update")
    @PreAuthorize("hasAuthority('user:update')")
    public ResultData userUpdate() {
        return ResultData.ok(ResultCode.SUCCESS, "访问用户修改界面成功!");
    }

    @GetMapping("/delete")
    //@Secured("ROLE_admin")= @PreAuthorize("hasRole('ROLE_admin')")
    @PreAuthorize("hasRole('ROLE_admin')")
    public ResultData userDelete() {
        return ResultData.ok(ResultCode.SUCCESS, "访问用户删除界面成功!");
    }

}

10.编写application.yml文件

server:
  port: 8003
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql:///securitydemo?serverTimezone=UTC&useSSL=true&characterEncoding=utf-8
    username: root
    password: 123456
  application:
    name: security_demo
mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.it.pojo
logging:
  level:
    com:
      it:
        mapper: info

目录结构

?结果演示

?1.直接访问首页:

提示无法访问,不能进入

?2.登录失败:

提示登录失败,无法访问首页

3.普通用户登录:

可以访问首页且可以查看和修改用户,不能添加和删除用户(没有对应权限)

?

?

?

?

?

?

4.管理员登录

可以 访问首页并且能对用户进行增删改查

?

?

?

?

?

?

?

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-11-19 17:30:07  更:2021-11-19 17:31:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:38:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码