shiro入门

Shiro简介

先上官网https://shiro.apache.org/

什么是Shiro

Shiro是一个功能强大且易于使用的Java安全框架,它执行身份验证、授权、加密和会话管理。使用Shiro易于理解的API,您可以快速轻松地保护任何应用程序—从最小的移动应用程序到最大的web和企业应用程序

Shiro核心架构

在这里插入图片描述

Subject

Subject即主体,外部应用与subject进行交互,subject记录了当前的操作用户,将用户的概念理解为当前操作的主体。外部程序通过subject进行认证授权,而subject是通过SecurityManager安全管理器进行认证授权

SecurityManager

SecurityManager即安全管理器,对全部的subject进行安全管理,它是shiro的核心,负责对所有的subject进行安全管理。通过SecurityManager可以完成subject的认证、授权等,实质上SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理等

SecurityManager是一个接口,继承了Authenticator, Authorizer, SessionManager这三个接口

Authenticator

Authenticator即认证器,对用户身份进行认证,Authenticator是一个接口,shiro提供ModularRealmAuthenticator实现类,通过ModularRealmAuthenticator基本上可以满足大多数需求,也可以自定义认证器

Authorizer

Authorizer即授权器,用户通过认证器认证通过,在访问功能时需要通过授权器判断用户是否有此功能的操作权限

Realm

Realm即领域,相当于datasource数据源,securityManager进行安全认证需要通过Realm获取用户权限数据,比如:如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息

不要把realm理解成只是从数据源取数据,在realm中还有认证授权校验的相关的代码

SessionManager

sessionManager即会话管理,shiro框架定义了一套会话管理,它不依赖web容器的session,所以shiro可以使用在非web应用上,也可以将分布式应用的会话集中在一点管理,此特性可使它实现单点登录

SessionDAO

SessionDAO即会话dao,是对session会话操作的一套接口,比如要将session存储到数据库,可以通过jdbc将会话存储到数据库

CacheManager

CacheManager即缓存管理,将用户权限数据存储在缓存,这样可以提高性能

Cryptography

Cryptography即密码管理,shiro提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。

Shiro中的认证

什么是认证

身份认证,就是判断一个用户是否为合法用户的处理过程。最常用的简单身份认证方式是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确

三个概念

Subject

访问系统的用户,主体可以是用户、程序等,进行认证的都称为主体

Principal

身份信息,是主体(subject)进行身份认证的标识,标识必须具有唯一性,如用户名、手机号、邮箱地址等,一个主体可以有多个身份,但是必须有一个主身份(Primary Principal)

credential

凭证信息,是只有主体自己知道的安全信息,如密码、证书等

Shiro的工作流程

1、Subject 登录:

  • 用户通过提供凭据(通常是用户名和密码)创建一个 AuthenticationToken 对象,然后调用 Shiro 的 SecurityUtils 或自定义代码的方式将令牌提交给 Shiro。
  • Shiro 接受令牌,然后将其传递给配置的 Realm 进行身份验证。

2、Realm 身份验证:

  • Realm 是一个负责执行身份验证和授权的组件。在 Realm 中,Shiro 将从 AuthenticationToken 中获取主体和凭证。
  • Realm 验证凭证的合法性,如果验证成功,将返回 AuthenticationInfo 对象,其中包括了主体的标识信息。
  • 如果验证失败,将抛出异常通知登录失败。

3、Subject 身份验证:

  • 一旦 Realm 验证成功,Shiro 会创建一个会保存用户的主体信息的额 Subject 对象,表示已经通过身份验证的用户。
  • Subject 对象会保存用户的主体信息,并将用户状态设置为已经登录。

4、授权:

  • 一旦用户成功登录,Shiro 可以通过一组配置的角色和权限规则来授权用户对资源的访问。
  • Subject 可以检查是否具有某个角色或权限,并决定是否允许用户访问资源。
  • 如果用户没有所需的角色或权限,将抛出 AuthorizationException 异常。
  • 在这一步骤中,自定义过滤器将介入,它可以执行额外的逻辑来控制访问,例如,检查用户是否满足特定的自定义条件。
  • 如果自定义过滤器通过验证,用户将被允许访问资源。如果自定义过滤器不通过验证,用户可能被拒绝访问或者需要执行其他操作,例如返回适当的错误消息。

5、会话管理:

  • Shiro 提供会话管理机制,可选地支持 Web 应用程序的会话管理。
  • 会话管理可以包括会话超时、会话验证等功能,确保用户的会话安全。

Shiro、JWT、SpringBoot 项目集成

pom依赖

<!--        引入shiro依赖--> 
<dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.1</version>
        </dependency>
<!-- 避免开启shiro注解冲突--> 
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

shiro配置类

package com.kvteam.backend.config;


import com.kvteam.backend.shiro.MyFilter;
import com.kvteam.backend.shiro.UserRealm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @ClassName : ShiroConfig
 * @Description :
 * @Author : zhangjin
 * @Date: 2023-10-18 13:13
 */
@Configuration
public class ShiroConfig {

    /**
     * ShiroFilter入口来拦截需要安全控制的URL,然后进行相应的控制 然后ShiroFilterFactoryBean就是SpringBoot中用用ShiroFilterFactoryBean 来创建ShiroFilter
     * (创建拦截器)
     * @param defaultWebSecurityManager
     * @return {@link ShiroFilterFactoryBean}
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(defaultWebSecurityManager);
        /*
         * anon:无需认证就可以登录
         * authc:必须认证
         * user:必须拥有记住我这一功能才使用
         * perms:拥有对某个资源的权限才能访问
         * role:用于某个角色权限才能访问
         */
         // 自定义拦截链
        Map<String,Filter> filters=new HashMap<>();
        filters.put("MyFilter", new MyFilter());
        //放入拦截器
        bean.setFilters(filters);
        Map<String, String> filterMap = new LinkedHashMap<String,String>();


        //添加过滤
        filterMap.put("/user/login", "anon");
        filterMap.put("/user/logout","anon");

        //不拦截swagger
        filterMap.put("/swagger-ui.html", "anon");
        filterMap.put("/swagger/**", "anon");
        filterMap.put("/swagger-resources/**", "anon");
        filterMap.put("/v2/**", "anon");
        filterMap.put("/webjars/**", "anon");
        filterMap.put("/configuration/**", "anon");
        filterMap.put("/**", "MyFilter");
        //放入默认的过滤器链条映射
        bean.setFilterChainDefinitionMap(filterMap);
        return bean;
    }

    /**
     *  安全管理器,对全部的subject进行安全管理(根据Realm定义的权限数据来对当前用户进行安全管理(一般就是认证和授权))
     * 安全管理器
     * 创建DefaultWebSecurityManager对象
     *
     * @param
     * @return {@link DefaultWebSecurityManager}
     */
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(UserRealm userRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        return securityManager;
    }


    /** 配置userRealm 相当于datasource数据源,securityManager进行安全认证需要通过Realm获取用户权限数据(根据什么来进行安全管理)
     * @return {@link UserRealm}
     */
    @Bean
    public UserRealm userRealm() {
        return new UserRealm();
    }

    /** 开启shiro权限注解
     * @param defaultWebSecurityManager
     * @return {@link AuthorizationAttributeSourceAdvisor}
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager defaultWebSecurityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(defaultWebSecurityManager);
        return advisor;
    }


}

JWT 的token工具类

package com.kvteam.backend.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

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

/**
 * token 工具类
 */
public class TokenUtil {
    /**
     * token过期时间
     */
    private static final long EXPIRE_TIME = 30 * 60 * 1000;
    /**
     * token秘钥
     */
    private static final String TOKEN_SECRET = "kvteam";


    /**
     * 生成签名,30分钟过期
     * @param username 用户名
     * @param loginTime 登录时间
     * @return 生成的token
     */
    public static String sign(String username, String loginTime) {
        try {
            // 设置过期时间
            Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
            // 私钥和加密算法
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            // 设置头部信息
            Map<String, Object> header = new HashMap<>(2);
            header.put("Type", "Jwt");
            header.put("alg", "HS256");
            // 返回token字符串
            return JWT.create()
                    .withHeader(header)
                    .withClaim("loginName", username)
                    .withClaim("loginTime", loginTime)
                    .withExpiresAt(date)
                    .sign(algorithm);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 检验token是否正确
     * @param token 需要校验的token
     * @return 校验是否成功
     */
    public static boolean verify(String token){
        try {
            //设置签名的加密算法:HMAC256
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            System.out.println(jwt.getClaims().get("loginName").asString());
            return true;
        } catch (Exception e){
            return false;
        }
    }

    /**
     * 获取token中包含的登录用户名
     * @param token 需要校验的token
     * @return 登录用户名
     */
    public static String getLoginName(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            return jwt.getClaims().get("loginName").asString();
        } catch (Exception e){
            return null;
        }
    }
}

Shiro核心组件

Realm代码:

提供自定义的认证和授权条件

package com.kvteam.backend.shiro;

import com.kvteam.backend.entity.UserEntity;
import com.kvteam.backend.service.IUserService;
import com.kvteam.backend.util.TokenUtil;
import lombok.extern.slf4j.Slf4j;
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 javax.annotation.Resource;

/**
 * @ClassName : UserRealm
 * @Description : 用什么来进行安全管理(条件) 作用域,数据源 来具体的认证授权的条件 授权域
 * @Author : zhangjin
 * @Date: 2023-10-18 13:16
 */
@Slf4j
public class UserRealm extends AuthorizingRealm {

    @Resource
    private IUserService userService;

    /**
     * 授权方法  先认证,再授权
     * @param
     * @return {@link AuthorizationInfo}
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        log.info("执行了=》授权doGetAuthenticationInfo");
        //SimpleAuthenticationInfo 获取需要授权的信息 在用户登录后执行,用于确定用户有哪些操作权限。
        //获取当前的
        UserEntity user = (UserEntity) principals.getPrimaryPrincipal();
        log.info("授权:"+user.toString());

        //定义类
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //授权从simpleAuthorizationInfo获取user 再来根据相对应的角色权限来进行授权 根据角色的Role来进行授权
        //添加权限 addStringPermission
        simpleAuthorizationInfo.addStringPermission(user.getRole());

        //返回认证对象
        return simpleAuthorizationInfo;
    }

    /**
     * 认证方法 根据请求头里面的token获取当前的用户信息
     * @param token  认证的核心,就是来比较当前对象和其所对应的的权限来进比较,如果
     * @return {@link AuthenticationInfo}
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //获取当前token的身份信息(前端传来)getPrincipal获取当前身份信息即token
        String accessToken =(String)token.getPrincipal();
        log.info("认证token:"+accessToken);

        //  获取用户名  来解析这个token
        String username = TokenUtil.getLoginName(accessToken);
        log.info(username.toString());
        if(username==null)
        {
            log.info("token失效,用户名为空");
            throw new IncorrectCredentialsException("token失效,请重新登录");
        }
        //如果用户名不为空  根据用户名来查询这个这用户
        UserEntity user = userService.selectByUserName(username);
        if(user==null)
        {  //如果没查到
            log.info("token失效,用户名错误");
            throw new UnknownAccountException("用户不存在");
        }

        //返回一个它的实现类SimpleAuthenticationInfo,将user,token传入它可以自动认证  用于表示身份验证信息,即用于验证用户的身份凭证是否有效
        /*TODO user: 表示已通过身份验证的用户对象,通常包含用户的详细信息,如用户名、密码等。这个对象在认证成功后用于表示已登录的用户。
        *TODO accessToken: 表示用户的身份信息,通常是一个凭证,可以是令牌或者类似的身份验证信息。在这里,accessToken被传递给SimpleAuthenticationInfo以便在后续的Shiro操作中使用。
        *TODO 第三 个参数 ("") 是一个凭证的盐(salt)。盐是一个随机值,用于增加密码的安全性。在这里,它被留空,表示没有使用盐。
        *TODO 这行代码的目的是将user和accessToken关联在一起,并将它们包装在一个SimpleAuthenticationInfo对象中,以便Shiro能够验证用户的身份。当用户成功登录后,Shiro将使用这个SimpleAuthenticationInfo对象来标识已认证的用户,以便后续的授权操作。
        */
        //以便后面获取这user对象
        //  创建简单认证对象
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user,accessToken,"");

        log.info("执行了=》认证doGetAuthenticationInfo");
        return simpleAuthenticationInfo;
    }
}

将Token转化为Shiro的token

package com.kvteam.backend.shiro;

import org.apache.shiro.authc.UsernamePasswordToken;

/**
 * @ClassName : UserToken
 *   这个类的主要目的是将用户的身份信息和凭证信息封装在一个对象中,以便在Shiro身份验证过程中使用。重写为根据token来身份验证
 * @Description : 用户拦截
 * @Author : zhangjin
 * @Date: 2023-10-19 09:21
 */
public class UserToken extends UsernamePasswordToken {
    String token;

    /**构造方法 创建对象
     * @param token
     */
    public UserToken(String token)
    {
        this.token=token;
    }

    /** 获得身份信息 重写为直接返回token  就是重写了getPrincipal方法,因为我们是根据token来证实身份信息
     * @return {@link Object}
     */
    @Override
    public Object getPrincipal() {
        return token;
    }

    /** 获得凭证信息
     * @return {@link Object}
     */
    @Override
    public Object getCredentials() {
        return token;
    }

}

自定义拦截链

package com.kvteam.backend.shiro;


import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.kvteam.backend.util.ResultVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 总之,这个类充当自定义的拦截器,用于处理身份验证和授权逻辑,以及控制受保护资源的访问。它在整合Shiro框架中起到关键作用,确保系统的安全性。
 * @ClassName : MyFilter 验证过滤器
 * @Description : 自定义拦截链
 * @Author : zhangjin
 * @Date: 2023-10-18 18:06
 */
@Slf4j
public class MyFilter extends AuthenticatingFilter {

    /**
     * 用于将字符串转为对象
     */
    Gson gson=new Gson();

    /**
     *
     * 重写获得token的方法,根据请求头来获取token,将JWT生成的token转化为shiro的token
     * @return {@link AuthenticationToken}
     * @throws Exception
     */
    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest=(HttpServletRequest) request;
        String token = httpServletRequest.getHeader("token");
        //根据请求头来获取token,并生成 shiro的AuthenticationToken
        return new UserToken(token);

    }


    /**
     *  只有特定的方法能被允许  方法重写了父类的方法,用于检查是否允许访问受保护的资源。
     *  在这里,它允许"OPTIONS"请求通过,这通常用于跨域请求的预检请求。
     *
     *  这段代码的主要目的是允许"OPTIONS"请求通过,这是一种通常用于跨域请求的预检请求。对于其他类型的请求,返回false,
     *  表示不允许访问受保护的资源,除非它们已经通过了身份验证和授权的检查。
     * @param request
     * @param response
     * @param mappedValue
     * @return boolean
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        //允许option请求通过
        if (((HttpServletRequest) request).getMethod().equals(RequestMethod.OPTIONS.name())) {
            return true;
        }
        return false;
    }

    /**
     * 进行token检查,检查是否为空
     * onAccessDenied(ServletRequest request, ServletResponse response) 方法重写了父类的方法,
     * 用于在访问被拒绝时执行。它检查请求头中的"token"是否为空,如果为空,则返回一个未认证的响应,提示客户端需要先登录。
     * 如果"token"不为空,它会执行executeLogin方法,尝试进行身份验证。
     * @param request
     * @param response
     * @return boolean
     * @throws Exception
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest=(HttpServletRequest) request;
        HttpServletResponse httpServletResponse=(HttpServletResponse) response;
        //获取请求token
        String token=httpServletRequest.getHeader("token");
        //如果请求为空
        log.info("进入了+》拦截器------");
        log.info("token为"+token);
        //判断是否为空
        if(StringUtils.isBlank(token))
        {
            //设置了响应头,允许跨域请求并携带凭证(如Cookies)。
            httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
            httpServletResponse.setHeader("Access-Control-Allow-Origin",httpServletRequest.getHeader("Origin") );
            //设置响应的字符编码为UTF-8。
            httpServletResponse.setCharacterEncoding("UTF-8");
            //token为空 提示先进行登录
            JSONObject json = new JSONObject();
            json.put("code","401");
//          gson.toJson(ResultVo.fail("请先登录"))
            httpServletResponse.getWriter().append(json.toJSONString());
//           httpServletResponse.getWriter().write(gson.toJson(ResultVo.fail("请重新登录")));
            return false;
        }
        //执行验证方法
        /*
        Shiro框架会尝试根据request中的信息进行身份验证。在你的自定义拦截器中,这一步通常是在检查请求头中的"token"后,
        如果"token"不为空,就会调用executeLogin来触发Shiro执行身份验证。如果验证成功,用户将被认为是已经登录,
        并可以访问受保护的资源。如果验证失败,将会执行相应的错误处理逻辑。
        用于启动Shiro的身份验证过程的方法,它允许你在自定义的拦截器中触发用户身份验证。
        * */
        //通过之后执行登录认证方法
        return executeLogin(request,response);
    }


    /**
     * 重写AuthenticationException,用全局处理异常进行处理,否则市默认返回login.jsp
     * @param token
     * @param e
     * @param request
     * @param response
     * @return boolean
     */
    @Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
        HttpServletRequest httpServletRequest= (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setContentType("application/json;charset=utf-8");
        httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
        httpResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("Origin"));
        httpResponse.setCharacterEncoding("UTF-8");
        log.info("进入了认证+》----------");

        try {
            //处理登录失败的异常,如果引发异常的原因 ,
            //获取登录失败引发的异常,通常用于确定登录失败的原因。如果e中存在cause,则获取cause,否则获取e本身。
            Throwable throwable;
            if (e.getCause() == null) {
                throwable = e;
            } else {
                throwable = e.getCause();
            }
            JSONObject json = new JSONObject();
            json.put("code","402");
            httpResponse.getWriter().write(gson.toJson(ResultVo.fail("登录凭证已失效,请重新登录")));
        } catch (IOException e1) {
            log.info(e1.toString());
        }
        return false;
    }

}

Controller层

具体的业务逻辑

package com.kvteam.backend.controller;

import com.alibaba.fastjson.JSONObject;
import com.kvteam.backend.dto.RegisterDto;
import com.kvteam.backend.dto.UserDto;
import com.kvteam.backend.entity.LogEntity;
import com.kvteam.backend.entity.UserEntity;
import com.kvteam.backend.service.ILogService;
import com.kvteam.backend.service.IUserService;
import com.kvteam.backend.util.ResultVo;
import com.kvteam.backend.util.TokenUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * @Author: zahngjin
 * @Description:
 * @Date: 2023/10/17 11:13
 */
@RestController
@Slf4j
@CrossOrigin
@Api(value = "用户 API 接口",tags = "用户 API 接口")
@RequestMapping("/user")
public class UserController {

    @Resource
    private IUserService userService;

    @Resource
    private ILogService logService;


    /**
     *  登录方法
     * @param userDto
     * @return {@link ResultVo}<{@link String}>
     */
    @ApiOperation("用户登录")
    @PostMapping("/login")
    public ResultVo<String> login(@RequestBody UserDto userDto)
    {
        log.info("login");
        log.info(userDto.toString());
        UserEntity user = userService.selectByUserName(userDto.getName());

        if (user == null) {
            return ResultVo.fail("账号错误");
        } else if (!userService.hash(userDto.getPassword(),user.getSalt()).equals(user.getPassword())) {
            //根据user的salt再进行加密,再来对输入的密码进行加密,来匹配师傅与数据库的密码是否一样
            return ResultVo.fail("密码错误");
        } else {
            //生成token
            String token= TokenUtil.sign(userDto.getName(),String.valueOf(System.currentTimeMillis()));
            String name = userDto.getName();
            UserEntity userEntity = userService.selectByUserName(name);

            LogEntity logEntity = new LogEntity(userEntity.getId(),name,null,null);
            logService.loginLog(logEntity);
            return ResultVo.success(token);
        }
    }


    /**
     * 查询所有用户
     * @param
     * @return {@link ResultVo}<{@link List}<{@link UserEntity}>>
     */
    @ApiOperation("查询所有用户")
    @RequiresPermissions("SUPER_ADMIN")
    @GetMapping ("/selectAll/{pageNum}")
    public ResultVo<List<UserEntity>> selectAll(@PathVariable("pageNum") int pageNum)
    {
        log.info("pageNum:"+pageNum);
        List<UserEntity> userEntities = userService.selectAll(pageNum);
        return ResultVo.success(userEntities);
    }


    /**
     * 添加用户
     * @param registerDto
     * @return {@link ResultVo}<{@link String}>
     */
    @ApiOperation("添加新用户")
    @RequiresPermissions("SUPER_ADMIN")
    @PostMapping("/insert")
    public ResultVo<String> insertUser(@RequestBody RegisterDto registerDto)
    {
        boolean result = userService.insertUser(registerDto);
        if(result)
        {
            return ResultVo.success("添加成功");
        }
        return ResultVo.fail("添加失败");
    }


    /**
     * 修改用户角色和密码
     * @param userEntity
     * @return {@link ResultVo}<{@link String}>
     */
    @ApiOperation("更新用户信息")
    @RequiresPermissions("SUPER_ADMIN")
    @PutMapping("/update")
    public ResultVo<String> updateUser(@RequestBody UserEntity userEntity)
    {
        boolean result = userService.updateUser(userEntity);
        if(result)
        {
            return ResultVo.success("更新成功");
        }
        return ResultVo.fail("更新失败");
    }

    /**
     * 根据role查询
     * @param role
     * @return {@link ResultVo}<{@link UserEntity}>
     */
    @ApiOperation("按照权限查询用户")
    @RequiresPermissions("SUPER_ADMIN")
    @PutMapping("/selectRole/{pageNum}")
    public ResultVo<List<UserEntity>> selectUserByRole(@PathVariable("pageNum") int pageNum,@RequestBody String role)
    {
        log.info("pageNum:"+pageNum);
        log.info("role-----"+role);
        JSONObject parse = JSONObject.parseObject(role);
        role =(String)parse.get("role");
        List<UserEntity> userEntity = userService.selectByUserRole(role,pageNum);
        if(userEntity!=null)
        {
            return ResultVo.success(userEntity);
        }
        return ResultVo.fail(null);
    }

}

posted @ 2023-10-25 09:26  粹白  阅读(24)  评论(0编辑  收藏  举报