SpringBoot + Shiro + Mybatis-plus + Kaptcha + vue实现权限管理登录功能

Posted 黑胡子大叔的小屋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot + Shiro + Mybatis-plus + Kaptcha + vue实现权限管理登录功能相关的知识,希望对你有一定的参考价值。

登录功能

在这里插入图片描述

使用到的技术

  • shiro
  • Mybatis-plus
  • Springboot
  • kaptcha

引入依赖

	<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- shiro -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.7.0</version>
        </dependency>

        <!--mybatis-plus 持久层-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.1</version>
        </dependency>

        <!--   整合swagger     -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.8.0</version>
        </dependency>
        <!-- kaptcha 验证码 -->
        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
        </dependency>
    </dependencies>

配置shiro

package com.unclebb.zlgl.config;

import com.unclebb.zlgl.utils.CustomRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

/**
 * @program: zlgl
 * @description: Shiro配置类:将SecurityManager以及Realm都注入到Spring容器中
 * @author: LiuZhiliang
 * @create: 2021-05-10 08:56
 **/
@Configuration
public class ShiroConfig {
    /**
     * @Description: Filter工厂,设置对应的过滤条件和跳转条件
     * @Param:
     * @return:
     * @Author: Liuzhiliang
     * @Date:
     */

    //权限管理,配置主要是Realm的管理认证
    @Bean
    public DefaultWebSecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        ThreadContext.bind(securityManager);
        return securityManager;
    }
    //将自己的验证方式加入容器
    @Bean
    public CustomRealm myShiroRealm() {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        //加密
        matcher.setHashAlgorithmName("md5");
        matcher.setHashIterations(1);
        CustomRealm customRealm = new CustomRealm();
        customRealm.setCredentialsMatcher(matcher);
        return customRealm;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
//        Map<String,String> maps = new HashMap<>();
//        maps.put("/logout","logout");
//        maps.put("/**","authc");
//        shiroFilterFactoryBean.setLoginUrl("/login");
//        shiroFilterFactoryBean.setUnauthorizedUrl("/403.html");
//        shiroFilterFactoryBean.setSuccessUrl("/index");
//        shiroFilterFactoryBean.setFilterChainDefinitionMap(maps);
        return shiroFilterFactoryBean;
    }

}

配置swagger

package com.unclebb.zlgl.config;

import com.google.common.base.Predicates;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * @Author unclebb
 * @Description Swagger配置类
 * @Date 2021/5/9
 **/
@Configuration
@EnableSwagger2
public class Swagger2Config {

    @Bean
    public Docket webApiConfig(){

        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("webApi")
                .apiInfo(webApiInfo())
                .select()
                //过滤掉admin路径下的所有页面
                .paths(Predicates.and(PathSelectors.regex("/user/.*")))
                //过滤掉所有error或error.*页面
                //.paths(Predicates.not(PathSelectors.regex("/error.*")))
                .build();

    }

    private ApiInfo webApiInfo(){

        return new ApiInfoBuilder()
                .title("网站-API文档")
                .description("本文档描述了网站微服务接口定义")
                .version("1.0")
                .contact(new Contact("qy", "http://atguigu.com", "55317332@qq.com"))
                .build();
    }

}

配置kaptcha

package com.unclebb.zlgl.config;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.Properties;

/**
 * @program: zlgl
 * @description: Kaptcha配置类
 * @author: LiuZhiliang
 * @create: 2021-05-12 09:03
 **/
@Component
public class KaptchaConfig {
    @Bean
    public DefaultKaptcha getKaptcha(){
        DefaultKaptcha dk = new DefaultKaptcha();
        Properties properties = new Properties();
        // 图片边框
        properties.setProperty("kaptcha.border", "yes");
        // 边框颜色
        properties.setProperty("kaptcha.border.color", "105,179,90");
        // 字体颜色
        properties.setProperty("kaptcha.textproducer.font.color", "red");
        // 图片宽
        properties.setProperty("kaptcha.image.width", "110");
        // 图片高
        properties.setProperty("kaptcha.image.height", "40");
        // 字体大小
        properties.setProperty("kaptcha.textproducer.font.size", "30");
        // session key
        properties.setProperty("kaptcha.session.key", "code");
        // 验证码长度
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        // 字体
        properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
        Config config = new Config(properties);
        dk.setConfig(config);

        return dk;
    }
}

pojo

User

package com.unclebb.zlgl.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.util.Set;

/**
 * @Author unclebb
 * @Description 用户实体类
 * @Date 2021/5/9
 **/
@Data
@TableName(value = "user")
public class User {
    @TableId(value = "id",type = IdType.AUTO)//指定自增策略
    private int id;
    @TableField(value = "username")
    private String username;
    @TableField(value = "password")
    private String password;
    @TableField(exist = false)
    private Set<Role> rolesSet;
    private String salt;
}

Role

package com.unclebb.zlgl.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

import java.util.Set;

/**
 * @Author unclebb
 * @Description 角色实体类
 * @Date 2021/5/9
 **/
@Data
public class Role {
    @TableId(value = "id",type = IdType.AUTO)//指定自增策略
    private int id;
    @TableField(value = "user_name")
    private String userName;
    @TableField(value = "role_name")
    private String roleName;
    @TableField(exist = false)
    private Set<Permission> permissionSet;
}

Permission

package com.unclebb.zlgl.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

/**
 * @Author unclebb
 * @Description 权限实体类
 * @Date 2021/5/9
 **/
@Data
public class Permission {
    @TableId(value = "id",type = IdType.AUTO)//指定自增策略
    private int id;
    @TableField(value = "role_name")
    private String roleName;
    @TableField(value = "permission_name")
    private String permissionName;
}

Mapper

基本格式:

package com.unclebb.zlgl.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.unclebb.zlgl.pojo.User;
import org.apache.ibatis.annotations.Mapper;

/**
 * @Author unclebb
 * @Description 用户映射
 * @Date 2021/5/9
 **/
@Mapper
public interface UserMapper extends BaseMapper<User> {
}

Service

Interface

LoginService

package com.unclebb.zlgl.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.unclebb.zlgl.pojo.User;
import org.springframework.stereotype.Service;

/**
 * @Author unclebb
 * @Description 用户登录接口
 * @Date 2021/5/9
 **/
@Service
public interface LoginService extends IService<User> {
    public User getByUsername(String username);
}

RoleService

package com.unclebb.zlgl.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.unclebb.zlgl.pojo.Role;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public interface RoleService extends IService<Role> {
    public List<Role> getRole(String userName);
}

PermissionService

package com.unclebb.zlgl.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.unclebb.zlgl.pojo.Permission;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public interface PermissionService extends IService<Permission> {
    public List<Permission> getPermissions(String roleName);
}

ServiceImpl

LoginServiceImpl

package com.unclebb.zlgl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.unclebb.zlgl.mapper.UserMapper;
import com.unclebb.zlgl.pojo.Role;
import com.unclebb.zlgl.pojo.User;
import com.unclebb.zlgl.service.LoginService;
import com.unclebb.zlgl.service.PermissionService;
import com.unclebb.zlgl.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @Author unclebb
 * @Description 登录实现类
 * @Date 2021/5/9
 **/
@Service
public class LoginServiceImpl extends ServiceImpl<UserMapper, User> implements LoginService {

    @Autowired
    RoleService roleService;

    @Override
    public User getByUsername(String username) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        User user = this.getOne(wrapper)

以上是关于SpringBoot + Shiro + Mybatis-plus + Kaptcha + vue实现权限管理登录功能的主要内容,如果未能解决你的问题,请参考以下文章

精品源码Spring MVC+Mybatis+Shiro+Bootstrap仓库管理系统

springboot整合shiro

SpringBoot整合Shiro 四:认证+授权

springboot学习笔记-5 springboot整合shiro

springboot学习笔记-5 springboot整合shiro

SpringBoot整合Shiro