springboot整合Shiro

1.shiro是什么

Shiro是Apache下的一个开源项目。shiro属于轻量级框架,相对于SpringSecurity简单的多,也没有SpringSecurity那么复杂。以下是我自己学习之后的记录。
官方架构图如下:官方架构图

2.主要功能

shiro主要有三大功能模块:

  1. Subject:主体,一般指用户。
  2. SecurityManager:安全管理器,管理所有Subject,可以配合内部安全组件。(类似于SpringMVC中的DispatcherServlet)
  3. Realms:用于进行权限信息的验证,一般需要自己实现。

3.细分功能

1. Authentication:身份认证/登录(账号密码验证)。
2. Authorization:授权,即角色或者权限验证。
3. Session Manager:会话管理,用户登录后的session相关管理。
4. Cryptography:加密,密码加密等。
5. Web Support:Web支持,集成Web环境。
6. Caching:缓存,用户信息、角色、权限等缓存到如redis等缓存中。
7. Concurrency:多线程并发验证,在一个线程中开启另一个线程,可以把权限自动传播过去。
8. Testing:测试支持;
9. Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问。
10. Remember Me:记住我,登录后,下次再来的话不用登录了。
(更多关于shiro是什么的文字请自行去搜索引擎找,本文主要记录springboot与shiro的集成)
首先先创建springboot项目,此处不过多描述。

**

上代码:

目录结构

在这里插入图片描述
目录结构

pom.xml:

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>
        <!-- msyql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- redis 缓存数据库-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- commons-lang3 工具包-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-all</artifactId>
            <version>1.4.2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.shiro</groupId>
                    <artifactId>shiro-quartz</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Account实体类(用户对应实体类):

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.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("account")
public class Account implements Serializable {

    @TableId(type = IdType.AUTO)
    private Integer accid;
    @TableField
    private String accname;
    @TableField
    private String accpass;
    @TableField
    private String accstate;

}

Permissions.java(权限对应实体类):

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

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("permission")
public class Permission implements Serializable {

    @TableId
    private Integer pid;
    @TableField
    private String pname;
    @TableField
    private String code;
   

}

Role实体类(角色应实体类):

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

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("role")
public class Role implements Serializable {

    @TableId
    private Integer rid;
    @TableField
    private String rname;
    @TableField
    private String remark;


}

ShiroConfig配置类:

import com.sykj.realm.MyRealm;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
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.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.LinkedHashMap;
import java.util.Map;

/**
 * shiro配置类
 */
@Configuration
public class ShiroConfig {
    //1. realm对象注入
    @Bean
    public MyRealm myRealm(){
        MyRealm myRealm=new MyRealm();
        //设置加密方式
        myRealm.setCredentialsMatcher(hashedCredentialsMatcher());
//        //配置自定义密码比较器
//        myRealm.setCredentialsMatcher(retryLimitHashedCredentialsMatcher());
        return myRealm;
    }

    /*
     * @describe 自定义凭证匹配器 配置密码比较器
     * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了所以我们需要修改下doGetAuthenticationInfo中的代码)
     * 可以扩展凭证匹配器,实现输入密码错误次数后锁定等功能
     * @return org.apache.shiro.authc.credential.HashedCredentialsMatcher
     */
    @Bean(name = "credentialsMatcher")
    public CustomerMatcher hashedCredentialsMatcher() {
        CustomerMatcher hashedCredentialsMatcher = new CustomerMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");//散列算法:这里使用MD5算法;
        hashedCredentialsMatcher.setHashIterations(1024);//散列的次数,比如散列两次,相当于 md5(md5(""));
        //storedCredentialsHexEncoded默认是true,此时用的是密码加密用的是Hex编码;false时用Base64编码
        // hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
        return hashedCredentialsMatcher;
    }



    //2. securityManager安全管理器注入
    //2.安全管理器
    @Bean
    public SecurityManager securityManager(HashedCredentialsMatcher hashedCredentialsMatcher){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        securityManager.setRealm(myRealm());
//        //配置 ehcache缓存管理器 参考博客:
//        securityManager.setCacheManager(ehCacheManager());
        return securityManager;
    }
    //3. shiro过滤器配置
    @Bean
    public ShiroFilterFactoryBean factory(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //登录认证不通过跳转的url
        shiroFilterFactoryBean.setLoginUrl("/user/loginError");
        //功能权限不足跳转个URL
        shiroFilterFactoryBean.setUnauthorizedUrl("/user/unAuthError");

        Map map=new LinkedHashMap();
        map.put("/user/login","anon");//放行,允许不登录就直接访问,不拦截
        map.put("/user/loginError","anon");
        map.put("/user/unAuthError","anon");
        map.put("/**","authc");//登录拦截器


        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }
    //4. shiro注解开启
    /**
     * 开启aop注解支持
     * 即在controller中使用 @RequiresPermissions("user/userList")
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor attributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        //设置安全管理器
        attributeSourceAdvisor.setSecurityManager(securityManager);
        return attributeSourceAdvisor;
    }

    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        defaultAAP.setProxyTargetClass(true);
        return defaultAAP;
    }
}

MyRealm (登录认证、权限鉴权的验证类 )
此类为自定义类

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sykj.bean.Account;
import com.sykj.bean.Permission;
import com.sykj.bean.Role;
import com.sykj.service.AccountService;
import com.sykj.service.PermissionService;
import com.sykj.service.RoleService;
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.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

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

public class MyRealm extends AuthorizingRealm {
    @Autowired
    private AccountService accountService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private PermissionService permissionService;
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 巨坑 建议重写
     * @param token
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }

    /**
     * 权限认证
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("开始权限认证---------------------");

//          Account account= (Account) principalCollection.getPrimaryPrincipal();//取出用户登录信息
        Account account= (Account) principalCollection.getPrimaryPrincipal();//登陆成功保存的用户信息
        System.out.println(account);
          //调用服务层方法获取该用户的所有角色信息
           List<Role> roles=roleService.queryRoles(account.getAccid());
           //保存角色信息  用set集合 保证去重复
        Set<String> roleSet=new HashSet<>();
        //保存资源信息
        Set<String> permssionSet=new HashSet<>();
           //判断redis上是否存在key   存放角色和权限信息
           if(redisTemplate.hasKey("account:roleAndPermission:"+account.getAccid())){
               System.out.println("从redis中取出数据----------------->>>>>>>>>>>>>>>>>>>>>.");
               //取出角色信息
             roleSet= (Set<String>) redisTemplate.opsForHash().get("account:roleAndPermission:"+account.getAccid(),"roles");
             //取出权限信息
             permssionSet= (Set<String>) redisTemplate.opsForHash().get("account:roleAndPermission:"+account.getAccid(),"permission");
           }else{
               System.out.println("向redis中存放数据-----------。》》》》》》》》》》》》》");
               for(Role role:roles){
                   roleSet.add(role.getRname());
                   List<Permission> permissions=permissionService.querypermiss(role.getRid());
                   for (Permission permission:permissions){
                       permssionSet.add(permission.getCode());
                   }
               }
               //向redis中存放数据  角色 和权限信息
               redisTemplate.opsForHash().put("account:roleAndPermission:"+account.getAccid(),"roles",roleSet);
               redisTemplate.opsForHash().put("account:roleAndPermission:"+account.getAccid(),"permission",permssionSet);
           }
    SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();//保存用户的角色和权限信息
         info.addRoles(roleSet);
         info.addStringPermissions(permssionSet);
        return info;
    }

    /**
     *
     * 登录认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("-------------登录认证");
        UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;
        String accname=token.getUsername();
        QueryWrapper wrapper=new QueryWrapper();
        wrapper.eq("accname",accname);
       Account account=  accountService.getOne(wrapper);
          if (account==null){
           throw  new  UnknownAccountException();
          }
          if (account.getAccstate().equals("0")){
               throw new LockedAccountException("账号被锁定,请及时联系管理员。");
          }
            //加盐并编码
          ByteSource salt = ByteSource.Util.bytes("sykj");
        System.out.println("=================================");
        System.out.println(account.getAccpass());
          SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(account,account.getAccpass(),salt,getName());
        return info;
    }

}

Aes 加密解密工具类

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;


/*****************************************************
 * AES加密解密工具
 ****************************************************/

public class AesUtil {


	private static final String ALGORITHM = "AES/ECB/PKCS5Padding";    //"算法/模式/补码方式"

	/*****************************************************
	 * AES加密
	 * @param content 加密内容
	 * @param key 加密密码,由字母或数字组成
	此方法使用AES-128-ECB加密模式,key需要为16位
	加密解密key必须相同,如:abcd1234abcd1234
	 * @return 加密密文
	 ****************************************************/

	public static String enCode(String content, String key) {
		if (key == null || "".equals(key)) {

			System.out.println("key为空!");
			return null;
		}
		if (key.length() != 16) {
			System.out.println("key长度不是16位!");
			return null;
		}
		try {
			byte[] raw = key.getBytes();  //获得密码的字节数组
			SecretKeySpec skey = new SecretKeySpec(raw, "AES"); //根据密码生成AES密钥
			Cipher cipher = Cipher.getInstance(ALGORITHM);  //根据指定算法ALGORITHM自成密码器
			cipher.init(Cipher.ENCRYPT_MODE, skey); //初始化密码器,第一个参数为加密(ENCRYPT_MODE)或者解密(DECRYPT_MODE)操作,第二个参数为生成的AES密钥
			byte [] byte_content = content.getBytes("utf-8"); //获取加密内容的字节数组(设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
			byte [] encode_content = cipher.doFinal(byte_content); //密码器加密数据
			return Base64.encodeBase64String(encode_content); //将加密后的数据转换为字符串返回
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/*****************************************************
	 * AES解密
	 * @param content 加密密文
	 * @param key 加密密码,由字母或数字组成
	此方法使用AES-128-ECB加密模式,key需要为16位
	加密解密key必须相同
	 * @return 解密明文
	 ****************************************************/

	public static String deCode(String content, String key) {
		if (key == null || "".equals(key)) {
			System.out.println("key为空!");
			return null;
		}
		System.out.println(key.length()+"--------->>>>>");
		if (key.length() != 16) {
			System.out.println("key长度不是16位!");
			return null;
		}
		try {
			byte[] raw = key.getBytes();  //获得密码的字节数组
			SecretKeySpec skey = new SecretKeySpec(raw, "AES"); //根据密码生成AES密钥
			Cipher cipher = Cipher.getInstance(ALGORITHM);  //根据指定算法ALGORITHM自成密码器
			cipher.init(Cipher.DECRYPT_MODE, skey); //初始化密码器,第一个参数为加密(ENCRYPT_MODE)或者解密(DECRYPT_MODE)操作,第二个参数为生成的AES密钥
			byte [] encode_content = Base64.decodeBase64(content); //把密文字符串转回密文字节数组
			byte [] byte_content = cipher.doFinal(encode_content); //密码器解密数据
			return new String(byte_content,"utf-8"); //将解密后的数据转换为字符串返回
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/*****************************************************
	 * AES加密解密测试
	 * @param args
	 * @return
	 ****************************************************/
//	public static void main(String[] args) {
//		String salt="dufy20119329java";
//		String accpass= AesUtil.deCode("OWm2wB8ibExxGF7eZC0l/l7HjRsG5qNUbx02+j7gd7dzpFwj+Fj4lC5aOeFYTwEI",salt);
//		System.out.println(accpass);
//	}

}

全局异常处理类

import com.sykj.util.ResponseResult;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局异常处理类
 */
@RestControllerAdvice
public class CustomExceptionAdvice {

    @ExceptionHandler(UnknownAccountException.class)
    public ResponseResult xxx(UnknownAccountException e){
        return new ResponseResult(-1000,"账号不存在,请重新输入",null);
    }

   @ExceptionHandler(IncorrectCredentialsException.class)
    public  ResponseResult password(IncorrectCredentialsException e){
        return new ResponseResult(-1001,"密码错误,请重新输入",null);
   }

    @ExceptionHandler(ClassCastException.class)
    public  ResponseResult password(ClassCastException e){
        return new ResponseResult(-1024,e.getMessage(),null);
    }

    @ExceptionHandler(UnauthorizedException.class)
    public ResponseResult aa(UnauthorizedException e){
        return new ResponseResult(-1000,"权限不足,亲联系管理员",null);
    }

    @ExceptionHandler(LockedAccountException.class)
    public ResponseResult zzz(LockedAccountException e){
        System.out.println("===============================================");
        return new ResponseResult(-1002,e.getMessage(),null);
    }

    @ExceptionHandler(ExcessiveAttemptsException.class)
    public ResponseResult eee(ExcessiveAttemptsException e){
        return new ResponseResult(-1003,e.getMessage(),null);
    }


}

服务器响应类

import java.io.Serializable;

/**
 * 服务器响应类
 */
public class ResponseResult implements Serializable {

    private int code;
    private String message;
    private Object data;

    public ResponseResult(int code, String message, Object data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public ResponseResult() {
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

AccountService类

import com.baomidou.mybatisplus.extension.service.IService;
import com.sykj.bean.Account;

public interface AccountService extends IService<Account> {
}

AccountServiceImpl类

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sykj.bean.Account;
import com.sykj.mapper.AccountMapper;
import com.sykj.service.AccountService;
import org.springframework.stereotype.Service;

@Service
public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> implements AccountService {
}

PermissionService类

import com.baomidou.mybatisplus.extension.service.IService;
import com.sykj.bean.Permission;

import java.util.List;

public interface PermissionService extends IService<Permission> {
    public List<Permission> querypermiss(Integer rid);
}

PermissionServiceImpl类

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.sykj.bean.Permission;
import com.sykj.mapper.PermissionMapper;
import com.sykj.service.PermissionService;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    public List<Permission> querypermiss(Integer rid) {
        return this.baseMapper.querypermiss(rid);
    }
}

Permission.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sykj.mapper.PermissionMapper">
    <select id="querypermiss"  parameterType="integer" resultType="com.sykj.bean.Permission">
        SELECT p.*
       FROM role_permission rp,permission p
        where rp.pid=p.pid and rp.rid=#{rid}

    </select>
</mapper>

RoleService类

import com.baomidou.mybatisplus.extension.service.IService;
import com.sykj.bean.Role;

import java.util.List;

public interface RoleService extends IService<Role> {
    public List<Role> queryRoles(Integer accid);
}

RoleServiceImpl类

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sykj.bean.Role;
import com.sykj.mapper.RoleMapper;
import com.sykj.service.RoleService;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Override
    public List<Role> queryRoles(Integer accid) {
        return this.baseMapper.queryRoles(accid);
    }
}

Role.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sykj.mapper.RoleMapper">
    <select id="queryRoles" parameterType="integer" resultType="com.sykj.bean.Role">
        select r.* from account_role ar,role r where  r.rid=ar.rid and ar.accid=#{accid}
    </select>
</mapper>

AccountController

import com.sykj.util.ResponseResult;
import com.sykj.util.AesUtil;
import com.sykj.util.NoRepeatSubmit;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.*;

@CrossOrigin
@RestController
public class AccountController {



    @RequestMapping("/user/login")
    public ResponseResult login(@RequestParam("username") String username,@RequestParam("password")  String password){
        Subject subject= SecurityUtils.getSubject();//用户主体
        System.out.println(password+"......>>>>>>>>>>>>>>>>>>>>>>>>>>>...");
        String password1=AesUtil.deCode(password,"sykj123456789111");
        System.out.println(password1+"===========");
        UsernamePasswordToken token=new UsernamePasswordToken(username,password1);
            subject.login(token);//流程走向Realm

             return  new ResponseResult(1000,"登陆成功",null);
    }


      @GetMapping("user/delete")
    public ResponseResult delete(){
        return new ResponseResult(1000,"删除成功",null);
      }
    
    @GetMapping("user/save")
    public ResponseResult save(){
        return new ResponseResult(1000,"添加成功",null);
    }

   
    @GetMapping("user/query")
    public ResponseResult query(){
        return new ResponseResult(1000,"查询成功",null);
    }

    @GetMapping("user/update")
    public ResponseResult update(){
        return new ResponseResult(1000,"修改成功",null);
    }

}

原文链接:https://blog.csdn.net/weixin_45289031/article/details/108142998

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值