zoukankan      html  css  js  c++  java
  • springboot + shiro + mysql + mybatis 工程快速搭建

    1. 新建 springboot 工程

    2. 随便起个名字

     

     3. 初始化工程

     

     4. 导入 shiro 和 thymeleaf 依赖

            <!-- thymeleaf依赖 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
            <!-- thymeleaf依赖结束 -->
            <!-- shiro依赖 -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.3.2</version>
            </dependency>
            <!-- shiro依赖结束 -->

    5. 编写 application.yml 配置文件

    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url:
    jdbc:mysql:///test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=true
      username: root password: root thymeleaf: encoding: UTF-8

    6. 新建一个 User 类

    import lombok.Data;
    
    @Data
    public class User {
        private Integer id;
        private String username;
        private String password;
        private String prems;
    }

    7. 创建 User 业务层与持久层

     UserService

    import com.example.exam01.entity.User;
    
    /**
     * User 业务层
     */
    public interface UserService {
        User findByName(String username);
    }

    UserServiceImpl

    import com.example.exam01.dao.UserDao;
    import com.example.exam01.entity.User;
    import com.example.exam01.service.UserService;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import javax.annotation.Resource;
    
    /**
     * User 业务层实现类
     */
    @Service
    @Transactional
    public class UserServiceImpl implements UserService {
    
        @Resource
        private UserDao userDao;
    
        @Override
        public User findByName(String username) {
            return userDao.findByName(username);
        }
    }

    UserDao

    import com.example.exam01.entity.User;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Select;
    import org.springframework.stereotype.Repository;
    
    /**
     * User 持久层
     */
    @Repository
    @Mapper
    public interface UserDao {
    
        @Select("SELECT * FROM user WHERE username = #{username}")
        User findByName(@Param("username") String username);
    }

    8. 新建一个 ShiroConfig 配置文件类

    import com.example.exam01.shiro.realm.MyRealm;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
    import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    /**
     * shiro 配置类
     */
    @Configuration
    public class ShiroConfig {
        @Bean(name = "shiroFilter")
        public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            shiroFilterFactoryBean.setSecurityManager(securityManager);
            shiroFilterFactoryBean.setLoginUrl("/toLogin");
            shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");
    
            // 定义一个map集合用来存放访问规则
            Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
            /*
                    Shiro内置过滤器, 可以实现权限相关的拦截器
                    常用的过滤器:
                    anon: 无需认证(登录)可以访问
                    authc: 必须认证才可以访问
                    user: 使用 rememberMe 的功能可以直接访问
                    perms: 该资源必须得到资源权限才可以访问
                    role: 该资源必须得到角色权限才可以访问
             */
            // 注意配置顺序
            filterChainDefinitionMap.put("/login", "anon");
            filterChainDefinitionMap.put("/", "anon");
            filterChainDefinitionMap.put("/admin/**", "perms[user:admin]");
            filterChainDefinitionMap.put("/user/**", "authc");
            filterChainDefinitionMap.put("/logout", "authc");
            //主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截 剩余的都需要认证
            filterChainDefinitionMap.put("/**", "authc");
            // 将规则写入 shiroFilterFactoryBean 中
            shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
            return shiroFilterFactoryBean;
    
        }
    
        /**
         * 获取 SecurityManager
         * @return
         */
        @Bean
        public SecurityManager securityManager() {
            DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
            defaultSecurityManager.setRealm(myRealm());
            return defaultSecurityManager;
        }
    
        /**
         * 获取 MyRealm
         * @return
         */
        @Bean
        public MyRealm myRealm() {
            MyRealm myRealm = new MyRealm();
            return myRealm;
        }
    }

    9. 新建一个 Realm 类

    import com.example.exam01.entity.User;
    import com.example.exam01.service.UserService;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.apache.shiro.subject.Subject;
    
    import javax.annotation.Resource;
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * realm类
     */
    public class MyRealm extends AuthorizingRealm {
    
        @Resource
        private UserService userService;
        /**
         * 授权
         * @param principalCollection
         * @return
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            // 获取当前登录用户
            Subject subject = SecurityUtils.getSubject();
            User user = (User) subject.getPrincipal();
    
            // 获取 SimpleAuthorizationInfo 对象写入授权规则
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    
            // 创建一个 set 集合用来保存当前用户的授权信息
            Set<String> stringSet = new HashSet<>();
            stringSet.add(user.getPrems());
    
            // 将授权信息写入 SimpleAuthorizationInfo 对象中
            info.setStringPermissions(stringSet);
            return info;
        }
    
        /**
         * 认证
         * @param auToken
         * @return
         * @throws AuthenticationException
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auToken) throws AuthenticationException {
            // AuthenticationToken 强转 UsernamePasswordToken
            UsernamePasswordToken token = (UsernamePasswordToken) auToken;
            // 从数据库获取用户信息
            User user = userService.findByName(token.getUsername());
            return new SimpleAuthenticationInfo(user, user.getPassword(),getName());
        }
    }

     10. 编写 controller 层

     LoginController

    package com.example.exam01.controller;
    
    import com.example.exam01.entity.User;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.crypto.hash.SimpleHash;
    import org.apache.shiro.subject.Subject;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    /**
     *  Login 控制类
     */
    
    @Controller
    public class LoginController {
    
        // 跳转登录页面
        @RequestMapping("/toLogin")
        public String toLogin(){
            return "login";
        }
    
        // 执行登录方法
        @RequestMapping("/login")
        public String login(User user, Model model){
            // 执行加密算法
            SimpleHash md5 = new SimpleHash("MD5",user.getPassword(),null,1);
            String password = md5.toString();
    
            // 获取 subject 对象
            Subject subject = SecurityUtils.getSubject();
    
            // 准备 token 令牌
            UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),password);
    
            // 定义一个返回提示信息容器
            String msg = null;
            // 执行认证登录
            try{
                subject.login(token);
            } catch (UnknownAccountException uae) {
                msg = "未知账户";
            } catch (IncorrectCredentialsException ice) {
                msg = "密码不正确";
            } catch (LockedAccountException lae) {
                msg = "账户已锁定";
            } catch (ExcessiveAttemptsException eae) {
                msg = "用户名或密码错误次数过多";
            } catch (AuthenticationException ae) {
                msg = "用户名或密码不正确";
            }
    
            // 判断登录是否成功
            if (subject.isAuthenticated()) {
                return "main";
            } else {
                token.clear();
                // 写入返回 tips
                model.addAttribute("msg",msg);
                return "login";
            }
        }
    
        // 执行登出方法
        @RequestMapping("/logout")
        public String logout(){
            Subject subject = SecurityUtils.getSubject();
            subject.logout();
            return "login";
        }
    
        // 跳转错误页面
        @RequestMapping("/noAuth")
        public String noAuth(){
            return "noAuth";
        }
    }

    UserController

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        @RequestMapping("list")
        public String list(){
            return "/user/userList";
        }
    }

    AdminController

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping("/admin")
    public class AdminController {
    
        @RequestMapping("/list")
        public String list(){
            return "/admin/adminList";
        }
    }

    11. 编写 HTML 页面

     

     login.html

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
    <head>
    <meta charset="UTF-8">
    <title>登录</title>
    </head>
    <body>
    <h3 th:text="${msg}" style="color: red"></h3>
    <form action="/login" method="post">
    <label>账号: <input type="text" name="username" placeholder="请输入用户名"></label><br>
    <label>密码: <input type="password" name="password" placeholder="请输入密码"></label><br>
    <input type="submit" value="登录">
    </form>
    </body>
    </html>

    main.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>主页</title>
    </head>
    <body>
    <a href="/logout"><button>退出登录</button></a>
    <hr>
    <a href="/user/list">UserList</a>
    <br>
    <a href="/admin/list">AdminList</a>
    </body>
    </html>

    noAuth.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>错误页面</title>
    </head>
    <body>
    您没有此权限!
    </body>
    </html>

    adminList.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>AdminList</title>
    </head>
    <body>
    AdminList 只是一个需要 admin 权限才能访问的页面
    </body>
    </html>

     userList.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>UserList</title>
    </head>
    <body>
    UserList 这是一个需要登录才能访问的页面
    </body>
    </html>

    12. 编写数据库

    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;
    
    
    DROP TABLE IF EXISTS `user`;
    CREATE TABLE `user`  (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
      `username` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名',
      `password` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密码',
      `prems` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '权限',
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
    
    INSERT INTO `user` VALUES (1, 'lilei', '202cb962ac59075b964b07152d234b70', 'user:admin');
    INSERT INTO `user` VALUES (2, 'hanmeimei', '202cb962ac59075b964b07152d234b70', 'user:user');
    
    SET FOREIGN_KEY_CHECKS = 1;

     源码下载: springboot + shiro demo 下载地址

  • 相关阅读:
    Swift 类的使用class
    Swift 结构体struct
    Swift 枚举enum
    Swift 元组 Tuple
    python UI自动化截图对比
    取出yaml中的字符并转换为元祖
    python 使用pyinstaller对PY文件进行exe打包
    Jenkins 浏览器打开提示离线
    pywinauto 学习笔记-利用文本框输入操作键盘
    打开文件测试的测试点
  • 原文地址:https://www.cnblogs.com/zhainan-blog/p/11969781.html
Copyright © 2011-2022 走看看