目录
后端技术点
- springboot
- shiro
- mybatisplus
- mysql
- shiro-redis
流程
后端大概要做这么一件事儿,在没有数据库的情况下,先学会使用shiro,然后在项目中使用数据库查询用户和权限,接着再是整合redis作为shiro的缓存。我在最后才进行的密码加密,防止忘记密码而登录不上:( .
shiro介绍
Apache Shiro是一个功能强大且易于使用的Java安全框架,可执行身份验证、授权、加密和会话管理。使用Shiro易于理解的API,您可以快速轻松地保护任何应用程序-从最小的移动应用程序到最大的web和企业应用程序。
架构图
Subject:它可以表示调用应用程序的外部进程,代表了当前与软件交互的实体,这个实体不一定是一个具体的人,与当前应用交互的任何东西都是Subject。
SecurityManager:SecurityManager是Shiro架构的核心,主要协调其托管组件,
包括:身份认证,授权,会话管理,缓存管理,realms,主体创建,注销等等
所有具体的交互都通过 SecurityManager 进行控制;
Authenticator:认证器,是负责执行和响应用户的身份验证(登录)的组件。当用户试图登录时,Authenticator将执行该逻辑。
Authorizer:授权器,负责决定用户在应用程序中的访问控制的组件,即控制着用户能访问应用中的哪些功能。
Realms:相当于数据源,通过realm存取认证、授权相关数据,可以是 JDBC 实现,或者内存实现等等;由用户提供;注意:Shiro 不知道你的用户 / 权限存储在哪及以何种格式存储;所以我们一般在应用中都需要实现自己的 Realm;
SessionManger:web应用中一般是用web容器(中间件tomcat)对session进行管理,shiro也提供一套session管理的方式。shiro不仅仅可以用于web管理也可以用于cs管理,所以他不用web容器的session管理。
SessionDao:用于SessionManager执行会话持久化(CRUD)操作。这允许将任何数据存储插入到SessionManagement基础设施中。比如我们想把session信息保存到数据库,或者保存到redis缓存中
CacheManager:用于创建和管理Shiro组件使用的缓存实例生命周期。因为Shiro可以访问许多后端数据源来进行身份验证、授权和会话管理,所以可以把这些数据存储到缓存中,可以在使用这些数据源时提高性能。任何现代缓存产品都可以插入到Shiro中,以提供快速高效的用户体验。
Cryptography:加密模块,Shiro 提供了一些常见的加密组件用于如密码加密 / 解密的。
最简单的一个实例
创建springboot项目
选择基本依赖
忘记截图了,大概就是先选了
spring-boot-starter-web,lombok,
springboot 2.6.10
完整依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</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>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.5.3</version>
</dependency>
</dependencies>
注意:引入shiro-spring-boot-starter.jar 之后 必须实现realms,否则启动会报错
创建shiro基本配置
新建config.shiro.ShiroRealm 继承AuthorizingRealm,实现身份认证和授权方法
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class ShiroRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
/**
* 认证
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//如果用户名密码 是 zhangsan 123 认证通过
String userName = (String) token.getPrincipal();
if(userName.equals("zhangsan")){
return new SimpleAuthenticationInfo(userName,"123",this.getName());
}
return null;
}
}
创建ShiroConfig.java,将自己实现的认证授权方法注入到SecurityManager中,
import org.apache.shiro.mgt.SessionsSecurityManager;
import org.apache.shiro.realm.Realm;
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;
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(getSessionsSecurityManager());
return shiroFilterFactoryBean;
}
@Bean
public SessionsSecurityManager getSessionsSecurityManager(){
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(getRealm());
return defaultWebSecurityManager;
}
@Bean
public Realm getRealm(){
ShiroRealm shiroRealm = new ShiroRealm();
return shiroRealm;
}
}
创建控制器,测试登录时是否调用自己实现的认证方法
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 前端控制器
* </p>
*
* @author ff
* @since 2022-08-05
*/
@RestController
@RequestMapping("/system/user/")
public class UserController {
/**
* 登录方法
* @param userName
* @param passWord
* @return
*/
@GetMapping("login")
public String login(String userName,String passWord){
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userName, passWord);
subject.login(usernamePasswordToken);
return "sucess";
}
}
访问地址
http://localhost:8080/system/user/login?userName=zhangsan&passWord=123
你可以分别测试userName和passWord错误的情况
用户名不存在情况下后台报错,UnknownAccountException
密码错误情况下后台报错,.IncorrectCredentialsException
知道这两个异常代表的信息,我们就可以在全局异常中处理这两个异常,然后向前端项目返回不同的错误信息。
然后就是授权信息
package com.han.springbootshiro.config.shiro;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class ShiroRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//主身份信息
String primaryPrincipal = (String) principals.getPrimaryPrincipal();
System.out.println(primaryPrincipal);
//暂时写成这样,后边都是从数据库查
if(primaryPrincipal.equals("zhangsan")){
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.addStringPermission("table");
simpleAuthorizationInfo.addStringPermission("list");
return simpleAuthorizationInfo;
}
return null;
}
/**
* 认证
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//如果用户名密码 是 zhangsan 123 认证通过
String userName = (String) token.getPrincipal();
if(userName.equals("zhangsan")){
return new SimpleAuthenticationInfo(userName,"123",this.getName());
}
return null;
}
}
接下来就是数据库,从数据库中查询用户名密码,权限信息
数据库表结构,就是用户关联角色,角色关联权限
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `t_permission`
-- ----------------------------
DROP TABLE IF EXISTS `t_permission`;
CREATE TABLE `t_permission` (
`id` varchar(40) NOT NULL,
`permission_code` varchar(100) NOT NULL,
`permission_name` varchar(100) NOT NULL,
`description` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of t_permission
-- ----------------------------
INSERT INTO `t_permission` VALUES ('1', 'table', 'table', 'table');
INSERT INTO `t_permission` VALUES ('2', 'project:manger', '项目管理', null);
INSERT INTO `t_permission` VALUES ('3', 'project:apply', '项目申请', null);
INSERT INTO `t_permission` VALUES ('4', 'project:review', '项目审核', null);
-- ----------------------------
-- Table structure for `t_role`
-- ----------------------------
DROP TABLE IF EXISTS `t_role`;
CREATE TABLE `t_role` (
`id` varchar(40) NOT NULL,
`role_name` varchar(50) NOT NULL,
`role_description` varchar(100) DEFAULT NULL,
`role_code` varchar(40) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of t_role
-- ----------------------------
INSERT INTO `t_role` VALUES ('1', '管理员', 'admin', 'admin');
INSERT INTO `t_role` VALUES ('7b5c86242b02e2efd237dc1d00699654', '大王', null, 'big-boss');
INSERT INTO `t_role` VALUES ('7cbfa3f3164e8371cef3139f2c293086', '小王', null, 'little-boss');
-- ----------------------------
-- Table structure for `t_role_permission`
-- ----------------------------
DROP TABLE IF EXISTS `t_role_permission`;
CREATE TABLE `t_role_permission` (
`id` varchar(40) NOT NULL,
`role_id` varchar(40) NOT NULL,
`permission_id` varchar(40) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of t_role_permission
-- ----------------------------
INSERT INTO `t_role_permission` VALUES ('0ba22b3cb9cb785fd805c8c6f29cb13d', '7b5c86242b02e2efd237dc1d00699654', '4');
INSERT INTO `t_role_permission` VALUES ('1f0d31b82cd7c953b08a8f4ab6477caa', '7cbfa3f3164e8371cef3139f2c293086', '2');
INSERT INTO `t_role_permission` VALUES ('53aeecca8ef33a514dba522fe3cb9e71', '1', '1');
INSERT INTO `t_role_permission` VALUES ('7fedc00f7cc73b8dd7783acaf720f079', '7cbfa3f3164e8371cef3139f2c293086', '2');
INSERT INTO `t_role_permission` VALUES ('a5bc83b9996543833a29970febb7b9c3', '1', '2');
INSERT INTO `t_role_permission` VALUES ('af88373c01e942c59aeeed634b89f79a', '1', '3');
INSERT INTO `t_role_permission` VALUES ('af8fa05c0c4a6233197d4da039b1ae4b', '1', '4');
INSERT INTO `t_role_permission` VALUES ('bc6fc74acdfd0ff9720fedc7080f927e', '7cbfa3f3164e8371cef3139f2c293086', '3');
INSERT INTO `t_role_permission` VALUES ('d8f7df408072482d775d66c540f3da40', '7b5c86242b02e2efd237dc1d00699654', '2');
INSERT INTO `t_role_permission` VALUES ('e16972e920060ce5d3a2ea9f263e7f46', '7cbfa3f3164e8371cef3139f2c293086', '3');
-- ----------------------------
-- Table structure for `t_user`
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`id` varchar(40) NOT NULL,
`username` varchar(40) NOT NULL,
`password` varchar(40) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES ('admin', 'zhangsan', '123');
-- ----------------------------
-- Table structure for `t_user_role`
-- ----------------------------
DROP TABLE IF EXISTS `t_user_role`;
CREATE TABLE `t_user_role` (
`id` varchar(40) NOT NULL,
`user_id` varchar(40) NOT NULL,
`role_id` varchar(40) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of t_user_role
-- ----------------------------
INSERT INTO `t_user_role` VALUES ('10909720e9211f6c8dec1ca8996b217f', '73e38603d03c01a048bebb91dceb6934', '7cbfa3f3164e8371cef3139f2c293086');
INSERT INTO `t_user_role` VALUES ('2b132d18fa2f51f83712dcf65c75c318', 'bigboos', '7b5c86242b02e2efd237dc1d00699654');
INSERT INTO `t_user_role` VALUES ('3', 'admin', '1');
INSERT INTO `t_user_role` VALUES ('59d3d04356c7010aa253716fe7f1edfe', 'afd43117bfc24eb289710329999c49dc', '7b5c86242b02e2efd237dc1d00699654');
INSERT INTO `t_user_role` VALUES ('6708c5ea667ee1b8c59908a3d08a4e0d', 'little', '7cbfa3f3164e8371cef3139f2c293086');
配置项目数据库信息
导入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!-- druid依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.0</version>
</dependency>
<!-- mybatisPlus 核心库 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
application.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/myapp?serverTimezone=GMT%2B8&useSSL=FALSE
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.han.myapp.model
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
然后就是mapper,service,这个我都是逆向生成的,大家可以去网上找下工具,
主要需要自己编写的方法是通过用户id查询角色信息和通过角色id查询权限信息,这个都很简单,直接粘一下实现类
RoleServiceImpl.java
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.han.springbootshiro.mapper.RoleMapper;
import com.han.springbootshiro.model.Role;
import com.han.springbootshiro.model.UserRole;
import com.han.springbootshiro.service.IRoleService;
import com.han.springbootshiro.service.IUserRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author
* @since 2022-08-05
*/
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {
@Autowired
private IUserRoleService userRoleService;
@Override
public List<Role> getRolesByUserId(String id) {
//查询 用户 角色 关联表 Userrole
LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(UserRole::getUserId,id);
List<UserRole> userRoleList = userRoleService.list(queryWrapper);
if(userRoleList.size()==0){
return null;
}
//获取角色ID
List<String> roleIds = userRoleList.stream().map(item -> item.getRoleId()).collect(Collectors.toList());
List<Role> roles = this.listByIds(roleIds);
return roles;
}
}
PermissionServiceImpl.java
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.han.springbootshiro.mapper.PermissionMapper;
import com.han.springbootshiro.model.Permission;
import com.han.springbootshiro.model.RolePermission;
import com.han.springbootshiro.service.IPermissionService;
import com.han.springbootshiro.service.IRolePermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author ff
* @since 2022-08-05
*/
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements IPermissionService {
@Autowired
private IRolePermissionService rolePermissionService;
@Override
public List<Permission> getPermissionsByroleId(List<String> roleIds) {
//查询 角色 权限 关系表
LambdaQueryWrapper<RolePermission> rolePermissionLambdaQueryWrapper = new LambdaQueryWrapper<>();
rolePermissionLambdaQueryWrapper.in(RolePermission::getRoleId,roleIds);
List<RolePermission> rolePermissions = rolePermissionService.list(rolePermissionLambdaQueryWrapper);
if(rolePermissions.size()==0){
return null;
}
List<String> permissionIds = rolePermissions.stream().map(item -> item.getPermissionId()).collect(Collectors.toList());
//根据权限id 查询 权限信息
List<Permission> permissions = this.listByIds(permissionIds);
return permissions;
}
}
还有就是realms,通过数据库查询用户信息和角色权限信息
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.han.springbootshiro.model.Permission;
import com.han.springbootshiro.model.Role;
import com.han.springbootshiro.model.User;
import com.han.springbootshiro.service.IPermissionService;
import com.han.springbootshiro.service.IRoleService;
import com.han.springbootshiro.service.IUserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
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.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import java.util.stream.Collectors;
public class ShiroRealm extends AuthorizingRealm {
@Autowired
private IUserService userService;
@Autowired
private IRoleService roleService;
@Autowired
private IPermissionService permissionService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
User primaryPrincipal = (User) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//通过用户名 获取 角色信息
List<Role> roles = roleService.getRolesByUserId(primaryPrincipal.getId());
if(null != roles && roles.size()>0){
//角色 code
List<String> roleCodes = roles.stream().map(item -> item.getRoleCode()).collect(Collectors.toList());
simpleAuthorizationInfo.addRoles(roleCodes);
//角色Id
List<String> roleIds = roles.stream().map(item -> item.getId()).collect(Collectors.toList());
List<Permission> permissions = permissionService.getPermissionsByroleId(roleIds);
if(null != permissions && permissions.size()>0){
List<String> permissionCodes = permissions.stream().map(item -> item.getPermissionCode()).collect(Collectors.toList());
simpleAuthorizationInfo.addStringPermissions(permissionCodes);;
}
}
return simpleAuthorizationInfo;
}
/**
* 认证
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//通过用户名查询用户信息
String principal = (String) token.getPrincipal();
System.out.println("principal:"+principal);
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getUsername,principal);
User getUser = userService.getOne(queryWrapper);
System.out.println(getUser);
if(null !=getUser){
//我们不需要验证密码是否正确,传给SimpleAuthenticationInfo就可以
return new SimpleAuthenticationInfo(getUser,getUser.getPassword(),this.getName());
}
return null;
}
}
测试运行正常
可能会有人发现,只调用了身份认证方法,没有调用授权方法,应该是还没有用到授权,所以没有调用,可以在登录时调用subject.hasRole("admin")方法,字符串无所谓,主要是主动调用验证是否有权限的方法,他就会自动调用realm中编写的授权方法
/**
* 登录方法
* @param userName
* @param passWord
* @return
*/
@GetMapping("login")
public String login(String userName,String passWord){
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userName, passWord);
subject.login(usernamePasswordToken);
subject.hasRole("admin");
return "sucess";
}
统一封装返回结果
这个很简单,就是返回的状态值,返回信息,返回数据,统一封装后前台只要按照这个获取就可以
import lombok.Data;
@Data
public class Result<T> {
private int code;
private String msg;
private T data;
public Result success(){
Result result = new Result();
result.setCode(CODE_ENUM.SUCCESS.code);
return result;
}
public Result error(){
Result result = new Result();
result.setCode(CODE_ENUM.ERROR.code);
return result;
}
public Result setData(T data){
this.data = data;
return this;
}
public Result setMsg(String msg){
this.msg = msg;
return this;
}
public enum CODE_ENUM{
SUCCESS(200),
ERROR(500);
private int code;
CODE_ENUM(int code){
this.code = code;
}
}
}
在编写获取用户信息和登出的方法。。算了,UserController.java一块粘过来吧
package com.han.springbootshiro.controller;
import com.han.springbootshiro.common.Result;
import com.han.springbootshiro.model.Permission;
import com.han.springbootshiro.model.Role;
import com.han.springbootshiro.model.User;
import com.han.springbootshiro.service.IPermissionService;
import com.han.springbootshiro.service.IRoleService;
import com.han.springbootshiro.service.IUserRoleService;
import com.han.springbootshiro.service.IUserService;
import com.han.springbootshiro.vo.UserVo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 前端控制器
* </p>
*
* @author
* @since 2022-08-05
*/
@RestController
@RequestMapping("/system/user/")
public class UserController {
@Autowired
private IUserService userService;
@Autowired
private IRoleService roleService;
@Autowired
private IPermissionService permissionService;
@Autowired
private IUserRoleService userRoleService;
/**
* 登录方法
* @param userName
* @param passWord
* @return
*/
@GetMapping("login")
public String login(String userName,String passWord){
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userName, passWord);
subject.login(usernamePasswordToken);
subject.hasRole("admin");
return "sucess";
}
@PostMapping("userInfo")
public Result userInfo(){
User principal = (User) SecurityUtils.getSubject().getPrincipal();
UserVo userVo = new UserVo();
BeanUtils.copyProperties(principal,userVo,new String[]{"password"});
//角色信息
List<Role> roles = roleService.getRolesByUserId(userVo.getId());
if(null != roles && roles.size()>0){
//角色 code
List<String> roleCodes = roles.stream().map(item -> item.getRoleCode()).collect(Collectors.toList());
userVo.setRoles(roleCodes);
//角色Id
List<String> roleIds = roles.stream().map(item -> item.getId()).collect(Collectors.toList());
List<Permission> permissions = permissionService.getPermissionsByroleId(roleIds);
if(null != permissions && permissions.size()>0){
List<String> permissionCodes = permissions.stream().map(item -> item.getPermissionCode()).collect(Collectors.toList());
userVo.setPermissions(permissionCodes);
}
}
return new Result().success().setData(userVo);
}
@GetMapping("logout")
public Result logout(){
Subject subject = SecurityUtils.getSubject();
subject.logout();
return new Result().success();
}
}
接下来之后,就是前后端联调