若依微服务3.6.3版本整合activiti7(7.1.0.M6)
目前有两种办法集成activiti7
- 放弃activiti7新版本封装的API,使用老版本的API,这种方式只需要直接集成即可,在7.1.0.M6版本中甚至不需要去除security的依赖。不多介绍,需要的可以私聊找我。
- 需要使用新版本的API,那就需要集成security,需要写一点代码实现security的集成。以下详细介绍这一种方式。
步骤1
在主项目的pom中添加如下代码,其中lombok和activiti-image-generator可以不加,一定要加spring-boot-starter-security,因为不知道为什么activiti的7.1.0.M6版本中去除了security的部分依赖,导致不能直接集成security,需要添加spring-boot-starter-security才行。
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>7.1.0.M6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-image-generator</artifactId>
<version>5.22.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
步骤2
在你的activiti模块的pom文件中添加如下代码
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
<!-- <exclusion>-->
<!-- <groupId>org.activiti.core.common</groupId>-->
<!-- <artifactId>activiti-spring-security</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>org.springframework.security</groupId>-->
<!-- <artifactId>spring-security-core</artifactId>-->
<!-- </exclusion>-->
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-image-generator</artifactId>
<exclusions>
<exclusion>
<artifactId>activiti-bpmn-model</artifactId>
<groupId>org.activiti</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
步骤3
添加对应的代码,目录及源码如下(security目录下的源码即可)
ActivitiSecurityConfig
package com.ruoyi.activiti.security.config;
import com.ruoyi.activiti.security.LoginFailureHandler;
import com.ruoyi.activiti.security.LoginSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class ActivitiSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private LoginSuccessHandler loginSuccessHandler;
@Autowired
private LoginFailureHandler loginFailureHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
//--------------------------最精简的配置 对所有的页面都允许-----------------------------
http
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login")//对应ActivitiSecurityController.requireAuthentication 未登录用户进行提示 提示内容编写
.successHandler(loginSuccessHandler)
.failureHandler(loginFailureHandler)
.and()
.authorizeRequests()
.anyRequest()
.permitAll().and().logout().permitAll().and().csrf().disable().headers().frameOptions().disable();//全部页面不验证
}
}
LoginUser
package com.ruoyi.activiti.security.domain;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* 用户信息
*
* @author ruoyi
*/
public class LoginUser implements UserDetails {
private static final long serialVersionUID = 1L;
/**
* 用户唯一标识
*/
private String token;
/**
* 用户名id
*/
private Long userid;
/**
* 用户名
*/
private String username;
/**
* 登录时间
*/
private Long loginTime;
/**
* 过期时间
*/
private Long expireTime;
/**
* 登录IP地址
*/
private String ipaddr;
/**
* 权限列表
*/
private Set<String> permissions;
/**
* 角色列表
*/
private Set<String> roles;
/**
* 用户信息
*/
private SysUser sysUser;
private List<SimpleGrantedAuthority> authorities;
public LoginUser(SysUser user, Set<String> permissions, List<SimpleGrantedAuthority> authorities) {
this.sysUser = user;
this.permissions = permissions;
this.authorities = authorities;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public Long getUserid() {
return userid;
}
public void setUserid(Long userid) {
this.userid = userid;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
// return sysUser.getPassword();
return new BCryptPasswordEncoder().encode("111");
}
public String getUsername() {
return sysUser.getUserName();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
public void setUsername(String username) {
this.username = username;
}
public Long getLoginTime() {
return loginTime;
}
public void setLoginTime(Long loginTime) {
this.loginTime = loginTime;
}
public Long getExpireTime() {
return expireTime;
}
public void setExpireTime(Long expireTime) {
this.expireTime = expireTime;
}
public String getIpaddr() {
return ipaddr;
}
public void setIpaddr(String ipaddr) {
this.ipaddr = ipaddr;
}
public Set<String> getPermissions() {
return permissions;
}
public void setPermissions(Set<String> permissions) {
this.permissions = permissions;
}
public Set<String> getRoles() {
return roles;
}
public void setRoles(Set<String> roles) {
this.roles = roles;
}
public SysUser getSysUser() {
return sysUser;
}
public void setSysUser(SysUser sysUser) {
this.sysUser = sysUser;
}
}
SysDept
package com.ruoyi.activiti.security.domain;
import com.ruoyi.common.core.web.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.ArrayList;
import java.util.List;
/**
* 部门表 sys_dept
*
* @author ruoyi
*/
public class SysDept extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 部门ID
*/
private Long deptId;
/**
* 父部门ID
*/
private Long parentId;
/**
* 祖级列表
*/
private String ancestors;
/**
* 部门名称
*/
private String deptName;
/**
* 显示顺序
*/
private String orderNum;
/**
* 负责人
*/
private String leader;
/**
* 联系电话
*/
private String phone;
/**
* 邮箱
*/
private String email;
/**
* 部门状态:0正常,1停用
*/
private String status;
/**
* 删除标志(0代表存在 2代表删除)
*/
private String delFlag;
/**
* 父部门名称
*/
private String parentName;
/**
* 子部门
*/
private List<SysDept> children = new ArrayList<SysDept>();
public Long getDeptId() {
return deptId;
}
public void setDeptId(Long deptId) {
this.deptId = deptId;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public String getAncestors() {
return ancestors;
}
public void setAncestors(String ancestors) {
this.ancestors = ancestors;
}
@NotBlank(message = "部门名称不能为空")
@Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
@NotBlank(message = "显示顺序不能为空")
public String getOrderNum() {
return orderNum;
}
public void setOrderNum(String orderNum) {
this.orderNum = orderNum;
}
public String getLeader() {
return leader;
}
public void setLeader(String leader) {
this.leader = leader;
}
@Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDelFlag() {
return delFlag;
}
public void setDelFlag(String delFlag) {
this.delFlag = delFlag;
}
public String getParentName() {
return parentName;
}
public void setParentName(String parentName) {
this.parentName = parentName;
}
public List<SysDept> getChildren() {
return children;
}
public void setChildren(List<SysDept> children) {
this.children = children;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("deptId", getDeptId())
.append("parentId", getParentId())
.append("ancestors", getAncestors())
.append("deptName", getDeptName())
.append("orderNum", getOrderNum())
.append("leader", getLeader())
.append("phone", getPhone())
.append("email", getEmail())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}
SysMenu
package com.ruoyi.activiti.security.domain;
import com.ruoyi.common.core.web.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.ArrayList;
import java.util.List;
/**
* 菜单权限表 sys_menu
*
* @author ruoyi
*/
public class SysMenu extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 菜单ID
*/
private Long menuId;
/**
* 菜单名称
*/
private String menuName;
/**
* 父菜单名称
*/
private String parentName;
/**
* 父菜单ID
*/
private Long parentId;
/**
* 显示顺序
*/
private Integer orderNum;
/**
* 路由地址
*/
private String path;
/**
* 组件路径
*/
private String component;
/**
* 路由参数
*/
private String query;
/**
* 是否为外链(0是 1否)
*/
private String isFrame;
/**
* 是否缓存(0缓存 1不缓存)
*/
private String isCache;
/**
* 类型(M目录 C菜单 F按钮)
*/
private String menuType;
/**
* 显示状态(0显示 1隐藏)
*/
private String visible;
/**
* 菜单状态(0显示 1隐藏)
*/
private String status;
/**
* 权限字符串
*/
private String perms;
/**
* 菜单图标
*/
private String icon;
/**
* 子菜单
*/
private List<SysMenu> children = new ArrayList<SysMenu>();
public Long getMenuId() {
return menuId;
}
public void setMenuId(Long menuId) {
this.menuId = menuId;
}
@NotBlank(message = "菜单名称不能为空")
@Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符")
public String getMenuName() {
return menuName;
}
public void setMenuName(String menuName) {
this.menuName = menuName;
}
public String getParentName() {
return parentName;
}
public void setParentName(String parentName) {
this.parentName = parentName;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
@NotNull(message = "显示顺序不能为空")
public Integer getOrderNum() {
return orderNum;
}
public void setOrderNum(Integer orderNum) {
this.orderNum = orderNum;
}
@Size(min = 0, max = 200, message = "路由地址不能超过200个字符")
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
@Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
public String getComponent() {
return component;
}
public void setComponent(String component) {
this.component = component;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
public String getIsFrame() {
return isFrame;
}
public void setIsFrame(String isFrame) {
this.isFrame = isFrame;
}
public String getIsCache() {
return isCache;
}
public void setIsCache(String isCache) {
this.isCache = isCache;
}
@NotBlank(message = "菜单类型不能为空")
public String getMenuType() {
return menuType;
}
public void setMenuType(String menuType) {
this.menuType = menuType;
}
public String getVisible() {
return visible;
}
public void setVisible(String visible) {
this.visible = visible;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
@Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
public String getPerms() {
return perms;
}
public void setPerms(String perms) {
this.perms = perms;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public List<SysMenu> getChildren() {
return children;
}
public void setChildren(List<SysMenu> children) {
this.children = children;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("menuId", getMenuId())
.append("menuName", getMenuName())
.append("parentId", getParentId())
.append("orderNum", getOrderNum())
.append("path", getPath())
.append("component", getComponent())
.append("isFrame", getIsFrame())
.append("IsCache", getIsCache())
.append("menuType", getMenuType())
.append("visible", getVisible())
.append("status ", getStatus())
.append("perms", getPerms())
.append("icon", getIcon())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}
SysPost
package com.ruoyi.activiti.security.domain;
import com.ruoyi.common.core.annotation.Excel;
import com.ruoyi.common.core.annotation.Excel.ColumnType;
import com.ruoyi.common.core.web.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
/**
* 岗位表 sys_post
*
* @author ruoyi
*/
public class SysPost extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 岗位序号
*/
@Excel(name = "岗位序号", cellType = ColumnType.NUMERIC)
private Long postId;
/**
* 岗位编码
*/
@Excel(name = "岗位编码")
private String postCode;
/**
* 岗位名称
*/
@Excel(name = "岗位名称")
private String postName;
/**
* 岗位排序
*/
@Excel(name = "岗位排序")
private String postSort;
/**
* 状态(0正常 1停用)
*/
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
/**
* 用户是否存在此岗位标识 默认不存在
*/
private boolean flag = false;
public Long getPostId() {
return postId;
}
public void setPostId(Long postId) {
this.postId = postId;
}
@NotBlank(message = "岗位编码不能为空")
@Size(min = 0, max = 64, message = "岗位编码长度不能超过64个字符")
public String getPostCode() {
return postCode;
}
public void setPostCode(String postCode) {
this.postCode = postCode;
}
@NotBlank(message = "岗位名称不能为空")
@Size(min = 0, max = 50, message = "岗位名称长度不能超过50个字符")
public String getPostName() {
return postName;
}
public void setPostName(String postName) {
this.postName = postName;
}
@NotBlank(message = "显示顺序不能为空")
public String getPostSort() {
return postSort;
}
public void setPostSort(String postSort) {
this.postSort = postSort;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("postId", getPostId())
.append("postCode", getPostCode())
.append("postName", getPostName())
.append("postSort", getPostSort())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}
SysUser
package com.ruoyi.activiti.security.domain;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.common.core.annotation.Excel;
import com.ruoyi.common.core.annotation.Excel.ColumnType;
import com.ruoyi.common.core.annotation.Excel.Type;
import com.ruoyi.common.core.annotation.Excels;
import com.ruoyi.common.core.web.domain.BaseEntity;
import com.ruoyi.common.core.xss.Xss;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.Date;
import java.util.List;
/**
* 用户对象 sys_user
*
* @author ruoyi
*/
public class SysUser extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
@Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
private Long userId;
/**
* 部门ID
*/
@Excel(name = "部门编号", type = Type.IMPORT)
private Long deptId;
/**
* 用户账号
*/
@Excel(name = "登录名称")
private String userName;
/**
* 用户昵称
*/
@Excel(name = "用户名称")
private String nickName;
/**
* 用户邮箱
*/
@Excel(name = "用户邮箱")
private String email;
/**
* 手机号码
*/
@Excel(name = "手机号码")
private String phonenumber;
/**
* 用户性别
*/
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
private String sex;
/**
* 用户头像
*/
private String avatar;
/**
* 密码
*/
private String password;
/**
* 帐号状态(0正常 1停用)
*/
@Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
private String status;
/**
* 删除标志(0代表存在 2代表删除)
*/
private String delFlag;
/**
* 最后登录IP
*/
@Excel(name = "最后登录IP", type = Type.EXPORT)
private String loginIp;
/**
* 最后登录时间
*/
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
private Date loginDate;
/**
* 部门对象
*/
@Excels({
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
@Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
})
private SysDept dept;
/**
* 角色对象
*/
private List<SysRole> roles;
/**
* 角色组
*/
private Long[] roleIds;
/**
* 岗位组
*/
private Long[] postIds;
/**
* 角色ID
*/
private Long roleId;
public SysUser() {
}
public SysUser(Long userId) {
this.userId = userId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public boolean isAdmin() {
return isAdmin(this.userId);
}
public static boolean isAdmin(Long userId) {
return userId != null && 1L == userId;
}
public Long getDeptId() {
return deptId;
}
public void setDeptId(Long deptId) {
this.deptId = deptId;
}
@Xss(message = "用户昵称不能包含脚本字符")
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
@Xss(message = "用户账号不能包含脚本字符")
@NotBlank(message = "用户账号不能为空")
@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
public String getPhonenumber() {
return phonenumber;
}
public void setPhonenumber(String phonenumber) {
this.phonenumber = phonenumber;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
@JsonProperty
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDelFlag() {
return delFlag;
}
public void setDelFlag(String delFlag) {
this.delFlag = delFlag;
}
public String getLoginIp() {
return loginIp;
}
public void setLoginIp(String loginIp) {
this.loginIp = loginIp;
}
public Date getLoginDate() {
return loginDate;
}
public void setLoginDate(Date loginDate) {
this.loginDate = loginDate;
}
public SysDept getDept() {
return dept;
}
public void setDept(SysDept dept) {
this.dept = dept;
}
public List<SysRole> getRoles() {
return roles;
}
public void setRoles(List<SysRole> roles) {
this.roles = roles;
}
public Long[] getRoleIds() {
return roleIds;
}
public void setRoleIds(Long[] roleIds) {
this.roleIds = roleIds;
}
public Long[] getPostIds() {
return postIds;
}
public void setPostIds(Long[] postIds) {
this.postIds = postIds;
}
public Long getRoleId() {
return roleId;
}
public void setRoleId(Long roleId) {
this.roleId = roleId;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("userId", getUserId())
.append("deptId", getDeptId())
.append("userName", getUserName())
.append("nickName", getNickName())
.append("email", getEmail())
.append("phonenumber", getPhonenumber())
.append("sex", getSex())
.append("avatar", getAvatar())
.append("password", getPassword())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("loginIp", getLoginIp())
.append("loginDate", getLoginDate())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.append("dept", getDept())
.toString();
}
}
SysMenuMapper
package com.ruoyi.activiti.security.mapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 菜单表 数据层
*
* @author ruoyi
*/
@Mapper
public interface SysMenuMapper {
/**
* 根据用户ID查询权限
*
* @param userId 用户ID
* @return 权限列表
*/
public List<String> selectMenuPermsByUserId(Long userId);
}
SysPostMapper
package com.ruoyi.activiti.security.mapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.Set;
/**
* 岗位信息 数据层
*
* @author ruoyi
*/
@Mapper
public interface SysPostMapper {
/**
* 根据用户ID获取岗位选择框列表
*
* @param userId 用户ID
* @return 选中岗位ID列表
*/
public Set<String> selectPostCodeByUserId(Long userId);
}
SysUserMapper
package com.ruoyi.activiti.security.mapper;
import com.ruoyi.activiti.security.domain.SysUser;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 用户表 数据层
*
* @author ruoyi
*/
@Mapper
public interface SysUserMapper {
// public List<String> selectUserNameByPostCodeAndDeptId(@Param("postCode")String postCode,@Param("deptId") String deptId);
public List<String> selectUserNameByPostCodeAndDeptId(String postCode, Long deptId);
/**
* 通过用户名查询用户
*
* @param userName 用户名
* @return 用户对象信息
*/
public SysUser selectUserByUserName(String userName);
}
MyUserDetailsService
package com.ruoyi.activiti.security.service.impl;
import com.ruoyi.activiti.security.domain.LoginUser;
import com.ruoyi.common.core.enums.UserStatus;
import com.ruoyi.common.core.exception.base.BaseException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.activiti.security.domain.SysUser;
import com.ruoyi.activiti.security.service.ISysPermissionService;
import com.ruoyi.activiti.security.service.ISysPostService;
import com.ruoyi.activiti.security.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Component
public class MyUserDetailsService implements UserDetailsService {
private Logger logger = LoggerFactory.getLogger(getClass());
private static final Logger log = LoggerFactory.getLogger(MyUserDetailsService.class);
@Autowired
private ISysUserService userService;
@Autowired
private ISysPostService sysPostService;
@Autowired
private ISysPermissionService permissionService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
SysUser user = userService.selectUserByUserName(username);
if (StringUtils.isNull(user)) {
log.info("登录用户:{} 不存在.", username);
throw new UsernameNotFoundException("登录用户:" + username + " 不存在");
} else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
log.info("登录用户:{} 已被删除.", username);
throw new BaseException("对不起,您的账号:" + username + " 已被删除");
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
log.info("登录用户:{} 已被停用.", username);
throw new BaseException("对不起,您的账号:" + username + " 已停用");
}
return createLoginUser(user);
}
public UserDetails createLoginUser(SysUser user) {
Set<String> postCode = sysPostService.selectPostCodeByUserId(user.getUserId());
postCode = postCode.parallelStream().map(s -> "GROUP_" + s).collect(Collectors.toSet());
postCode.add("ROLE_ACTIVITI_USER");
List<SimpleGrantedAuthority> collect = postCode.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList());
return new LoginUser(user, permissionService.getMenuPermission(user.getUserId()), collect);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
SysMenuServiceImpl
package com.ruoyi.activiti.security.service.impl;
import com.ruoyi.activiti.security.service.ISysMenuService;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.activiti.security.mapper.SysMenuMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 菜单 业务层处理
*
* @author ruoyi
*/
@Service
public class SysMenuServiceImpl implements ISysMenuService {
public static final String PREMISSION_STRING = "perms[\"{0}\"]";
@Autowired
private SysMenuMapper menuMapper;
/**
* 根据用户ID查询权限
*
* @param userId 用户ID
* @return 权限列表
*/
@Override
public Set<String> selectMenuPermsByUserId(Long userId) {
List<String> perms = menuMapper.selectMenuPermsByUserId(userId);
Set<String> permsSet = new HashSet<>();
for (String perm : perms) {
if (StringUtils.isNotEmpty(perm)) {
permsSet.addAll(Arrays.asList(perm.trim().split(",")));
}
}
return permsSet;
}
}
SysPermissionServiceImpl
package com.ruoyi.activiti.security.service.impl;
import com.ruoyi.activiti.security.service.ISysMenuService;
import com.ruoyi.activiti.security.service.ISysPermissionService;
import com.ruoyi.activiti.security.domain.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.Set;
@Service
public class SysPermissionServiceImpl implements ISysPermissionService {
@Autowired
private ISysMenuService menuService;
/**
* 获取菜单数据权限
*
* @param userId 用户Id
* @return 菜单权限信息
*/
@Override
public Set<String> getMenuPermission(Long userId) {
Set<String> perms = new HashSet<String>();
// 管理员拥有所有权限
if (SysUser.isAdmin(userId)) {
perms.add("*:*:*");
} else {
perms.addAll(menuService.selectMenuPermsByUserId(userId));
}
return perms;
}
}
SysPostServiceImpl
package com.ruoyi.activiti.security.service.impl;
import com.ruoyi.activiti.security.service.ISysPostService;
import com.ruoyi.activiti.security.mapper.SysPostMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Set;
/**
* 岗位信息 服务层处理
*
* @author ruoyi
*/
@Service
public class SysPostServiceImpl implements ISysPostService {
@Autowired
private SysPostMapper postMapper;
/**
* 根据用户ID获取岗位选择框列表
*
* @param userId 用户ID
* @return 选中岗位ID列表
*/
@Override
public Set<String> selectPostCodeByUserId(Long userId) {
return postMapper.selectPostCodeByUserId(userId);
}
}
SysUserServiceImpl
package com.ruoyi.activiti.security.service.impl;
import com.ruoyi.activiti.security.service.ISysUserService;
import com.ruoyi.activiti.security.domain.SysUser;
import com.ruoyi.activiti.security.mapper.SysUserMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 用户 业务层处理
*
* @author ruoyi
*/
@Service
public class SysUserServiceImpl implements ISysUserService {
private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class);
@Autowired
private SysUserMapper userMapper;
public List<String> selectUserNameByPostCodeAndDeptId(String postCode, Long deptId) {
return userMapper.selectUserNameByPostCodeAndDeptId(postCode, deptId);
}
/**
* 通过用户名查询用户
*
* @param userName 用户名
* @return 用户对象信息
*/
@Override
public SysUser selectUserByUserName(String userName) {
return userMapper.selectUserByUserName(userName);
}
}
ISysMenuService
package com.ruoyi.activiti.security.service;
import java.util.Set;
/**
* 菜单 业务层
*
* @author ruoyi
*/
public interface ISysMenuService {
/**
* 根据用户ID查询权限
*
* @param userId 用户ID
* @return 权限列表
*/
public Set<String> selectMenuPermsByUserId(Long userId);
}
ISysPermissionService
package com.ruoyi.activiti.security.service;
import java.util.Set;
public interface ISysPermissionService {
/**
* 获取菜单数据权限
*
* @param userId 用户Id
* @return 菜单权限信息
*/
public Set<String> getMenuPermission(Long userId);
}
ISysPostService
package com.ruoyi.activiti.security.service;
import java.util.Set;
/**
* 岗位信息 服务层
*
* @author ruoyi
*/
public interface ISysPostService {
/**
* 根据用户ID获取岗位选择框列表
*
* @param userId 用户ID
* @return 选中岗位ID列表
*/
public Set<String> selectPostCodeByUserId(Long userId);
}
ISysUserService
package com.ruoyi.activiti.security.service;
import com.ruoyi.activiti.security.domain.SysUser;
import java.util.List;
/**
* 用户 业务层
*
* @author ruoyi
*/
public interface ISysUserService {
public List<String> selectUserNameByPostCodeAndDeptId(String postCode, Long deptId);
/**
* 通过用户名查询用户
*
* @param userName 用户名
* @return 用户对象信息
*/
public SysUser selectUserByUserName(String userName);
}
ActivitiSecurityUtil
package com.ruoyi.activiti.security.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import java.util.Collection;
@Component
public class ActivitiSecurityUtil {
private Logger logger = LoggerFactory.getLogger(ActivitiSecurityUtil.class);
@Autowired
private UserDetailsService userDetailsService;
public void logInAs(String username) {
UserDetails user = userDetailsService.loadUserByUsername(username);
if (user == null) {
throw new IllegalStateException("User " + username + " doesn't exist, please provide a valid user");
}
logger.info("> Logged in as: " + username);
SecurityContextHolder.setContext(new SecurityContextImpl(new Authentication() {
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return user.getAuthorities();
}
@Override
public Object getCredentials() {
return user.getPassword();
}
@Override
public Object getDetails() {
return user;
}
@Override
public Object getPrincipal() {
return user;
}
@Override
public boolean isAuthenticated() {
return true;
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
}
@Override
public String getName() {
return user.getUsername();
}
}));
org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);
}
}
GlobalConfig
package com.ruoyi.activiti.security.util;
public class GlobalConfig {
/**
* 测试场景
*/
public static final Boolean Test = false;
//windows路径
// public static final String BPMN_PathMapping = "file:D:\\WangJianIDEA_Test\\activiti-imooc\\src\\main\\resources\\resources\\bpmn\\";
//Liunx路径
public static final String BPMN_PathMapping = "file:/opt/app/activitiweb/upload/";
public enum ResponseCode {
SUCCESS(0, "成功"),
ERROR(1, "错误");
private final int code;
private final String desc;
ResponseCode(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
}
LoginFailureHandler
package com.ruoyi.activiti.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.activiti.security.util.GlobalConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component("loginFailureHandler")
public class LoginFailureHandler implements AuthenticationFailureHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private ObjectMapper objectMapper;
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
logger.info("登录失败");
httpServletResponse.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
httpServletResponse.setContentType("application/json;charset=UTF-8");
httpServletResponse.getWriter().write(objectMapper.writeValueAsString(AjaxResult.success(GlobalConfig.ResponseCode.ERROR.getDesc(),"登录失败:" + e.getMessage())));
}
}
LoginSuccessHandler
package com.ruoyi.activiti.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.activiti.security.util.GlobalConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component("loginSuccessHandler")
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private ObjectMapper objectMapper;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException, ServletException {
logger.info("登录成功1");
}
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
logger.info("登录成功2");
httpServletResponse.setContentType("application/json;charset=UTF-8");
httpServletResponse.getWriter().write(objectMapper.writeValueAsString(AjaxResult.success(GlobalConfig.ResponseCode.SUCCESS.getDesc(),authentication.getName())));
}
}
SysMenuMapper.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.ruoyi.activiti.security.mapper.SysMenuMapper">
<resultMap type="SysMenu" id="SysMenuResult">
<id property="menuId" column="menu_id" />
<result property="menuName" column="menu_name" />
<result property="parentName" column="parent_name" />
<result property="parentId" column="parent_id" />
<result property="orderNum" column="order_num" />
<result property="path" column="path" />
<result property="component" column="component" />
<result property="query" column="query" />
<result property="isFrame" column="is_frame" />
<result property="isCache" column="is_cache" />
<result property="menuType" column="menu_type" />
<result property="visible" column="visible" />
<result property="status" column="status" />
<result property="perms" column="perms" />
<result property="icon" column="icon" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateTime" column="update_time" />
<result property="updateBy" column="update_by" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectMenuVo">
select menu_id, menu_name, parent_id, order_num, path, component, `query`, is_frame, is_cache, menu_type, visible, status, ifnull(perms,'') as perms, icon, create_time
from sys_menu
</sql>
<select id="selectMenuPermsByUserId" parameterType="Long" resultType="String">
select distinct m.perms
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
left join sys_user_role ur on rm.role_id = ur.role_id
left join sys_role r on r.role_id = ur.role_id
where m.status = '0' and r.status = '0' and ur.user_id = #{userId}
</select>
</mapper>
SysPostMapper.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.ruoyi.activiti.security.mapper.SysPostMapper">
<resultMap type="SysPost" id="SysPostResult">
<id property="postId" column="post_id" />
<result property="postCode" column="post_code" />
<result property="postName" column="post_name" />
<result property="postSort" column="post_sort" />
<result property="status" column="status" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectPostVo">
select post_id, post_code, post_name, post_sort, status, create_by, create_time, remark
from sys_post
</sql>
<select id="selectPostCodeByUserId" parameterType="Long" resultType="String">
select p.post_code
from sys_post p
left join sys_user_post up on up.post_id = p.post_id
left join sys_user u on u.user_id = up.user_id
where u.user_id = #{userId}
</select>
</mapper>
SysUserMapper.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.ruoyi.activiti.security.mapper.SysUserMapper">
<!-- <select id="selectUserNameByPostCodeAndDeptId" parameterType="String" resultType="String">-->
<!-- SELECT user_name FROM sys_post p-->
<!-- left join sys_user_post up on p.post_id = up.post_id-->
<!-- left join sys_user u on up.user_id= u.user_id-->
<!-- where post_code=#{postCode} and dept_id=#{deptId}-->
<!-- </select>-->
<resultMap type="SysUser" id="SysUserResult">
<id property="userId" column="user_id" />
<result property="deptId" column="dept_id" />
<result property="userName" column="user_name" />
<result property="nickName" column="nick_name" />
<result property="email" column="email" />
<result property="phonenumber" column="phonenumber" />
<result property="sex" column="sex" />
<result property="avatar" column="avatar" />
<result property="password" column="password" />
<result property="status" column="status" />
<result property="delFlag" column="del_flag" />
<result property="loginIp" column="login_ip" />
<result property="loginDate" column="login_date" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
<association property="dept" column="dept_id" javaType="SysDept" resultMap="deptResult" />
<collection property="roles" javaType="java.util.List" resultMap="RoleResult" />
</resultMap>
<resultMap id="deptResult" type="SysDept">
<id property="deptId" column="dept_id" />
<result property="parentId" column="parent_id" />
<result property="deptName" column="dept_name" />
<result property="ancestors" column="ancestors" />
<result property="orderNum" column="order_num" />
<result property="leader" column="leader" />
<result property="status" column="dept_status" />
</resultMap>
<resultMap id="RoleResult" type="SysRole">
<id property="roleId" column="role_id" />
<result property="roleName" column="role_name" />
<result property="roleKey" column="role_key" />
<result property="roleSort" column="role_sort" />
<result property="dataScope" column="data_scope" />
<result property="status" column="role_status" />
</resultMap>
<sql id="selectUserVo">
select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,
d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status,
r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
left join sys_user_role ur on u.user_id = ur.user_id
left join sys_role r on r.role_id = ur.role_id
</sql>
<select id="selectUserNameByPostCodeAndDeptId" resultType="String">
SELECT user_name FROM sys_post p
left join sys_user_post up on p.post_id = up.post_id
left join sys_user u on up.user_id= u.user_id
where post_code=#{param1} and dept_id=#{param2}
</select>
<select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult">
<include refid="selectUserVo"/>
where u.user_name = #{userName}
</select>
</mapper>
以上就是全部代码了
需要注意的是
- 在整合的时候写的nacos配置网关文件中,不要写StripPrefix=1,否则会删除一节访问路径,导致404找不到接口的情况,这个问题搞了我好几天
- 写了这么多代码,其实大体思路就是整合了security后,在需要使用activiti新版本api的时候,使用activitiSecurityUtil.logInAs(SecurityUtils.getUsername());这一句来进行登录,并给与ROLE_ACTIVITI_USER权限即可。