修复安全漏洞;

登录密码添加rsa校验
dongdingding
吴顺杰 11 months ago
parent 5cefdb5b93
commit 3f071a79ca

@ -1,103 +0,0 @@
若依系统开发环境搭建手册
1. 准备工作
1.1 前置环境准备 -- -- 安装Maven
若依基于Maven管理项目的构建需要先安装好相应的版本。
1.2 开发工具
若依系统采用Eclipse作为开发工具。但不局限于Eclipse。此处仅介绍在Eclipse搭建开发环境所需的操作。
2. 开发环境搭建
2.1 开发工具的配置
2.1.1 配置Maven
进入Window->Preferences->Maven->Installations页面设置已经安装好的Maven
2.1.2 配置Maven仓库路径
进入Window->Preferences->Maven->User Settings页面配置仓库路径
2.1.4 关闭校验
进入Window->Preferences->Validation页面勾选"Suspend all validators",关闭校验
2.2 导入工程
通过Eclipse导入工程步骤如下
(1)点击左侧项目区域 -- >Import...
(2)选择RuoYi
(3)点击Finish
(4)RuoYi的代码就被导出到Eclipse中了此时可以在工程视图中看到。
3. 运行若依系统
3.1 必要的配置
3.1.1 修改数据库连接
编辑src/main/ resources目录下的application-druid.yml 文件,修改数据库地址账号信息。
执行sql/ ry_20180423.sqlquartz.sql 两个文件 日期随版本变化
3.1.2 开发环境配置
编辑src/main/ resources目录下的application.yml 文件,
默认端口为80
3.1.3 代码生成配置
编辑src/main/ resources目录下的application.yml 文件,
默认为module根据实际情况修改即可。生成的表要有注释
如对模板有特殊需求可自行修改。编辑src/main/ resources/templates/vm目录下
3.1.4 日志配置
编辑src/main/ resources目录下的logback.yml 文件
<property name="log.path" value="/home/ruoyi/logs" />
改为自己需要的路径
3.2 启动及验证(后台)
启动RuoYiApplication.java 出现如下图表示启动成功
打开浏览器输入http://localhost:8080/captchaImage
若能正确显示返回信息,搭建后台成功。
3.3 启动及验证(前台)
# 进入项目目录
cd ruoyi-ui
npm install --registry=https://registry.npm.taobao.org
npm run dev
打开浏览器输入http://localhost:80 (默认账户 admin/admin123
若能正确展示登录页面,并能成功登录,菜单及页面展示正常,则表明环境搭建成功
注意执行npm命令需要配置node环境
4. 部署若依系统
4.1 war部署方式
4.1.1 修改pom.xml文件。将jar修改为war
如果是分模块需要修改ruoyi-admin
4.1.2 在spring-boot-starter依赖中移除tomcat模块
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
4.1.3 部署到tomcat的webapps目录下面
默认为RuoYi.war
4.1.4 启动及验证
运行startup.bat 出现如下图即部署成功
4.2 Jar方式部署
执行命令java - jar RuoYi.jar
脚本执行ry.sh start 启动stop 停止
4.2 前端部署
# 打包正式环境
npm run build:prod
# 打包预发布环境
npm run build:stage
构建打包成功之后,会在根目录生成 dist 文件夹,里面就是构建打包好的文件,通常是 ***.js 、***.css、index.html 等静态文件。发布到你的 nginx 或者静态服务器即可,其中的 index.html 是后台服务的入口页面。
演示地址ruoyi.vip
文档地址doc.ruoyi.vip

@ -19,6 +19,13 @@
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>

@ -6,6 +6,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysDictDataService;
@ -22,7 +23,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
@ -72,7 +72,7 @@ public class SysDictDataController extends BaseController {
public AjaxResult dictType(@PathVariable String dictType) {
List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
if (StringUtils.isNull(data)) {
data = new ArrayList<>();
throw new ServiceException("请输入正确字典");
}
return success(data);
}

@ -1,21 +1,23 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import java.util.Set;
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.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.sign.RsaUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.system.service.ISysMenuService;
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.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Set;
/**
*
@ -23,8 +25,7 @@ import com.ruoyi.system.service.ISysMenuService;
* @author ruoyi
*/
@RestController
public class SysLoginController
{
public class SysLoginController {
@Autowired
private SysLoginService loginService;
@ -41,12 +42,10 @@ public class SysLoginController
* @return
*/
@PostMapping("/login")
public AjaxResult login(@RequestBody LoginBody loginBody)
{
public AjaxResult login(@RequestBody LoginBody loginBody) throws Exception {
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
loginBody.getUuid());
String token = loginService.login(loginBody.getUsername(), RsaUtils.decryptByPrivateKey(loginBody.getPassword()), loginBody.getCode(), loginBody.getUuid());
ajax.put(Constants.TOKEN, token);
return ajax;
}
@ -57,8 +56,7 @@ public class SysLoginController
* @return
*/
@GetMapping("getInfo")
public AjaxResult getInfo()
{
public AjaxResult getInfo() {
SysUser user = SecurityUtils.getLoginUser().getUser();
// 角色集合
Set<String> roles = permissionService.getRolePermission(user);
@ -77,8 +75,7 @@ public class SysLoginController
* @return
*/
@GetMapping("getRouters")
public AjaxResult getRouters()
{
public AjaxResult getRouters() {
Long userId = SecurityUtils.getUserId();
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
return AjaxResult.success(menuService.buildMenus(menus));

@ -0,0 +1,111 @@
package com.ruoyi.zhiyuanzhe.filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author wu
* @since 2023/10/26 22:38
*/
@Component
@ConfigurationProperties(prefix = "security.csrf")
@WebFilter(filterName = "CsrfFilter", urlPatterns = "/*")
public class CsrfFilter implements Filter {
private static final Logger log = LoggerFactory.getLogger(CsrfFilter.class);
/**
*
*/
FilterConfig filterConfig = null;
/**
*
*/
private boolean enable;
/**
* URL
*/
private List<String> excludes;
public void setEnable(boolean enable) {
this.enable = enable;
}
public void setExcludes(List<String> excludes) {
this.excludes = excludes;
}
/**
*
*/
@Override
public void init(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
/**
*
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
// 不启用或者已忽略的URL不拦截
if (!enable || isExcludeUrl(request.getServletPath())) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
String referer = request.getHeader("Referer");
String serverName = request.getServerName();
// 判断是否存在外链请求本站
if (null != referer && !referer.contains(serverName)) {
log.error("CSRF过滤器 => 服务器:{} => 当前域名:{}", serverName, referer);
servletResponse.setContentType("text/html; charset=utf-8");
servletResponse.getWriter().write("系统不支持当前域名的访问!");
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
/**
*
*/
@Override
public void destroy() {
this.filterConfig = null;
}
/**
* URL
*
* @param url URL
* @return true-false-
*/
private boolean isExcludeUrl(String url) {
if (excludes == null || excludes.isEmpty()) {
return false;
}
return excludes.stream().map(pattern -> Pattern.compile("^" + pattern)).map(p -> p.matcher(url))
.anyMatch(Matcher::find);
}
}

@ -2,6 +2,7 @@ package com.ruoyi.zhiyuanzhe.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
@ -13,6 +14,7 @@ import com.ruoyi.zhiyuanzhe.domain.request.BActivityPointsRequest;
import com.ruoyi.zhiyuanzhe.mapper.BActivityPointsMapper;
import com.ruoyi.zhiyuanzhe.service.IBActivityPointsService;
import com.ruoyi.zhiyuanzhe.service.IBDistributionRecordsService;
import com.ruoyi.zhiyuanzhe.utils.PushDataUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@ -144,6 +146,11 @@ public class BActivityPointsServiceImpl implements IBActivityPointsService {
// 保存发放记录
distributionRecordsService.insertBDistributionRecords(records);
}
if (records.getStatus() == 1) {
// 如果保存的是已发放的数据就推送上链
String jsonStr = JSONUtil.toJsonStr(records);
PushDataUtil.pushData(jsonStr);
}
}
/**

@ -1,6 +1,7 @@
package com.ruoyi.zhiyuanzhe.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.zhiyuanzhe.domain.BDistributionRecords;
@ -8,6 +9,7 @@ import com.ruoyi.zhiyuanzhe.domain.request.BActivityPointsRequest;
import com.ruoyi.zhiyuanzhe.domain.request.SubmitRequest;
import com.ruoyi.zhiyuanzhe.mapper.BDistributionRecordsMapper;
import com.ruoyi.zhiyuanzhe.service.IBDistributionRecordsService;
import com.ruoyi.zhiyuanzhe.utils.PushDataUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@ -144,5 +146,10 @@ public class BDistributionRecordsServiceImpl implements IBDistributionRecordsSer
records.setTrackingNumber(req.getTrackingNumber());
// 保存发放记录
this.updateBDistributionRecords(records);
if (records.getStatus() == 1) {
// 如果保存的是已发放的数据就推送上链
String jsonStr = JSONUtil.toJsonStr(records);
PushDataUtil.pushData(jsonStr);
}
}
}

@ -0,0 +1,40 @@
package com.ruoyi.zhiyuanzhe.utils;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.exception.ServiceException;
import java.util.HashMap;
import java.util.Map;
/**
*
*
* @author wu
* @since 2023/10/25 16:19
*/
public class PushDataUtil {
private static final String pushUrl = "http://192.114.0.251/anchorchain/api/chaincode/createelementbygateway";
/**
* json
*
* @param elementjsonstr json
*/
public static void pushData(String elementjsonstr) {
// 获取uuid
String key = IdUtil.simpleUUID();
Map<String, Object> param = new HashMap<>();
param.put("key", key);
param.put("elementjsonstr", elementjsonstr);
String result = HttpUtil.post(pushUrl, param);
Map map = JSONObject.parseObject(result, Map.class);
System.err.println(map);
Object code = map.get("code");
if (Integer.valueOf((String) code) != 200) {
throw new ServiceException("数据传输失败");
}
}
}

@ -59,7 +59,28 @@ spring:
wall:
config:
multi-statement-allow: true
# redis 配置
redis:
# 地址
host: localhost
# 端口默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password:
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# 日志配置
logging:
level:

@ -0,0 +1,88 @@
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
url: jdbc:mysql://192.114.0.162:3306/zhi_yuan_zhe?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: jichuang2023@
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: false
url:
username:
password:
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置连接超时时间
connectTimeout: 30000
# 配置网络超时时间
socketTimeout: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: ruoyi
login-password: 123456
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
# redis 配置
redis:
# 地址
host: localhost
# 端口默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password:
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# 日志配置
logging:
level:
com.ruoyi: error
org.springframework: error

@ -63,28 +63,7 @@ spring:
restart:
# 热部署开关
enabled: true
# redis 配置
redis:
# 地址
host: localhost
# 端口默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password:
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# token配置
token:
@ -140,3 +119,10 @@ knife4j:
api-rule: package
api-rule-resources:
- com
# 信息安全
security:
csrf:
enable: true
excludes:

@ -0,0 +1,140 @@
package com.ruoyi.common.utils.sign;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* RSA
*
* @author ruoyi
**/
public class RsaUtils {
// Rsa 私钥
public static String privateKey = "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY" + "7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN" + "PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA" + "kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow" + "cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv" + "DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh" + "YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3" + "UP8iWi1Qw0Y=";
/**
*
*
* @param text
* @return
*/
public static String decryptByPrivateKey(String text) throws Exception {
return decryptByPrivateKey(privateKey, text);
}
/**
*
*
* @param publicKeyString
* @param text
* @return
*/
public static String decryptByPublicKey(String publicKeyString, String text) throws Exception {
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
return new String(result);
}
/**
*
*
* @param privateKeyString
* @param text
* @return
*/
public static String encryptByPrivateKey(String privateKeyString, String text) throws Exception {
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(text.getBytes());
return Base64.encodeBase64String(result);
}
/**
*
*
* @param privateKeyString
* @param text
* @return
*/
public static String decryptByPrivateKey(String privateKeyString, String text) throws Exception {
PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
return new String(result);
}
/**
*
*
* @param publicKeyString
* @param text
* @return
*/
public static String encryptByPublicKey(String publicKeyString, String text) throws Exception {
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(text.getBytes());
return Base64.encodeBase64String(result);
}
/**
* RSA
*
* @return
*/
public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
return new RsaKeyPair(publicKeyString, privateKeyString);
}
/**
* RSA
*/
public static class RsaKeyPair {
private final String publicKey;
private final String privateKey;
public RsaKeyPair(String publicKey, String privateKey) {
this.publicKey = publicKey;
this.privateKey = privateKey;
}
public String getPublicKey() {
return publicKey;
}
public String getPrivateKey() {
return privateKey;
}
}
}

@ -1,12 +1,5 @@
package com.ruoyi.framework.web.service;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.UserConstants;
@ -28,6 +21,14 @@ import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.security.context.AuthenticationContextHolder;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
*
@ -35,8 +36,7 @@ import com.ruoyi.system.service.ISysUserService;
* @author ruoyi
*/
@Component
public class SysLoginService
{
public class SysLoginService {
@Autowired
private TokenService tokenService;
@ -61,36 +61,27 @@ public class SysLoginService
* @param uuid
* @return
*/
public String login(String username, String password, String code, String uuid)
{
public String login(String username, String password, String code, String uuid) {
// 验证码校验
validateCaptcha(username, code, uuid);
// 登录前置校验
loginPreCheck(username, password);
// 用户验证
Authentication authentication = null;
try
{
try {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
AuthenticationContextHolder.setContext(authenticationToken);
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
authentication = authenticationManager.authenticate(authenticationToken);
}
catch (Exception e)
{
if (e instanceof BadCredentialsException)
{
} catch (Exception e) {
if (e instanceof BadCredentialsException) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
throw new UserPasswordNotMatchException();
}
else
{
} else {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
throw new ServiceException(e.getMessage());
}
}
finally
{
} finally {
AuthenticationContextHolder.clearContext();
}
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
@ -108,21 +99,17 @@ public class SysLoginService
* @param uuid
* @return
*/
public void validateCaptcha(String username, String code, String uuid)
{
public void validateCaptcha(String username, String code, String uuid) {
boolean captchaEnabled = configService.selectCaptchaEnabled();
if (captchaEnabled)
{
if (captchaEnabled) {
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
String captcha = redisCache.getCacheObject(verifyKey);
redisCache.deleteObject(verifyKey);
if (captcha == null)
{
if (captcha == null) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
throw new CaptchaExpireException();
}
if (!code.equalsIgnoreCase(captcha))
{
if (!code.equalsIgnoreCase(captcha)) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
throw new CaptchaException();
}
@ -131,35 +118,31 @@ public class SysLoginService
/**
*
*
* @param username
* @param password
*/
public void loginPreCheck(String username, String password)
{
public void loginPreCheck(String username, String password) {
// 用户名或密码为空 错误
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
{
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
throw new UserNotExistsException();
}
// 密码如果不在指定范围内 错误
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH)
{
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
throw new UserPasswordNotMatchException();
}
// 用户名不在指定范围内 错误
if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|| username.length() > UserConstants.USERNAME_MAX_LENGTH)
{
|| username.length() > UserConstants.USERNAME_MAX_LENGTH) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
throw new UserPasswordNotMatchException();
}
// IP黑名单校验
String blackStr = configService.selectConfigByKey("sys.login.blackIPList");
if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
{
if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
throw new BlackListException();
}
@ -170,8 +153,7 @@ public class SysLoginService
*
* @param userId ID
*/
public void recordLoginInfo(Long userId)
{
public void recordLoginInfo(Long userId) {
SysUser sysUser = new SysUser();
sysUser.setUserId(userId);
sysUser.setLoginIp(IpUtils.getIpAddr());

@ -544,7 +544,9 @@ create table sys_config (
) engine=innodb auto_increment=100 comment = '参数配置表';
insert into sys_config values(1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', sysdate(), '', null, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow' );
insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', sysdate(), '', null, '初始化密码 123456' );
insert into sys_config
values (2, '用户管理-账号初始密码', 'sys.user.initPassword', 'Zhiyuan@2023', 'Y', 'admin', sysdate(), '', null,
'初始化密码 Zhiyuan@2023');
insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', sysdate(), '', null, '深色主题theme-dark浅色主题theme-light' );
insert into sys_config values(4, '账号自助-验证码开关', 'sys.account.captchaEnabled', 'true', 'Y', 'admin', sysdate(), '', null, '是否开启验证码功能true开启false关闭');
insert into sys_config values(5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', sysdate(), '', null, '是否开启注册用户功能true开启false关闭');

Loading…
Cancel
Save