diff --git a/db/yami_shop.sql b/db/yami_shop.sql index 6b8fdc2..6845776 100644 --- a/db/yami_shop.sql +++ b/db/yami_shop.sql @@ -233,28 +233,6 @@ CREATE TABLE `qrtz_triggers` ( /*Data for the table `qrtz_triggers` */ -/*Table structure for table `tz_app_connect` */ - -DROP TABLE IF EXISTS `tz_app_connect`; - -CREATE TABLE `tz_app_connect` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `user_id` varchar(36) NOT NULL COMMENT '本系统userId', - `app_id` tinyint(2) DEFAULT NULL COMMENT '第三方系统id 1:微信小程序', - `nick_name` varchar(64) DEFAULT NULL COMMENT '第三方系统昵称', - `image_url` varchar(500) DEFAULT NULL COMMENT '第三方系统头像', - `biz_user_id` varchar(255) DEFAULT NULL COMMENT '第三方系统userid', - `biz_unionid` varchar(255) DEFAULT NULL COMMENT '第三方系统unionid', - PRIMARY KEY (`id`), - KEY `user_app_id` (`user_id`,`app_id`) COMMENT '用户id和appid联合索引' -) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8; - -/*Data for the table `tz_app_connect` */ - -insert into `tz_app_connect`(`id`,`user_id`,`app_id`,`nick_name`,`image_url`,`biz_user_id`,`biz_unionid`) values -(48,'51540df5255e4d22903b0f83921095ff',1,NULL,NULL,'o-lgc5CUDIn2nkk8512hKumBnjMI','o92Yz1cLnHuo70epfneTG8SaRY0c'), -(49,'5f159317be5b4dc4bf3188f1a3da0369',1,NULL,NULL,'o-lgc5IHLX-RuR1aw5qwP9bpGDuQ','o92Yz1bmhLV8CKMwQkuPk5C8lFfg'); - /*Table structure for table `tz_area` */ DROP TABLE IF EXISTS `tz_area`; diff --git a/mall4v/src/components/mul-pic-upload/index.vue b/mall4v/src/components/mul-pic-upload/index.vue index 4e0f127..d7f50c3 100644 --- a/mall4v/src/components/mul-pic-upload/index.vue +++ b/mall4v/src/components/mul-pic-upload/index.vue @@ -79,5 +79,3 @@ } - diff --git a/pom.xml b/pom.xml index dfe78c6..7406b4d 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,6 @@ yami-shop-service yami-shop-security yami-shop-quartz - yami-shop-mp @@ -24,25 +23,24 @@ UTF-8 UTF-8 3.7.0 - 2.3.6.RELEASE - 2.3.4.RELEASE + 2.3.12.RELEASE 1.8 28.2-jre - 4.5.0 + 5.7.15 1.11.3 3.17 7.2.18 3.5.0 1.5.4 2.9.2 - 1.9.3 + 1.9.6 4.0.0 4.3.9 1.1.0 3.1.0 - 3.10.6 - 2.57 - + 3.12.5 + 4.0.2 + 2.12.1 2.17.1 @@ -55,11 +53,6 @@ pom import - - org.springframework.security.oauth.boot - spring-security-oauth2-autoconfigure - ${security.oauth.auto.version} - com.github.binarywang weixin-java-pay @@ -138,9 +131,9 @@ - de.ruedigermoeller - fst - ${fst.version} + com.esotericsoftware + kryo + ${kryo.version} org.apache.logging.log4j @@ -157,6 +150,11 @@ log4j-api ${log4j.version} + + com.alibaba + transmittable-thread-local + ${transmittable-thread-local.version} + diff --git a/yami-shop-admin/pom.xml b/yami-shop-admin/pom.xml index d709d47..6140292 100644 --- a/yami-shop-admin/pom.xml +++ b/yami-shop-admin/pom.xml @@ -7,7 +7,6 @@ com.yami.shop yami-shop 0.0.1-SNAPSHOT - ../pom.xml @@ -29,7 +28,7 @@ com.yami.shop - yami-shop-security + yami-shop-security-admin ${yami.shop.version} @@ -37,11 +36,6 @@ yami-shop-quartz ${yami.shop.version} - - com.yami.shop - yami-shop-mp - ${yami.shop.version} - diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/AdminLoginController.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/AdminLoginController.java new file mode 100644 index 0000000..1ccb566 --- /dev/null +++ b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/AdminLoginController.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.admin.controller; + +import cn.hutool.core.util.StrUtil; +import com.anji.captcha.model.common.ResponseModel; +import com.anji.captcha.model.vo.CaptchaVO; +import com.anji.captcha.service.CaptchaService; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.yami.shop.common.exception.YamiShopBindException; +import com.yami.shop.security.admin.dto.CaptchaAuthenticationDTO; +import com.yami.shop.security.common.bo.UserInfoInTokenBO; +import com.yami.shop.security.common.enums.SysTypeEnum; +import com.yami.shop.security.common.manager.PasswordCheckManager; +import com.yami.shop.security.common.manager.PasswordManager; +import com.yami.shop.security.common.manager.TokenStore; +import com.yami.shop.security.common.vo.TokenInfoVO; +import com.yami.shop.sys.constant.Constant; +import com.yami.shop.sys.model.SysMenu; +import com.yami.shop.sys.model.SysUser; +import com.yami.shop.sys.service.SysMenuService; +import com.yami.shop.sys.service.SysUserService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author FrozenWatermelon + * @date 2020/6/30 + */ +@RestController +@Api(tags = "登录") +public class AdminLoginController { + + @Autowired + private TokenStore tokenStore; + + @Autowired + private SysUserService sysUserService; + + @Autowired + private SysMenuService sysMenuService; + + @Autowired + private PasswordCheckManager passwordCheckManager; + + @Autowired + private CaptchaService captchaService; + + @Autowired + private PasswordManager passwordManager; + + @PostMapping("/adminLogin") + @ApiOperation(value = "账号密码 + 验证码登录(用于后台登录)", notes = "通过账号/手机号/用户名密码登录") + public ResponseEntity login( + @Valid @RequestBody CaptchaAuthenticationDTO captchaAuthenticationDTO) { + // 登陆后台登录需要再校验一遍验证码 + CaptchaVO captchaVO = new CaptchaVO(); + captchaVO.setCaptchaVerification(captchaAuthenticationDTO.getCaptchaVerification()); + ResponseModel response = captchaService.verification(captchaVO); + if (!response.isSuccess()) { + return ResponseEntity.badRequest().body("验证码有误或已过期"); + } + + SysUser sysUser = sysUserService.getByUserName(captchaAuthenticationDTO.getUserName()); + if (sysUser == null) { + throw new YamiShopBindException("账号或密码不正确"); + } + + // 半小时内密码输入错误十次,已限制登录30分钟 + String decryptPassword = passwordManager.decryptPassword(captchaAuthenticationDTO.getPassWord()); + passwordCheckManager.checkPassword(SysTypeEnum.ADMIN,captchaAuthenticationDTO.getUserName(), decryptPassword, sysUser.getPassword()); + + // 不是店铺超级管理员,并且是禁用状态,无法登录 + if (Objects.equals(sysUser.getStatus(),0)) { + // 未找到此用户信息 + throw new YamiShopBindException("未找到此用户信息"); + } + + UserInfoInTokenBO userInfoInToken = new UserInfoInTokenBO(); + userInfoInToken.setUserId(String.valueOf(sysUser.getUserId())); + userInfoInToken.setSysType(SysTypeEnum.ADMIN.value()); + userInfoInToken.setEnabled(sysUser.getStatus() == 1); + userInfoInToken.setPerms(getUserPermissions(sysUser.getUserId())); + userInfoInToken.setNickName(sysUser.getUsername()); + userInfoInToken.setShopId(sysUser.getShopId()); + // 存储token返回vo + TokenInfoVO tokenInfoVO = tokenStore.storeAndGetVo(userInfoInToken); + return ResponseEntity.ok(tokenInfoVO); + } + + + private Set getUserPermissions(Long userId) { + List permsList; + + //系统管理员,拥有最高权限 + if(userId == Constant.SUPER_ADMIN_ID){ + List menuList = sysMenuService.list(Wrappers.emptyWrapper()); + permsList = menuList.stream().map(SysMenu::getPerms).collect(Collectors.toList()); + }else{ + permsList = sysUserService.queryAllPerms(userId); + } + return permsList.stream().flatMap((perms)->{ + if (StrUtil.isBlank(perms)) { + return null; + } + return Arrays.stream(perms.trim().split(StrUtil.COMMA)); + } + ).collect(Collectors.toSet()); + } +} diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/AttributeController.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/AttributeController.java index 6b7b232..4301e98 100644 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/AttributeController.java +++ b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/AttributeController.java @@ -10,31 +10,20 @@ package com.yami.shop.admin.controller; -import java.util.Objects; - -import javax.validation.Valid; - +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.yami.shop.bean.enums.ProdPropRule; +import com.yami.shop.bean.model.ProdProp; +import com.yami.shop.common.exception.YamiShopBindException; import com.yami.shop.common.util.PageParam; -import com.yami.shop.common.enums.YamiHttpStatus; - -import com.yami.shop.security.util.SecurityUtils; +import com.yami.shop.security.admin.util.SecurityUtils; +import com.yami.shop.service.ProdPropService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - +import org.springframework.web.bind.annotation.*; -import com.yami.shop.bean.enums.ProdPropRule; -import com.yami.shop.bean.model.ProdProp; -import com.yami.shop.common.exception.YamiShopBindException; -import com.yami.shop.service.ProdPropService; -import com.baomidou.mybatisplus.core.metadata.IPage; +import javax.validation.Valid; +import java.util.Objects; /** * 参数管理 diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/CategoryController.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/CategoryController.java index c1490df..188f2b7 100644 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/CategoryController.java +++ b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/CategoryController.java @@ -10,34 +10,20 @@ package com.yami.shop.admin.controller; -import java.util.Date; -import java.util.List; -import java.util.Objects; - - import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.yami.shop.bean.model.Category; +import com.yami.shop.common.annotation.SysLog; import com.yami.shop.common.exception.YamiShopBindException; -import com.yami.shop.security.util.SecurityUtils; +import com.yami.shop.security.admin.util.SecurityUtils; +import com.yami.shop.service.CategoryService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; - -import com.yami.shop.bean.model.Category; -import com.yami.shop.common.annotation.SysLog; -import com.yami.shop.service.BrandService; -import com.yami.shop.service.CategoryService; -import com.yami.shop.service.ProdPropService; - -import cn.hutool.core.collection.CollectionUtil; +import java.util.Date; +import java.util.List; +import java.util.Objects; diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/HotSearchController.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/HotSearchController.java index a1f43b0..2c382dd 100644 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/HotSearchController.java +++ b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/HotSearchController.java @@ -10,34 +10,21 @@ package com.yami.shop.admin.controller; -import javax.validation.Valid; -import java.util.Date; -import java.util.List; - - import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.yami.shop.security.util.SecurityUtils; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.yami.shop.bean.model.HotSearch; +import com.yami.shop.common.util.PageParam; +import com.yami.shop.security.admin.util.SecurityUtils; +import com.yami.shop.service.HotSearchService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; -import com.yami.shop.common.util.PageParam; -import com.baomidou.mybatisplus.core.metadata.IPage; - - - - +import org.springframework.web.bind.annotation.*; -import com.yami.shop.service.HotSearchService; -import com.yami.shop.bean.model.HotSearch; +import javax.validation.Valid; +import java.util.Date; +import java.util.List; /** * diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/IndexImgController.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/IndexImgController.java index f68f794..8b6c466 100644 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/IndexImgController.java +++ b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/IndexImgController.java @@ -15,7 +15,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.yami.shop.bean.model.IndexImg; import com.yami.shop.bean.model.Product; import com.yami.shop.common.util.PageParam; -import com.yami.shop.security.util.SecurityUtils; +import com.yami.shop.security.admin.util.SecurityUtils; import com.yami.shop.service.IndexImgService; import com.yami.shop.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/NoticeController.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/NoticeController.java index 17b84de..8935292 100644 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/NoticeController.java +++ b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/NoticeController.java @@ -12,10 +12,10 @@ package com.yami.shop.admin.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; -import com.yami.shop.common.util.PageParam; import com.yami.shop.bean.model.Notice; import com.yami.shop.common.annotation.SysLog; -import com.yami.shop.security.util.SecurityUtils; +import com.yami.shop.common.util.PageParam; +import com.yami.shop.security.admin.util.SecurityUtils; import com.yami.shop.service.NoticeService; import lombok.AllArgsConstructor; import org.springframework.http.ResponseEntity; diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/OrderController.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/OrderController.java index 95bfb6c..3e8bf89 100644 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/OrderController.java +++ b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/OrderController.java @@ -10,49 +10,42 @@ package com.yami.shop.admin.controller; -import java.io.IOException; -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletResponse; - +import cn.hutool.core.io.IORuntimeException; +import cn.hutool.core.io.IoUtil; +import cn.hutool.poi.excel.ExcelUtil; +import cn.hutool.poi.excel.ExcelWriter; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.google.common.base.Objects; +import com.yami.shop.bean.enums.OrderStatus; +import com.yami.shop.bean.model.Order; +import com.yami.shop.bean.model.OrderItem; +import com.yami.shop.bean.model.UserAddrOrder; +import com.yami.shop.bean.param.DeliveryOrderParam; import com.yami.shop.bean.param.OrderParam; import com.yami.shop.common.exception.YamiShopBindException; -import com.yami.shop.security.util.SecurityUtils; +import com.yami.shop.common.util.PageParam; +import com.yami.shop.security.admin.util.SecurityUtils; import com.yami.shop.service.*; +import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.Sheet; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.annotation.DateTimeFormat; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.*; - -import com.yami.shop.common.util.PageParam; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.google.common.base.Objects; -import com.yami.shop.bean.enums.OrderStatus; -import com.yami.shop.bean.model.Order; -import com.yami.shop.bean.model.OrderItem; -import com.yami.shop.bean.model.UserAddrOrder; -import com.yami.shop.bean.param.DeliveryOrderParam; - -import cn.hutool.core.io.IORuntimeException; -import cn.hutool.poi.excel.ExcelUtil; -import cn.hutool.poi.excel.ExcelWriter; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Arrays; +import java.util.Date; +import java.util.List; /** * @author lgh on 2018/09/15. */ +@Slf4j @Controller @RequestMapping("/order/order") public class OrderController { @@ -282,16 +275,9 @@ public class OrderController { writer.flush(servletOutputStream); servletOutputStream.flush(); } catch (IORuntimeException | IOException e) { - e.printStackTrace(); + log.error("写出Excel错误:", e); } finally { - writer.close(); - try { - if (servletOutputStream != null) { - servletOutputStream.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } + IoUtil.close(writer); } } } diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/PickAddrController.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/PickAddrController.java index 9416485..36bc60e 100644 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/PickAddrController.java +++ b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/PickAddrController.java @@ -10,36 +10,23 @@ package com.yami.shop.admin.controller; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; - -import javax.validation.Valid; - - +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.yami.shop.bean.model.PickAddr; import com.yami.shop.common.enums.YamiHttpStatus; import com.yami.shop.common.exception.YamiShopBindException; -import com.yami.shop.security.util.SecurityUtils; +import com.yami.shop.common.util.PageParam; +import com.yami.shop.security.admin.util.SecurityUtils; +import com.yami.shop.service.PickAddrService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; - -import com.yami.shop.common.util.PageParam; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.yami.shop.bean.model.PickAddr; -import com.yami.shop.service.PickAddrService; - -import cn.hutool.core.util.StrUtil; +import javax.validation.Valid; +import java.util.Arrays; +import java.util.Objects; diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/ProdTagController.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/ProdTagController.java index ffef4c9..e2277d4 100644 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/ProdTagController.java +++ b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/ProdTagController.java @@ -14,11 +14,11 @@ package com.yami.shop.admin.controller; import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; -import com.yami.shop.common.util.PageParam; import com.yami.shop.bean.model.ProdTag; import com.yami.shop.common.annotation.SysLog; import com.yami.shop.common.exception.YamiShopBindException; -import com.yami.shop.security.util.SecurityUtils; +import com.yami.shop.common.util.PageParam; +import com.yami.shop.security.admin.util.SecurityUtils; import com.yami.shop.service.ProdTagService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/ProductController.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/ProductController.java index 67ba873..e921f8a 100644 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/ProductController.java +++ b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/ProductController.java @@ -14,14 +14,13 @@ import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; -import com.yami.shop.common.util.PageParam; import com.yami.shop.bean.model.Product; import com.yami.shop.bean.model.Sku; import com.yami.shop.bean.param.ProductParam; -import com.yami.shop.common.enums.YamiHttpStatus; import com.yami.shop.common.exception.YamiShopBindException; import com.yami.shop.common.util.Json; -import com.yami.shop.security.util.SecurityUtils; +import com.yami.shop.common.util.PageParam; +import com.yami.shop.security.admin.util.SecurityUtils; import com.yami.shop.service.BasketService; import com.yami.shop.service.ProdTagReferenceService; import com.yami.shop.service.ProductService; diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/ShopDetailController.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/ShopDetailController.java index 8e7d6b7..45b3482 100644 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/ShopDetailController.java +++ b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/ShopDetailController.java @@ -10,31 +10,25 @@ package com.yami.shop.admin.controller; -import java.util.Date; -import java.util.List; -import java.util.stream.Collectors; - -import javax.validation.Valid; - - +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.yami.shop.security.util.SecurityUtils; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.yami.shop.bean.model.ShopDetail; +import com.yami.shop.bean.param.ShopDetailParam; +import com.yami.shop.common.util.PageParam; +import com.yami.shop.security.admin.util.SecurityUtils; +import com.yami.shop.service.ShopDetailService; +import ma.glasnost.orika.MapperFacade; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; - -import com.yami.shop.common.util.PageParam; -import com.baomidou.mybatisplus.core.metadata.IPage; - -import com.yami.shop.bean.model.ShopDetail; -import com.yami.shop.bean.param.ShopDetailParam; -import com.yami.shop.service.ShopDetailService; - -import cn.hutool.core.util.StrUtil; -import ma.glasnost.orika.MapperFacade; +import javax.validation.Valid; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/SpecController.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/SpecController.java index b1ae4be..e4976d8 100644 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/SpecController.java +++ b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/SpecController.java @@ -10,36 +10,24 @@ package com.yami.shop.admin.controller; -import java.util.List; -import java.util.Objects; - import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.yami.shop.common.enums.YamiHttpStatus; - -import com.yami.shop.security.util.SecurityUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import com.yami.shop.common.util.PageParam; import com.baomidou.mybatisplus.core.metadata.IPage; - import com.yami.shop.bean.enums.ProdPropRule; import com.yami.shop.bean.model.ProdProp; import com.yami.shop.bean.model.ProdPropValue; import com.yami.shop.common.exception.YamiShopBindException; +import com.yami.shop.common.util.PageParam; +import com.yami.shop.security.admin.util.SecurityUtils; import com.yami.shop.service.ProdPropService; import com.yami.shop.service.ProdPropValueService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; import javax.validation.Valid; +import java.util.List; +import java.util.Objects; /** * 规格管理 diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/TransportController.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/TransportController.java index 305d0b3..edbfdf5 100644 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/TransportController.java +++ b/yami-shop-admin/src/main/java/com/yami/shop/admin/controller/TransportController.java @@ -10,31 +10,20 @@ package com.yami.shop.admin.controller; -import java.util.Date; -import java.util.List; - import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.yami.shop.security.util.SecurityUtils; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.yami.shop.bean.model.Transport; +import com.yami.shop.common.util.PageParam; +import com.yami.shop.security.admin.util.SecurityUtils; +import com.yami.shop.service.TransportService; import org.apache.commons.lang3.StringUtils; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; - -import com.yami.shop.common.util.PageParam; -import com.baomidou.mybatisplus.core.metadata.IPage; - -import com.yami.shop.bean.model.Transport; -import com.yami.shop.service.TransportService; +import java.util.Date; +import java.util.List; /** * @author lgh on 2018/11/16. diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/security/AdminAuthenticationToken.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/security/AdminAuthenticationToken.java deleted file mode 100644 index 2f26350..0000000 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/security/AdminAuthenticationToken.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.admin.security; - -import com.yami.shop.security.token.MyAuthenticationToken; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import org.springframework.security.core.userdetails.UserDetails; - -/** - * 系统用户账号密码登陆 - */ -@Getter -@Setter -@NoArgsConstructor -public class AdminAuthenticationToken extends MyAuthenticationToken { - - private String sessionUUID; - - private String imageCode; - - public AdminAuthenticationToken(UserDetails principal, Object credentials) { - super(principal, credentials, principal.getAuthorities()); - } - - -} diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/security/AdminTokenEnhancer.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/security/AdminTokenEnhancer.java deleted file mode 100644 index a554b96..0000000 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/security/AdminTokenEnhancer.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.yami.shop.admin.security; - -import com.yami.shop.security.service.YamiSysUser; -import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; -import org.springframework.security.oauth2.common.OAuth2AccessToken; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.token.TokenEnhancer; -import org.springframework.stereotype.Component; - -import java.util.HashMap; -import java.util.Map; - -/** - * token增强 - * @author LGH - */ -@Component -public class AdminTokenEnhancer implements TokenEnhancer { - - - @Override - public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { - final Map additionalInfo = new HashMap<>(8); - YamiSysUser yamiSysUser = (YamiSysUser) authentication.getUserAuthentication().getPrincipal(); - additionalInfo.put("shopId", yamiSysUser.getShopId()); - additionalInfo.put("userId", yamiSysUser.getUserId()); - additionalInfo.put("authorities", yamiSysUser.getAuthorities()); - ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo); - return accessToken; - } -} diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/security/LoginAuthenticationFilter.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/security/LoginAuthenticationFilter.java deleted file mode 100644 index 99cd6ca..0000000 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/security/LoginAuthenticationFilter.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.admin.security; - -import cn.hutool.core.util.StrUtil; -import cn.hutool.extra.servlet.ServletUtil; -import com.yami.shop.common.util.Json; -import com.yami.shop.common.util.RedisUtil; -import com.yami.shop.security.constants.SecurityConstants; -import com.yami.shop.security.exception.BadCredentialsExceptionBase; -import com.yami.shop.security.exception.ImageCodeNotMatchExceptionBase; -import com.yami.shop.security.exception.UsernameNotFoundExceptionBase; -import com.yami.shop.security.provider.AuthenticationTokenParser; -import com.yami.shop.security.service.YamiUserDetailsService; -import lombok.AllArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.AbstractAuthenticationToken; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.AuthenticationServiceException; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -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.password.PasswordEncoder; -import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.stereotype.Component; - -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -/** - * 管理员登陆: - * post: http://127.0.0.1:8085/login - * {principal:username,credentials:password} - */ -@Component -public class LoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter { - - private YamiUserDetailsService yamiUserDetailsService; - - private PasswordEncoder passwordEncoder; - - @Autowired - public LoginAuthenticationFilter(YamiUserDetailsService yamiUserDetailsService, PasswordEncoder passwordEncoder) { - super("/login"); - this.yamiUserDetailsService = yamiUserDetailsService; - this.passwordEncoder = passwordEncoder; - } - - @Override - public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { - if (!ServletUtil.METHOD_POST.equals(request.getMethod())) { - throw new AuthenticationServiceException( - "Authentication method not supported: " + request.getMethod()); - } - String requestBody = getStringFromStream(request); - - if (StrUtil.isBlank(requestBody)) { - throw new AuthenticationServiceException("无法获取输入信息"); - } - AdminAuthenticationToken adminAuthenticationToken = Json.parseObject(requestBody, AdminAuthenticationToken.class); - - - String username = adminAuthenticationToken.getPrincipal() == null?"NONE_PROVIDED":adminAuthenticationToken.getName(); - - - String kaptchaKey = SecurityConstants.SPRING_SECURITY_RESTFUL_IMAGE_CODE + adminAuthenticationToken.getSessionUUID(); - - String kaptcha = RedisUtil.get(kaptchaKey); - - RedisUtil.del(kaptchaKey); - - if(StrUtil.isBlank(adminAuthenticationToken.getImageCode()) || !adminAuthenticationToken.getImageCode().equalsIgnoreCase(kaptcha)){ - throw new ImageCodeNotMatchExceptionBase("验证码有误"); - } - - UserDetails user; - try { - user = yamiUserDetailsService.loadUserByUsername(username); - } catch (UsernameNotFoundExceptionBase var6) { - throw new UsernameNotFoundExceptionBase("账号或密码不正确"); - } - - String encodedPassword = user.getPassword(); - String rawPassword = adminAuthenticationToken.getCredentials().toString(); - - // 密码不正确 - if (!passwordEncoder.matches(rawPassword,encodedPassword)){ - throw new BadCredentialsExceptionBase("账号或密码不正确"); - } - - if (!user.isEnabled()) { - throw new UsernameNotFoundExceptionBase("账号已被锁定,请联系管理员"); - } - AdminAuthenticationToken result = new AdminAuthenticationToken(user, adminAuthenticationToken.getCredentials()); - result.setDetails(adminAuthenticationToken.getDetails()); - return result; - } - - - private String getStringFromStream(HttpServletRequest req) { - ServletInputStream is; - try { - is = req.getInputStream(); - int nRead = 1; - int nTotalRead = 0; - byte[] bytes = new byte[10240]; - while (nRead > 0) { - nRead = is.read(bytes, nTotalRead, bytes.length - nTotalRead); - if (nRead > 0) { - nTotalRead = nTotalRead + nRead; - } - } - return new String(bytes, 0, nTotalRead, StandardCharsets.UTF_8); - } catch (IOException e) { - e.printStackTrace(); - return ""; - } - } - - @Override - @Autowired - public void setAuthenticationManager(AuthenticationManager authenticationManager) { - super.setAuthenticationManager(authenticationManager); - } - - @Override - @Autowired - public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) { - super.setAuthenticationSuccessHandler(successHandler); - } - - @Override - @Autowired - public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) { - super.setAuthenticationFailureHandler(failureHandler); - } - -} diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/security/ResourceServerConfiguration.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/security/ResourceServerConfiguration.java deleted file mode 100644 index 0cdd65d..0000000 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/security/ResourceServerConfiguration.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.admin.security; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; -import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.web.cors.CorsUtils; - -@Configuration -@EnableResourceServer -@EnableGlobalMethodSecurity(prePostEnabled = true) -public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { - - @Autowired - private LoginAuthenticationFilter loginAuthenticationFilter; - - @Override - public void configure(HttpSecurity http) throws Exception { - // @formatter:off - http - .addFilterBefore(loginAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) - .csrf().disable().cors() - .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) - .and().authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll() - .and().requestMatchers().anyRequest() - .and().anonymous() - .and().authorizeRequests() - .antMatchers( - "/webjars/**", - "/swagger/**", - "/v2/api-docs", - "/doc.html", - "/swagger-ui.html", - "/swagger-resources/**", - "/captcha.jpg").permitAll() - .and() - .authorizeRequests() - .antMatchers("/**").authenticated();//配置所有访问控制,必须认证过后才可以访问 - // @formatter:on - } - - -} diff --git a/yami-shop-admin/src/main/java/com/yami/shop/admin/security/YamiSysUserDetailsServiceImpl.java b/yami-shop-admin/src/main/java/com/yami/shop/admin/security/YamiSysUserDetailsServiceImpl.java deleted file mode 100644 index 7152fba..0000000 --- a/yami-shop-admin/src/main/java/com/yami/shop/admin/security/YamiSysUserDetailsServiceImpl.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.admin.security; - -import cn.hutool.core.util.StrUtil; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import com.yami.shop.bean.model.User; -import com.yami.shop.common.util.CacheManagerUtil; -import com.yami.shop.sys.constant.Constant; -import com.yami.shop.security.enums.App; -import com.yami.shop.security.exception.UsernameNotFoundExceptionBase; -import com.yami.shop.security.model.AppConnect; -import com.yami.shop.security.service.YamiSysUser; -import com.yami.shop.security.service.YamiUser; -import com.yami.shop.security.service.YamiUserDetailsService; -import com.yami.shop.sys.dao.SysMenuMapper; -import com.yami.shop.sys.dao.SysUserMapper; -import com.yami.shop.sys.model.SysMenu; -import com.yami.shop.sys.model.SysUser; -import lombok.AllArgsConstructor; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.AuthorityUtils; -import org.springframework.stereotype.Service; - -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * 用户详细信息 - * - * @author - */ -@Slf4j -@Service -@AllArgsConstructor -public class YamiSysUserDetailsServiceImpl implements YamiUserDetailsService { - private final SysMenuMapper sysMenuMapper; - private final SysUserMapper sysUserMapper; - private final CacheManagerUtil cacheManagerUtil; - - /** - * 用户密码登录 - * - * @param username 用户名 - * @return - * @throws UsernameNotFoundExceptionBase - */ - @Override - @SneakyThrows - public YamiSysUser loadUserByUsername(String username) { - return getUserDetails(username); - } - - - /** - * 构建userdetails - * - * @param username 用户名称 - * @return - */ - private YamiSysUser getUserDetails(String username) { - SysUser sysUser = sysUserMapper.selectByUsername(username); - - if (sysUser == null) { - throw new UsernameNotFoundExceptionBase("用户不存在"); - } - - Collection authorities - = AuthorityUtils.createAuthorityList(getUserPermissions(sysUser.getUserId()).toArray(new String[0])); - // 构造security用户 - return new YamiSysUser(sysUser.getUserId(), sysUser.getShopId(), sysUser.getUsername(), sysUser.getPassword(), sysUser.getStatus() == 1, - true, true, true , authorities); - } - - private Set getUserPermissions(Long userId) { - List permsList; - - //系统管理员,拥有最高权限 - if(userId == Constant.SUPER_ADMIN_ID){ - List menuList = sysMenuMapper.selectList(Wrappers.emptyWrapper()); - - - permsList = menuList.stream().map(SysMenu::getPerms).collect(Collectors.toList()); - }else{ - permsList = sysUserMapper.queryAllPerms(userId); - } - - - Set permsSet = permsList.stream().flatMap((perms)->{ - if (StrUtil.isBlank(perms)) { - return null; - } - return Arrays.stream(perms.trim().split(",")); - } - ).collect(Collectors.toSet()); - return permsSet; - } - - @Override - public YamiUser loadUserByAppIdAndBizUserId(App app, String bizUserId) { - return null; - } - - @Override - public void insertUserIfNecessary(AppConnect appConnect) { - - } - - @Override - public YamiUser loadUserByUserMail(String userMail, String loginPassword) { - return null; - } - - @Override - public User loadUserByMobileOrUserName(String mobileOrUserName, Integer loginType) { - return null; - } - - @Override - public YamiUser getYamiUser(Integer appId, User user, String bizUserId) { - return null; - } -} diff --git a/yami-shop-admin/src/main/resources/application-dev.yml b/yami-shop-admin/src/main/resources/application-dev.yml index bf3f59a..65da3e6 100644 --- a/yami-shop-admin/src/main/resources/application-dev.yml +++ b/yami-shop-admin/src/main/resources/application-dev.yml @@ -19,6 +19,6 @@ spring: cache-null-values: true redis: redisson: - config: classpath:redisson.yml + config: classpath:redisson/redisson.yml logging: - config: classpath:logback-dev.xml + config: classpath:logback/logback-dev.xml diff --git a/yami-shop-admin/src/main/resources/application-docker.yml b/yami-shop-admin/src/main/resources/application-docker.yml index a3ce25d..93b5a7a 100644 --- a/yami-shop-admin/src/main/resources/application-docker.yml +++ b/yami-shop-admin/src/main/resources/application-docker.yml @@ -15,6 +15,6 @@ spring: connection-test-query: SELECT 1 redis: redisson: - config: classpath:redisson-docker.yml + config: classpath:redisson/redisson-docker.yml logging: - config: classpath:logback-prod.xml + config: classpath:logback/logback-prod.xml diff --git a/yami-shop-admin/src/main/resources/application-prod.yml b/yami-shop-admin/src/main/resources/application-prod.yml index ebbc1ee..05652c6 100644 --- a/yami-shop-admin/src/main/resources/application-prod.yml +++ b/yami-shop-admin/src/main/resources/application-prod.yml @@ -15,6 +15,6 @@ spring: connection-test-query: SELECT 1 redis: redisson: - config: classpath:redisson.yml + config: classpath:redisson/redisson.yml logging: - config: classpath:logback-prod.xml + config: classpath:logback/logback-prod.xml diff --git a/yami-shop-admin/src/main/resources/logback-dev.xml b/yami-shop-admin/src/main/resources/logback/logback-dev.xml similarity index 100% rename from yami-shop-admin/src/main/resources/logback-dev.xml rename to yami-shop-admin/src/main/resources/logback/logback-dev.xml diff --git a/yami-shop-admin/src/main/resources/logback-prod.xml b/yami-shop-admin/src/main/resources/logback/logback-prod.xml similarity index 100% rename from yami-shop-admin/src/main/resources/logback-prod.xml rename to yami-shop-admin/src/main/resources/logback/logback-prod.xml diff --git a/yami-shop-api/src/main/resources/redisson-docker.yml b/yami-shop-admin/src/main/resources/redisson/redisson-docker.yml similarity index 77% rename from yami-shop-api/src/main/resources/redisson-docker.yml rename to yami-shop-admin/src/main/resources/redisson/redisson-docker.yml index 4ba23b7..46e08da 100644 --- a/yami-shop-api/src/main/resources/redisson-docker.yml +++ b/yami-shop-admin/src/main/resources/redisson/redisson-docker.yml @@ -4,28 +4,25 @@ singleServerConfig: database: ${REDIS_DATABASE} password: ${REDIS_PASSWORD} idleConnectionTimeout: 10000 - pingTimeout: 1000 connectTimeout: 10000 timeout: 3000 retryAttempts: 3 retryInterval: 1500 - reconnectionTimeout: 3000 - failedAttempts: 3 clientName: null # 发布和订阅连接的最小空闲连接数 默认1 subscriptionConnectionMinimumIdleSize: 1 # 发布和订阅连接池大小 默认50 - subscriptionConnectionPoolSize: 10 + subscriptionConnectionPoolSize: 1 # 单个连接最大订阅数量 默认5 - subscriptionsPerConnection: 5 + subscriptionsPerConnection: 1 # 最小空闲连接数 默认32,现在暂时不需要那么多的线程 - connectionMinimumIdleSize: 4 + connectionMinimumIdleSize: 2 # connectionPoolSize 默认64,现在暂时不需要那么多的线程 - connectionPoolSize: 20 + connectionPoolSize: 4 # 这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。 threads: 0 # 这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。 nettyThreads: 0 codec: - class: com.yami.shop.common.serializer.redisson.FstCodec -transportMode: NIO \ No newline at end of file + class: org.redisson.codec.KryoCodec +transportMode: NIO diff --git a/yami-shop-admin/src/main/resources/redisson.yml b/yami-shop-admin/src/main/resources/redisson/redisson.yml similarity index 77% rename from yami-shop-admin/src/main/resources/redisson.yml rename to yami-shop-admin/src/main/resources/redisson/redisson.yml index 1c8989e..01883be 100644 --- a/yami-shop-admin/src/main/resources/redisson.yml +++ b/yami-shop-admin/src/main/resources/redisson/redisson.yml @@ -4,28 +4,25 @@ singleServerConfig: database: 0 password: null idleConnectionTimeout: 10000 - pingTimeout: 1000 connectTimeout: 10000 timeout: 3000 retryAttempts: 3 retryInterval: 1500 - reconnectionTimeout: 3000 - failedAttempts: 3 clientName: null # 发布和订阅连接的最小空闲连接数 默认1 subscriptionConnectionMinimumIdleSize: 1 # 发布和订阅连接池大小 默认50 - subscriptionConnectionPoolSize: 10 + subscriptionConnectionPoolSize: 1 # 单个连接最大订阅数量 默认5 - subscriptionsPerConnection: 5 + subscriptionsPerConnection: 1 # 最小空闲连接数 默认32,现在暂时不需要那么多的线程 - connectionMinimumIdleSize: 4 + connectionMinimumIdleSize: 2 # connectionPoolSize 默认64,现在暂时不需要那么多的线程 - connectionPoolSize: 20 + connectionPoolSize: 4 # 这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。 threads: 0 # 这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。 nettyThreads: 0 codec: - class: com.yami.shop.common.serializer.redisson.FstCodec -transportMode: NIO \ No newline at end of file + class: org.redisson.codec.KryoCodec +transportMode: NIO diff --git a/yami-shop-api/pom.xml b/yami-shop-api/pom.xml index d1da7cf..d797674 100644 --- a/yami-shop-api/pom.xml +++ b/yami-shop-api/pom.xml @@ -20,12 +20,7 @@ com.yami.shop - yami-shop-security - ${yami.shop.version} - - - com.yami.shop - yami-shop-mp + yami-shop-security-api ${yami.shop.version} diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/controller/AddrController.java b/yami-shop-api/src/main/java/com/yami/shop/api/controller/AddrController.java index 6c88ce9..8dcd9a7 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/controller/AddrController.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/controller/AddrController.java @@ -10,36 +10,25 @@ package com.yami.shop.api.controller; -import java.util.Date; -import java.util.List; - -import javax.validation.Valid; - import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.yami.shop.common.exception.YamiShopBindException; -import com.yami.shop.security.util.SecurityUtils; -import lombok.AllArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - import com.yami.shop.bean.app.dto.UserAddrDto; import com.yami.shop.bean.app.param.AddrParam; import com.yami.shop.bean.model.UserAddr; +import com.yami.shop.common.exception.YamiShopBindException; +import com.yami.shop.security.api.util.SecurityUtils; import com.yami.shop.service.UserAddrService; - import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; +import lombok.AllArgsConstructor; import ma.glasnost.orika.MapperFacade; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.Date; +import java.util.List; @RestController diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/controller/MyOrderController.java b/yami-shop-api/src/main/java/com/yami/shop/api/controller/MyOrderController.java index 6a0d47b..f92a299 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/controller/MyOrderController.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/controller/MyOrderController.java @@ -10,37 +10,30 @@ package com.yami.shop.api.controller; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Objects; - import com.baomidou.mybatisplus.core.metadata.IPage; -import com.yami.shop.bean.enums.OrderStatus; -import com.yami.shop.common.exception.YamiShopBindException; -import com.yami.shop.common.util.PageParam; import com.yami.shop.bean.app.dto.*; -import com.yami.shop.dao.OrderMapper; -import com.yami.shop.security.util.SecurityUtils; -import com.yami.shop.service.*; -import lombok.AllArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - - +import com.yami.shop.bean.enums.OrderStatus; import com.yami.shop.bean.model.Order; import com.yami.shop.bean.model.OrderItem; import com.yami.shop.bean.model.ShopDetail; import com.yami.shop.bean.model.UserAddrOrder; +import com.yami.shop.common.exception.YamiShopBindException; import com.yami.shop.common.util.Arith; - +import com.yami.shop.common.util.PageParam; +import com.yami.shop.security.api.util.SecurityUtils; +import com.yami.shop.service.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; +import lombok.AllArgsConstructor; import ma.glasnost.orika.MapperFacade; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; @RestController @RequestMapping("/p/myOrder") diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/controller/OrderController.java b/yami-shop-api/src/main/java/com/yami/shop/api/controller/OrderController.java index 794c0d5..9671c3c 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/controller/OrderController.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/controller/OrderController.java @@ -10,15 +10,21 @@ package com.yami.shop.api.controller; -import java.util.*; - -import javax.validation.Valid; - +import cn.hutool.core.collection.CollectionUtil; import com.yami.shop.bean.app.dto.*; +import com.yami.shop.bean.app.param.OrderParam; +import com.yami.shop.bean.app.param.OrderShopParam; +import com.yami.shop.bean.app.param.SubmitOrderParam; import com.yami.shop.bean.event.ConfirmOrderEvent; +import com.yami.shop.bean.model.Order; +import com.yami.shop.bean.model.UserAddr; import com.yami.shop.common.exception.YamiShopBindException; -import com.yami.shop.security.util.SecurityUtils; +import com.yami.shop.common.util.Arith; +import com.yami.shop.security.api.util.SecurityUtils; import com.yami.shop.service.*; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import ma.glasnost.orika.MapperFacade; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.http.ResponseEntity; @@ -27,17 +33,10 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.yami.shop.bean.app.param.OrderParam; -import com.yami.shop.bean.app.param.OrderShopParam; -import com.yami.shop.bean.app.param.SubmitOrderParam; -import com.yami.shop.bean.model.Order; -import com.yami.shop.bean.model.UserAddr; -import com.yami.shop.common.util.Arith; - -import cn.hutool.core.collection.CollectionUtil; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import ma.glasnost.orika.MapperFacade; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; @RestController @RequestMapping("/p/order") diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/controller/PayController.java b/yami-shop-api/src/main/java/com/yami/shop/api/controller/PayController.java index 7855613..81aa697 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/controller/PayController.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/controller/PayController.java @@ -10,18 +10,11 @@ package com.yami.shop.api.controller; -import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; -import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; -import com.github.binarywang.wxpay.constant.WxPayConstants; -import com.github.binarywang.wxpay.service.WxPayService; -import com.yami.shop.api.config.ApiConfig; import com.yami.shop.bean.app.param.PayParam; import com.yami.shop.bean.pay.PayInfoDto; -import com.yami.shop.common.util.Arith; -import com.yami.shop.common.util.IPHelper; -import com.yami.shop.security.service.YamiUser; -import com.yami.shop.security.util.SecurityUtils; +import com.yami.shop.security.api.model.YamiUser; +import com.yami.shop.security.api.util.SecurityUtils; import com.yami.shop.service.PayService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -33,8 +26,6 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - @RestController @RequestMapping("/p/order") @Api(tags = "订单接口") @@ -43,10 +34,6 @@ public class PayController { private final PayService payService; - private final ApiConfig apiConfig; - - private final WxPayService wxMiniPayService; - /** * 支付接口 */ @@ -56,21 +43,11 @@ public class PayController { public ResponseEntity pay(@RequestBody PayParam payParam) { YamiUser user = SecurityUtils.getUser(); String userId = user.getUserId(); - String openId = user.getBizUserId(); PayInfoDto payInfo = payService.pay(userId, payParam); - - WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest(); - orderRequest.setBody(payInfo.getBody()); - orderRequest.setOutTradeNo(payInfo.getPayNo()); - orderRequest.setTotalFee((int) Arith.mul(payInfo.getPayAmount(), 100)); - orderRequest.setSpbillCreateIp(IPHelper.getIpAddr()); - orderRequest.setNotifyUrl(apiConfig.getDomainName() + "/notice/pay/order"); - orderRequest.setTradeType(WxPayConstants.TradeType.JSAPI); - orderRequest.setOpenid(openId); - - return ResponseEntity.ok(wxMiniPayService.createOrder(orderRequest)); + payService.paySuccess(payInfo.getPayNo(), ""); + return ResponseEntity.ok().build(); } /** diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/controller/PayNoticeController.java b/yami-shop-api/src/main/java/com/yami/shop/api/controller/PayNoticeController.java index bade51c..9a86416 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/controller/PayNoticeController.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/controller/PayNoticeController.java @@ -10,13 +10,7 @@ package com.yami.shop.api.controller; -import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; -import com.github.binarywang.wxpay.exception.WxPayException; -import com.github.binarywang.wxpay.service.WxPayService; -import com.yami.shop.service.PayService; import lombok.AllArgsConstructor; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import springfox.documentation.annotations.ApiIgnore; @@ -26,26 +20,26 @@ import springfox.documentation.annotations.ApiIgnore; @RequestMapping("/notice/pay") @AllArgsConstructor public class PayNoticeController { - - /** - * 小程序支付 - */ - private final WxPayService wxMiniPayService; - - private final PayService payService; - - - @RequestMapping("/order") - public ResponseEntity submit(@RequestBody String xmlData) throws WxPayException { - WxPayOrderNotifyResult parseOrderNotifyResult = wxMiniPayService.parseOrderNotifyResult(xmlData); - - String payNo = parseOrderNotifyResult.getOutTradeNo(); - String bizPayNo = parseOrderNotifyResult.getTransactionId(); - - // 根据内部订单号更新order settlement - payService.paySuccess(payNo, bizPayNo); - - - return ResponseEntity.ok().build(); - } +//模拟支付不需要回调 +// /** +// * 小程序支付 +// */ +// private final WxPayService wxMiniPayService; +// +// private final PayService payService; +// +// +// @RequestMapping("/order") +// public ResponseEntity submit(@RequestBody String xmlData) throws WxPayException { +// WxPayOrderNotifyResult parseOrderNotifyResult = wxMiniPayService.parseOrderNotifyResult(xmlData); +// +// String payNo = parseOrderNotifyResult.getOutTradeNo(); +// String bizPayNo = parseOrderNotifyResult.getTransactionId(); +// +// // 根据内部订单号更新order settlement +// payService.paySuccess(payNo, bizPayNo); +// +// +// return ResponseEntity.ok().build(); +// } } \ No newline at end of file diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/controller/ProdCommController.java b/yami-shop-api/src/main/java/com/yami/shop/api/controller/ProdCommController.java index baf6b25..cb52945 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/controller/ProdCommController.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/controller/ProdCommController.java @@ -12,14 +12,12 @@ package com.yami.shop.api.controller; import com.baomidou.mybatisplus.core.metadata.IPage; -import com.yami.shop.common.util.PageParam; import com.yami.shop.bean.app.dto.ProdCommDataDto; import com.yami.shop.bean.app.dto.ProdCommDto; import com.yami.shop.bean.app.param.ProdCommParam; import com.yami.shop.bean.model.ProdComm; -import com.yami.shop.common.util.Json; import com.yami.shop.common.util.PageParam; -import com.yami.shop.security.util.SecurityUtils; +import com.yami.shop.security.api.util.SecurityUtils; import com.yami.shop.service.ProdCommService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/controller/ShopCartController.java b/yami-shop-api/src/main/java/com/yami/shop/api/controller/ShopCartController.java index 3ee7e65..d9c7549 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/controller/ShopCartController.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/controller/ShopCartController.java @@ -12,24 +12,31 @@ package com.yami.shop.api.controller; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.ArrayUtil; import com.google.common.collect.Lists; import com.yami.shop.bean.app.dto.*; import com.yami.shop.bean.app.param.ChangeShopCartParam; import com.yami.shop.bean.app.param.ShopCartParam; import com.yami.shop.bean.event.ShopCartEvent; -import com.yami.shop.bean.model.*; +import com.yami.shop.bean.model.Basket; +import com.yami.shop.bean.model.Product; +import com.yami.shop.bean.model.Sku; import com.yami.shop.common.util.Arith; -import com.yami.shop.security.util.SecurityUtils; -import com.yami.shop.service.*; -import io.swagger.annotations.*; +import com.yami.shop.security.api.util.SecurityUtils; +import com.yami.shop.service.BasketService; +import com.yami.shop.service.ProductService; +import com.yami.shop.service.SkuService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import org.springframework.context.ApplicationContext; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; -import java.util.*; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; @RestController diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/controller/SmsController.java b/yami-shop-api/src/main/java/com/yami/shop/api/controller/SmsController.java index 40381db..5be90ea 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/controller/SmsController.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/controller/SmsController.java @@ -10,21 +10,19 @@ package com.yami.shop.api.controller; -import com.yami.shop.security.util.SecurityUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - import com.google.common.collect.Maps; import com.yami.shop.bean.app.param.SendSmsParam; import com.yami.shop.bean.enums.SmsType; +import com.yami.shop.security.api.util.SecurityUtils; import com.yami.shop.service.SmsLogService; - import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/p/sms") diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserCollectionController.java b/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserCollectionController.java index 34bb6b1..2954926 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserCollectionController.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserCollectionController.java @@ -19,7 +19,7 @@ import com.yami.shop.bean.model.Product; import com.yami.shop.bean.model.UserCollection; import com.yami.shop.common.exception.YamiShopBindException; import com.yami.shop.common.util.PageParam; -import com.yami.shop.security.util.SecurityUtils; +import com.yami.shop.security.api.util.SecurityUtils; import com.yami.shop.service.ProductService; import com.yami.shop.service.UserCollectionService; import io.swagger.annotations.Api; diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserController.java b/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserController.java index 95bc36b..9db81c9 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserController.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserController.java @@ -10,32 +10,18 @@ package com.yami.shop.api.controller; -import cn.hutool.core.util.StrUtil; -import com.yami.shop.common.util.CacheManagerUtil; -import com.yami.shop.security.enums.App; -import com.yami.shop.security.service.YamiUser; -import com.yami.shop.security.util.SecurityUtils; -import lombok.AllArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; -import org.springframework.security.oauth2.provider.token.ConsumerTokenServices; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - +import cn.hutool.extra.emoji.EmojiUtil; import com.yami.shop.bean.app.dto.UserDto; import com.yami.shop.bean.app.param.UserInfoParam; import com.yami.shop.bean.model.User; +import com.yami.shop.security.api.util.SecurityUtils; import com.yami.shop.service.UserService; - -import cn.hutool.extra.emoji.EmojiUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import lombok.AllArgsConstructor; import ma.glasnost.orika.MapperFacade; - -import javax.servlet.http.HttpServletRequest; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/p/user") @@ -46,10 +32,6 @@ public class UserController { private final UserService userService; private final MapperFacade mapperFacade; - - private final CacheManagerUtil cacheManagerUtil; - - private final ConsumerTokenServices consumerTokenServices; /** * 查看用户接口 */ @@ -71,18 +53,6 @@ public class UserController { user.setPic(userInfoParam.getAvatarUrl()); user.setNickName(EmojiUtil.toAlias(userInfoParam.getNickName())); userService.updateById(user); - String cacheKey = App.MINI.value() + StrUtil.COLON + SecurityUtils.getUser().getBizUserId(); - cacheManagerUtil.evictCache("yami_user", cacheKey); - return ResponseEntity.ok(null); - } - - /** - * 退出登录,并清除redis中的token - **/ - @GetMapping("/logout") - public Boolean removeToken(HttpServletRequest httpRequest){ - String authorization = httpRequest.getHeader("authorization"); - String token = authorization.replace("bearer", ""); - return consumerTokenServices.revokeToken(token); + return ResponseEntity.ok().build(); } } diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserRegisterController.java b/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserRegisterController.java index 7cfbcb9..bf1dd4a 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserRegisterController.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserRegisterController.java @@ -1,40 +1,27 @@ package com.yami.shop.api.controller; -import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; +import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.yami.shop.api.security.AuthenticationToken; -import com.yami.shop.bean.enums.SmsType; import com.yami.shop.bean.model.User; import com.yami.shop.bean.param.UserRegisterParam; import com.yami.shop.common.exception.YamiShopBindException; -import com.yami.shop.common.util.IPHelper; -import com.yami.shop.common.util.PrincipalUtil; -import com.yami.shop.mp.config.WxMaConfiguration; -import com.yami.shop.security.enums.App; -import com.yami.shop.security.handler.LoginAuthSuccessHandler; -import com.yami.shop.security.model.AppConnect; -import com.yami.shop.security.service.AppConnectService; -import com.yami.shop.security.service.YamiUser; -import com.yami.shop.security.service.YamiUserDetailsService; -import com.yami.shop.security.util.SecurityUtils; -import com.yami.shop.service.SmsLogService; +import com.yami.shop.security.common.bo.UserInfoInTokenBO; +import com.yami.shop.security.common.enums.SysTypeEnum; +import com.yami.shop.security.common.manager.PasswordManager; +import com.yami.shop.security.common.manager.TokenStore; +import com.yami.shop.security.common.vo.TokenInfoVO; import com.yami.shop.service.UserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.oauth2.provider.token.ConsumerTokenServices; import org.springframework.web.bind.annotation.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.util.Date; -import java.util.Objects; /** * 用户信息 @@ -49,182 +36,66 @@ public class UserRegisterController { private final UserService userService; - private final SmsLogService smsLogService; - - private final AppConnectService appConnectService; - - private final LoginAuthSuccessHandler loginAuthSuccessHandler; - - private final WxMaConfiguration wxConfig; - - private final YamiUserDetailsService yamiUserDetailsService; - private final PasswordEncoder passwordEncoder; - public static final String CHECK_REGISTER_SMS_FLAG = "checkRegisterSmsFlag"; + private final TokenStore tokenStore; - public static final String CHECK_UPDATE_PWD_SMS_FLAG = "updatePwdSmsFlag"; + private final PasswordManager passwordManager; @PostMapping("/register") @ApiOperation(value = "注册", notes = "用户注册或绑定手机号接口") - public ResponseEntity register(@Valid @RequestBody UserRegisterParam userRegisterParam) { - userRegisterParam.setPassword(passwordEncoder.encode(userRegisterParam.getPassword())); - return ResponseEntity.ok(userService.insertUser(userRegisterParam)); + public ResponseEntity register(@Valid @RequestBody UserRegisterParam userRegisterParam) { + if (StrUtil.isBlank(userRegisterParam.getNickName())) { + userRegisterParam.setNickName(userRegisterParam.getUserName()); + } + // 正在进行申请注册 + if (userService.count(new LambdaQueryWrapper().eq(User::getNickName, userRegisterParam.getNickName())) > 0) { + // 该用户名已注册,无法重新注册 + throw new YamiShopBindException("该用户名已注册,无法重新注册"); + } + Date now = new Date(); + User user = new User(); + user.setModifyTime(now); + user.setUserRegtime(now); + user.setStatus(1); + user.setNickName(userRegisterParam.getNickName()); + user.setUserMail(userRegisterParam.getUserMail()); + String decryptPassword = passwordManager.decryptPassword(userRegisterParam.getPassWord()); + user.setLoginPassword(passwordEncoder.encode(decryptPassword)); + String userId = IdUtil.simpleUUID(); + user.setUserId(userId); + userService.save(user); + // 2. 登录 + UserInfoInTokenBO userInfoInTokenBO = new UserInfoInTokenBO(); + userInfoInTokenBO.setUserId(user.getUserId()); + userInfoInTokenBO.setSysType(SysTypeEnum.ORDINARY.value()); + userInfoInTokenBO.setIsAdmin(0); + userInfoInTokenBO.setEnabled(true); + return ResponseEntity.ok(tokenStore.storeAndGetVo(userInfoInTokenBO)); } @PutMapping("/updatePwd") @ApiOperation(value = "修改密码", notes = "修改密码") - public ResponseEntity updatePwd(@Valid @RequestBody UserRegisterParam userRegisterParam) { - User user = userService.getOne(new LambdaQueryWrapper().eq(User::getUserMobile, userRegisterParam.getUserMail())); + public ResponseEntity updatePwd(@Valid @RequestBody UserRegisterParam userPwdUpdateParam) { + User user = userService.getOne(new LambdaQueryWrapper().eq(User::getNickName, userPwdUpdateParam.getNickName())); if (user == null) { // 无法获取用户信息 throw new YamiShopBindException("无法获取用户信息"); } - if (StrUtil.isBlank(userRegisterParam.getPassword())) { + String decryptPassword = passwordManager.decryptPassword(userPwdUpdateParam.getPassWord()); + if (StrUtil.isBlank(decryptPassword)) { // 新密码不能为空 throw new YamiShopBindException("新密码不能为空"); } - if (StrUtil.equals(passwordEncoder.encode(userRegisterParam.getPassword()), user.getLoginPassword())) { + String password = passwordEncoder.encode(decryptPassword); + if (StrUtil.equals(password, user.getLoginPassword())) { // 新密码不能与原密码相同 throw new YamiShopBindException("新密码不能与原密码相同"); } user.setModifyTime(new Date()); - user.setLoginPassword(passwordEncoder.encode(userRegisterParam.getPassword())); + user.setLoginPassword(password); userService.updateById(user); return ResponseEntity.ok().build(); } - - @PutMapping("/registerOrBindUser") - @ApiOperation(value="注册或绑定手机号", notes="用户注册或绑定手机号接口") - public ResponseEntity register(HttpServletRequest request, HttpServletResponse response, @Valid @RequestBody UserRegisterParam userRegisterParam) { - - String mobile = userRegisterParam.getMobile(); - AppConnect appConnect = null; - User user = null; - String bizUserId = null; - boolean isWxAppId = Objects.equals(userRegisterParam.getAppType(), App.MINI.value()) || Objects.equals(userRegisterParam.getAppType(), App.MP.value()); - if(isWxAppId) { - bizUserId = SecurityUtils.getUser().getBizUserId(); - } - - // 正在进行注册,通过验证码校验 - if (Objects.equals(userRegisterParam.getRegisterOrBind(), 1)) { - - // 看看有没有校验验证码成功的标识 - userService.validate(userRegisterParam, CHECK_REGISTER_SMS_FLAG + userRegisterParam.getCheckRegisterSmsFlag()); - // 正在进行申请注册 - if (userService.count(new LambdaQueryWrapper().eq(User::getUserMobile,userRegisterParam.getMobile())) > 0) { - // 手机号已存在,无法注册 - throw new YamiShopBindException("yami.user.phone.exist"); - } - } - // 小程序注册/绑定手机号 - else { - YamiUser yamiUser = SecurityUtils.getUser(); - - appConnect = appConnectService.getByBizUserId(yamiUser.getBizUserId(), App.instance(yamiUser.getAppType())); - // 通过微信手机号校验 - if (Objects.equals(2, userRegisterParam.getValidateType())) { - try { - WxMaPhoneNumberInfo wxMaPhoneNumberInfo = wxConfig.wxMaService().getUserService().getPhoneNoInfo(yamiUser.getSessionKey(), userRegisterParam.getEncryptedData(), userRegisterParam.getIvStr()); - mobile = wxMaPhoneNumberInfo.getPhoneNumber(); - - } catch (Exception e) { - // 授权失败,请重新授权 - throw new YamiShopBindException(" 授权失败,请重新授权"); - } - if (StrUtil.isBlank(mobile)) { - // 无法获取用户手机号信息 - throw new YamiShopBindException("无法获取用户手机号信息"); - } - user = yamiUserDetailsService.loadUserByMobileOrUserName(mobile, 0); - } - // 通过账号密码校验 - else if (Objects.equals(3, userRegisterParam.getValidateType())) { - user = yamiUserDetailsService.loadUserByMobileOrUserName(mobile, 0); - if (user == null) { - // 账号或密码不正确 - throw new YamiShopBindException("yami.user.account.error"); - } - String encodedPassword = user.getLoginPassword(); - String rawPassword = userRegisterParam.getPassword(); - // 密码不正确 - if (StrUtil.isBlank(encodedPassword) || !passwordEncoder.matches(rawPassword,encodedPassword)){ - // 账号或密码不正确 - throw new YamiShopBindException("yami.user.account.error"); - } - } - // 通过验证码校验 - else { - if (!smsLogService.checkValidCode(userRegisterParam.getMobile(), userRegisterParam.getValidCode(), SmsType.VALID)){ - // 验证码有误或已过期 - throw new YamiShopBindException("yami.user.code.error"); - } - } - } - - Date now = new Date(); - - // 尝试用手机号获取用户信息 - if (user == null && StrUtil.isNotBlank(mobile)) { - user = userService.getOne(new LambdaQueryWrapper().eq(User::getUserMobile,mobile)); - } - - // 新建用户 - if (user == null) { - user = new User(); - if (StrUtil.isBlank(userRegisterParam.getUserName())) { - userRegisterParam.setUserName(mobile); - } - - // 如果有用户名,就判断用户名格式是否正确 - if (!PrincipalUtil.isUserName(userRegisterParam.getUserName())) { - throw new YamiShopBindException("用户名应由4-16位数字字母下划线组成"); - } - - user.setModifyTime(now); - user.setUserRegtime(now); - user.setUserRegip(IPHelper.getIpAddr()); - user.setStatus(1); - - user.setPic(userRegisterParam.getImg()); - user.setUserMobile(mobile); - if (StrUtil.isNotBlank(userRegisterParam.getPassword())) { - user.setLoginPassword(passwordEncoder.encode(userRegisterParam.getPassword())); - } - // 用户名就是默认的昵称 - user.setNickName(StrUtil.isBlank(userRegisterParam.getNickName())? userRegisterParam.getUserName(): userRegisterParam.getNickName()); -// } else { -// String userId = user.getUserId(); -// // 绑定账号 -// if (Objects.equals(userRegisterParam.getRegisterOrBind(),2)) { -// int count = appConnectService.count(new LambdaQueryWrapper().eq(AppConnect::getUserId, userId).eq(AppConnect::getAppId, userRegisterParam.getAppType())); -// if (count > 0) { -// throw new YamiShopBindException("该账号已被绑定,请换个账号试试"); -// } -// } - - } - if(Objects.nonNull(bizUserId)){ - appConnect = new AppConnect(); - appConnect.setBizUserId(bizUserId); - } - - appConnectService.registerOrBindUser(user, appConnect, userRegisterParam.getAppType()); - - - //进行授权登录 - UserDetails userDetails = yamiUserDetailsService.getYamiUser(userRegisterParam.getAppType(),user, bizUserId); - AuthenticationToken authenticationToken = new AuthenticationToken(); - authenticationToken.setPrincipal(user.getUserMobile()); - authenticationToken.setCredentials(user.getLoginPassword()); - authenticationToken.setPrincipal(userDetails.getUsername()); - authenticationToken.setDetails(userDetails); - authenticationToken.setAuthenticated(true); - loginAuthSuccessHandler.onAuthenticationSuccess(request,response,authenticationToken); - - return ResponseEntity.ok().build(); - } - } diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/listener/ConfirmOrderListener.java b/yami-shop-api/src/main/java/com/yami/shop/api/listener/ConfirmOrderListener.java index 55a8fad..4b0ded8 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/listener/ConfirmOrderListener.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/listener/ConfirmOrderListener.java @@ -10,34 +10,26 @@ package com.yami.shop.api.listener; -import com.google.common.collect.Lists; -import com.yami.shop.bean.app.dto.*; +import com.yami.shop.bean.app.dto.ShopCartItemDto; +import com.yami.shop.bean.app.dto.ShopCartOrderDto; import com.yami.shop.bean.app.param.OrderParam; import com.yami.shop.bean.event.ConfirmOrderEvent; -import com.yami.shop.bean.event.ShopCartEvent; import com.yami.shop.bean.model.Product; import com.yami.shop.bean.model.Sku; import com.yami.shop.bean.model.UserAddr; import com.yami.shop.bean.order.ConfirmOrderOrder; -import com.yami.shop.bean.order.ShopCartEventOrder; import com.yami.shop.common.exception.YamiShopBindException; import com.yami.shop.common.util.Arith; -import com.yami.shop.security.util.SecurityUtils; +import com.yami.shop.security.api.util.SecurityUtils; import com.yami.shop.service.ProductService; import com.yami.shop.service.SkuService; import com.yami.shop.service.TransportManagerService; import com.yami.shop.service.UserAddrService; -import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; -import ma.glasnost.orika.MapperFacade; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.event.EventListener; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import java.util.ArrayList; -import java.util.List; - /** * 确认订单信息时的默认操作 * @author LGH diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/listener/SubmitOrderListener.java b/yami-shop-api/src/main/java/com/yami/shop/api/listener/SubmitOrderListener.java index 42038ae..308238e 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/listener/SubmitOrderListener.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/listener/SubmitOrderListener.java @@ -23,7 +23,7 @@ import com.yami.shop.bean.order.SubmitOrderOrder; import com.yami.shop.common.exception.YamiShopBindException; import com.yami.shop.common.util.Arith; import com.yami.shop.dao.*; -import com.yami.shop.security.util.SecurityUtils; +import com.yami.shop.security.api.util.SecurityUtils; import com.yami.shop.service.ProductService; import com.yami.shop.service.SkuService; import com.yami.shop.service.UserAddrOrderService; diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/security/ApiTokenEnhancer.java b/yami-shop-api/src/main/java/com/yami/shop/api/security/ApiTokenEnhancer.java deleted file mode 100644 index 413ba0e..0000000 --- a/yami-shop-api/src/main/java/com/yami/shop/api/security/ApiTokenEnhancer.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.yami.shop.api.security; - -import cn.hutool.core.util.StrUtil; -import cn.hutool.extra.emoji.EmojiUtil; -import com.yami.shop.security.service.YamiUser; -import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; -import org.springframework.security.oauth2.common.OAuth2AccessToken; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.token.TokenEnhancer; -import org.springframework.stereotype.Component; - -import java.util.HashMap; -import java.util.Map; - -/** - * token增强 - * @author LGH - */ -@Component -public class ApiTokenEnhancer implements TokenEnhancer { - - - @Override - public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { - Map additionalInfo = new HashMap<>(8); - YamiUser yamiUser = (YamiUser) authentication.getUserAuthentication().getPrincipal(); - additionalInfo.put("userId", yamiUser.getUserId()); - additionalInfo.put("nickName", EmojiUtil.toUnicode(StrUtil.isBlank(yamiUser.getName())? "" : yamiUser.getName())); - additionalInfo.put("pic",yamiUser.getPic()); - additionalInfo.put("enabled",yamiUser.isEnabled()); - - ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo); - return accessToken; - } -} diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/security/AuthenticationToken.java b/yami-shop-api/src/main/java/com/yami/shop/api/security/AuthenticationToken.java deleted file mode 100644 index dbc4bb6..0000000 --- a/yami-shop-api/src/main/java/com/yami/shop/api/security/AuthenticationToken.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.api.security; - -import lombok.Getter; -import lombok.Setter; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.CredentialsContainer; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; - -import java.util.Collection; - -/** - * 自定义AbstractAuthenticationToken, - * @author SJL - */ -@Getter -@Setter -public class AuthenticationToken implements Authentication, - CredentialsContainer { - - private Collection authorities; - private UserDetails details; - - /** - * 用户名 - */ - protected String principal; - - /** - * 密码 - */ - protected Object credentials; - - /** - * uuid,现在用于验证码 - */ - private String sessionUUID; - - private boolean authenticated = false; - - public void setDetails(UserDetails details) { - this.details = details; - } - - - @Override - public Collection getAuthorities() { - return details.getAuthorities(); - } - - - @Override - public Object getDetails() { - return details; - } - - @Override - public boolean isAuthenticated() { - return authenticated; - } - - @Override - public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { - this.authenticated = isAuthenticated; - } - - @Override - public String getName() { - return details.getUsername(); - } - - @Override - public void eraseCredentials() { - eraseSecret(getCredentials()); - eraseSecret(getPrincipal()); - eraseSecret(details); - } - - private void eraseSecret(Object secret) { - if (secret instanceof CredentialsContainer) { - ((CredentialsContainer) secret).eraseCredentials(); - } - } - -} diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/security/LoginAuthenticationFilter.java b/yami-shop-api/src/main/java/com/yami/shop/api/security/LoginAuthenticationFilter.java deleted file mode 100644 index 25694f0..0000000 --- a/yami-shop-api/src/main/java/com/yami/shop/api/security/LoginAuthenticationFilter.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.api.security; - -import cn.binarywang.wx.miniapp.api.WxMaService; -import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; -import cn.hutool.core.util.BooleanUtil; -import cn.hutool.core.util.StrUtil; -import cn.hutool.extra.servlet.ServletUtil; -import com.yami.shop.common.util.Json; -import com.yami.shop.common.util.RedisUtil; -import com.yami.shop.security.constants.SecurityConstants; -import com.yami.shop.security.enums.App; -import com.yami.shop.security.exception.BadCredentialsExceptionBase; -import com.yami.shop.security.exception.ImageCodeNotMatchExceptionBase; -import com.yami.shop.security.exception.UsernameNotFoundExceptionBase; -import com.yami.shop.security.exception.WxErrorExceptionBase; -import com.yami.shop.security.model.AppConnect; -import com.yami.shop.security.service.YamiUser; -import com.yami.shop.security.service.YamiUserDetailsService; -import com.yami.shop.security.token.MyAuthenticationToken; -import lombok.AllArgsConstructor; -import me.chanjar.weixin.common.error.WxErrorException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.AuthenticationServiceException; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.stereotype.Component; - -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -/** - * 小程序登陆:此时principal为code - * post:http://127.0.0.1:8086/login - * {principal:code} - */ -@Component -public class LoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter { - - private final YamiUserDetailsService yamiUserDetailsService; - - private final WxMaService wxMaService; - - @Autowired - public LoginAuthenticationFilter(YamiUserDetailsService yamiUserDetailsService, WxMaService wxMaService) { - super("/login"); - this.yamiUserDetailsService = yamiUserDetailsService; - this.wxMaService = wxMaService; - } - - @Override - public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { - if (!ServletUtil.METHOD_POST.equals(request.getMethod())) { - throw new AuthenticationServiceException( - "Authentication method not supported: " + request.getMethod()); - } - String requestBody = getStringFromStream(request); - - if (StrUtil.isBlank(requestBody)) { - throw new AuthenticationServiceException("无法获取输入信息"); - } - MiniAppAuthenticationToken authentication = Json.parseObject(requestBody, MiniAppAuthenticationToken.class); - String code = String.valueOf(authentication.getPrincipal()); - YamiUser loadedUser = null; - - WxMaJscode2SessionResult session = null; - - AppConnect appConnect = new AppConnect(); - appConnect.setAppId(App.MINI.value()); - try { - - session = wxMaService.getUserService().getSessionInfo(code); - - loadedUser = yamiUserDetailsService.loadUserByAppIdAndBizUserId(App.MINI,session.getOpenid()); - } catch (WxErrorException e) { - throw new WxErrorExceptionBase(e.getMessage()); - } catch (UsernameNotFoundExceptionBase var6) { - if (session == null) { - throw new WxErrorExceptionBase("无法获取用户登陆信息"); - } - appConnect.setBizUserId(session.getOpenid()); - appConnect.setBizUnionid(session.getUnionid()); - yamiUserDetailsService.insertUserIfNecessary(appConnect); - } - - if (loadedUser == null) { - loadedUser = yamiUserDetailsService.loadUserByAppIdAndBizUserId(App.MINI, appConnect.getBizUserId()); - } - MiniAppAuthenticationToken result = new MiniAppAuthenticationToken(loadedUser, authentication.getCredentials()); - result.setDetails(authentication.getDetails()); - return result; - } - - - private String getStringFromStream(HttpServletRequest req) { - ServletInputStream is; - try { - is = req.getInputStream(); - int nRead = 1; - int nTotalRead = 0; - byte[] bytes = new byte[10240]; - while (nRead > 0) { - nRead = is.read(bytes, nTotalRead, bytes.length - nTotalRead); - if (nRead > 0) { - nTotalRead = nTotalRead + nRead; - } - } - return new String(bytes, 0, nTotalRead, StandardCharsets.UTF_8); - } catch (IOException e) { - e.printStackTrace(); - return ""; - } - } - - @Override - @Autowired - public void setAuthenticationManager(AuthenticationManager authenticationManager) { - super.setAuthenticationManager(authenticationManager); - } - - @Override - @Autowired - public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) { - super.setAuthenticationSuccessHandler(successHandler); - } - - @Override - @Autowired - public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) { - super.setAuthenticationFailureHandler(failureHandler); - } -} diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/security/MiniAppAuthenticationToken.java b/yami-shop-api/src/main/java/com/yami/shop/api/security/MiniAppAuthenticationToken.java deleted file mode 100644 index b72b40c..0000000 --- a/yami-shop-api/src/main/java/com/yami/shop/api/security/MiniAppAuthenticationToken.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.api.security; - -import com.yami.shop.security.token.MyAuthenticationToken; -import lombok.NoArgsConstructor; -import org.springframework.security.core.userdetails.UserDetails; - -/** - * 二维码Token - */ -@NoArgsConstructor -public class MiniAppAuthenticationToken extends MyAuthenticationToken { - - - public MiniAppAuthenticationToken(UserDetails principal, Object credentials) { - super(principal, credentials, principal.getAuthorities()); - } -} diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/security/ResourceServerConfiguration.java b/yami-shop-api/src/main/java/com/yami/shop/api/security/ResourceServerConfiguration.java deleted file mode 100644 index e4830a5..0000000 --- a/yami-shop-api/src/main/java/com/yami/shop/api/security/ResourceServerConfiguration.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.api.security; - -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.http.SessionCreationPolicy; -import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; -import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.web.cors.CorsUtils; - -@Configuration -@EnableResourceServer -public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { - - @Autowired - private LoginAuthenticationFilter loginAuthenticationFilter; - - @Override - public void configure(HttpSecurity http) throws Exception { - http - .addFilterBefore(loginAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) - .csrf().disable().cors() - .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .and().authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll() - .and().requestMatchers().anyRequest() - .and().anonymous() - .and().authorizeRequests() - //配置/p访问控制,必须认证过后才可以访问 - .antMatchers("/p/**").authenticated(); - } - - -} diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/security/WebAuthenticationToken.java b/yami-shop-api/src/main/java/com/yami/shop/api/security/WebAuthenticationToken.java deleted file mode 100644 index 5c9bef4..0000000 --- a/yami-shop-api/src/main/java/com/yami/shop/api/security/WebAuthenticationToken.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.api.security; - -import com.yami.shop.security.token.MyAuthenticationToken; -import lombok.NoArgsConstructor; -import org.springframework.security.core.userdetails.UserDetails; - -/** - * H5端Token - */ -@NoArgsConstructor -public class WebAuthenticationToken extends MyAuthenticationToken { - - - public WebAuthenticationToken(UserDetails principal, Object credentials) { - super(principal, credentials, principal.getAuthorities()); - } -} diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/security/WebLoginAuthenticationFilter.java b/yami-shop-api/src/main/java/com/yami/shop/api/security/WebLoginAuthenticationFilter.java deleted file mode 100644 index 0717541..0000000 --- a/yami-shop-api/src/main/java/com/yami/shop/api/security/WebLoginAuthenticationFilter.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.api.security; - -import cn.binarywang.wx.miniapp.api.WxMaService; -import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; -import cn.hutool.core.util.BooleanUtil; -import cn.hutool.core.util.StrUtil; -import cn.hutool.extra.servlet.ServletUtil; -import com.yami.shop.common.util.Json; -import com.yami.shop.common.util.RedisUtil; -import com.yami.shop.security.constants.SecurityConstants; -import com.yami.shop.security.enums.App; -import com.yami.shop.security.exception.BadCredentialsExceptionBase; -import com.yami.shop.security.exception.ImageCodeNotMatchExceptionBase; -import com.yami.shop.security.exception.UsernameNotFoundExceptionBase; -import com.yami.shop.security.exception.WxErrorExceptionBase; -import com.yami.shop.security.model.AppConnect; -import com.yami.shop.security.service.YamiUser; -import com.yami.shop.security.service.YamiUserDetailsService; -import com.yami.shop.security.token.MyAuthenticationToken; -import lombok.AllArgsConstructor; -import me.chanjar.weixin.common.error.WxErrorException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.AuthenticationServiceException; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.stereotype.Component; - -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -/** - * 账号密码登录 - */ -@Component -public class WebLoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter { - - private final YamiUserDetailsService yamiUserDetailsService; - - private final WxMaService wxMaService; - - @Autowired - public WebLoginAuthenticationFilter(YamiUserDetailsService yamiUserDetailsService, WxMaService wxMaService) { - super("/webLogin"); - this.yamiUserDetailsService = yamiUserDetailsService; - this.wxMaService = wxMaService; - } - - @Override - public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { - if (!ServletUtil.METHOD_POST.equals(request.getMethod())) { - throw new AuthenticationServiceException( - "Authentication method not supported: " + request.getMethod()); - } - String requestBody = getStringFromStream(request); - - if (StrUtil.isBlank(requestBody)) { - throw new AuthenticationServiceException("无法获取输入信息"); - } - WebAuthenticationToken authentication = Json.parseObject(requestBody, WebAuthenticationToken.class); - String userMail = String.valueOf(authentication.getPrincipal()); - String loginPassword = String.valueOf(authentication.getCredentials()); - - YamiUser loadedUser = null; - -// WxMaJscode2SessionResult session = null; - - AppConnect appConnect = new AppConnect(); - appConnect.setAppId(App.H5.value()); - loadedUser = yamiUserDetailsService.loadUserByUserMail(userMail,loginPassword); -// try { -// -//// session = wxMaService.getUserService().getSessionInfo(code); -// -// loadedUser = yamiUserDetailsService.loadUserByAppIdAndBizUserId(App.MINI,session.getOpenid()); -// } catch (WxErrorException e) { -// throw new WxErrorExceptionBase(e.getMessage()); -// } catch (UsernameNotFoundExceptionBase var6) { -// if (session == null) { -// throw new WxErrorExceptionBase("无法获取用户登陆信息"); -// } -// appConnect.setBizUserId(session.getOpenid()); -// appConnect.setBizUnionid(session.getUnionid()); -// yamiUserDetailsService.insertUserIfNecessary(appConnect); -// } - -// if (loadedUser == null) { -// loadedUser = yamiUserDetailsService.loadUserByAppIdAndBizUserId(App.MINI, appConnect.getBizUserId()); -// } -// MiniAppAuthenticationToken result = new MiniAppAuthenticationToken(loadedUser, authentication.getCredentials()); - WebAuthenticationToken result = new WebAuthenticationToken(loadedUser, authentication.getCredentials()); - result.setDetails(authentication.getDetails()); - return result; - } - - - private String getStringFromStream(HttpServletRequest req) { - ServletInputStream is; - try { - is = req.getInputStream(); - int nRead = 1; - int nTotalRead = 0; - byte[] bytes = new byte[10240]; - while (nRead > 0) { - nRead = is.read(bytes, nTotalRead, bytes.length - nTotalRead); - if (nRead > 0) { - nTotalRead = nTotalRead + nRead; - } - } - return new String(bytes, 0, nTotalRead, StandardCharsets.UTF_8); - } catch (IOException e) { - e.printStackTrace(); - return ""; - } - } - - @Override - @Autowired - public void setAuthenticationManager(AuthenticationManager authenticationManager) { - super.setAuthenticationManager(authenticationManager); - } - - @Override - @Autowired - public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) { - super.setAuthenticationSuccessHandler(successHandler); - } - - @Override - @Autowired - public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) { - super.setAuthenticationFailureHandler(failureHandler); - } -} diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/security/YamiAuthenticationProcessingFilter.java b/yami-shop-api/src/main/java/com/yami/shop/api/security/YamiAuthenticationProcessingFilter.java deleted file mode 100644 index 85763c2..0000000 --- a/yami-shop-api/src/main/java/com/yami/shop/api/security/YamiAuthenticationProcessingFilter.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.yami.shop.api.security; - -import cn.hutool.extra.servlet.ServletUtil; -import com.yami.shop.common.exception.YamiShopBindException; -import com.yami.shop.common.util.Json; -import com.yami.shop.common.xss.XssUtil; -import com.yami.shop.security.exception.BadCredentialsException; -import com.yami.shop.security.exception.UsernameNotFoundException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; -import org.springframework.web.HttpRequestMethodNotSupportedException; - -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -/** - * - * @author SJL - */ -public class YamiAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter { - - private UserDetailsService userDetailsService; - - private PasswordEncoder passwordEncoder; - /** - * 请求字符串的最大长度 1m - */ - public static final int MAX_STRING_SIZE = 1024 * 1024; - - protected YamiAuthenticationProcessingFilter(String defaultFilterProcessesUrl) { - super(defaultFilterProcessesUrl); - } - - @Autowired - public void setPasswordEncoder(PasswordEncoder passwordEncoder) { - this.passwordEncoder = passwordEncoder; - } - - @Autowired - public void setUserDetailsService(UserDetailsService userDetailsService) { - this.userDetailsService = userDetailsService; - } - - @Override - @Autowired - public void setAuthenticationManager(AuthenticationManager authenticationManager) { - super.setAuthenticationManager(authenticationManager); - } - - @Override - @Autowired - public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) { - super.setAuthenticationSuccessHandler(successHandler); - } - - @Override - @Autowired - public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) { - super.setAuthenticationFailureHandler(failureHandler); - } - - @Override - public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, ServletException{ - if (!ServletUtil.METHOD_POST.equals(request.getMethod())) { - throw new HttpRequestMethodNotSupportedException(request.getMethod(), new String[] { "POST" }); - } - - AuthenticationToken authenticationToken = Json.parseObject(getStringFromStream(request), AuthenticationToken.class); - UserDetails userDetails = getUserDetails(authenticationToken); - return handleAuthenticationToken(authenticationToken,userDetails); - } - - /** - * 获取用户信息 - * @param authenticationToken - * @return - */ - protected UserDetails getUserDetails(AuthenticationToken authenticationToken) { - UserDetails user; - try { - user = userDetailsService.loadUserByUsername(authenticationToken.getPrincipal()); - } catch (UsernameNotFoundException var6) { - // 账号或密码不正确 - throw new UsernameNotFoundException("账号或密码不正确"); - } - if (!user.isEnabled()) { - // 账号已被锁定,请联系管理员 - throw new UsernameNotFoundException("账号已被锁定,请联系管理员"); - } - - String encodedPassword = user.getPassword(); - String rawPassword = authenticationToken.getCredentials().toString(); - - // 密码不正确 - if (!passwordEncoder.matches(rawPassword,encodedPassword)){ - // 账号或密码不正确 - throw new BadCredentialsException("账号或密码不正确"); - } - return user; - } - - - /** - * 保存用户信息 - */ - protected AuthenticationToken handleAuthenticationToken(AuthenticationToken authentication, UserDetails userDetails) { - // 保存用户信息 - authentication.setPrincipal(userDetails.getUsername()); - authentication.setDetails(userDetails); - authentication.setAuthenticated(true); - return authentication; - } - - - public String getStringFromStream(HttpServletRequest req) { - if (req.getContentLength() > MAX_STRING_SIZE) { - // 请求数据过长 - throw new YamiShopBindException("yami.request.data.too.long"); - } - ServletInputStream is; - try { - is = req.getInputStream(); - int nRead = 1; - int nTotalRead = 0; - byte[] bytes = new byte[1024]; - while (nRead > 0) { - nRead = is.read(bytes, nTotalRead, bytes.length - nTotalRead); - if (nRead > 0) { - nTotalRead = nTotalRead + nRead; - } - } - if (nTotalRead > MAX_STRING_SIZE) { - // 请求数据过长 - throw new YamiShopBindException("yami.request.data.too.long"); - } - return XssUtil.clean(new String(bytes, 0, nTotalRead, StandardCharsets.UTF_8)); - } catch (IOException e) { - e.printStackTrace(); - return ""; - } - } -} diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/security/YamiUserServiceImpl.java b/yami-shop-api/src/main/java/com/yami/shop/api/security/YamiUserServiceImpl.java deleted file mode 100644 index f760821..0000000 --- a/yami-shop-api/src/main/java/com/yami/shop/api/security/YamiUserServiceImpl.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.api.security; - -import cn.hutool.core.util.IdUtil; -import cn.hutool.core.util.StrUtil; -import cn.hutool.extra.emoji.EmojiUtil; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.yami.shop.bean.model.User; -import com.yami.shop.common.annotation.RedisLock; -import com.yami.shop.common.exception.YamiShopBindException; -import com.yami.shop.common.util.CacheManagerUtil; -import com.yami.shop.common.util.PrincipalUtil; -import com.yami.shop.dao.UserMapper; -import com.yami.shop.security.dao.AppConnectMapper; -import com.yami.shop.security.enums.App; -import com.yami.shop.security.exception.UsernameNotFoundException; -import com.yami.shop.security.exception.UsernameNotFoundExceptionBase; -import com.yami.shop.security.model.AppConnect; -import com.yami.shop.security.service.YamiUser; -import com.yami.shop.security.service.YamiUserDetailsService; -import lombok.AllArgsConstructor; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.springframework.cache.annotation.CacheEvict; -import org.springframework.cache.annotation.Caching; -import org.springframework.http.ResponseEntity; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.*; - -/** - * 用户详细信息 - * - * @author - */ -@Slf4j -@Service -@AllArgsConstructor -public class YamiUserServiceImpl implements YamiUserDetailsService { - - private final UserMapper userMapper; - - private final AppConnectMapper appConnectMapper; - - private final PasswordEncoder passwordEncoder; - @Override - @SneakyThrows - public YamiUser loadUserByUsername(String username) { - if (StrUtil.isBlank(username) || !username.contains(StrUtil.COLON) ) { - throw new UsernameNotFoundExceptionBase("无法获取用户信息"); - } - String[] splitInfo = username.split(StrUtil.COLON); - App app = App.instance(Integer.valueOf(splitInfo[0])); - String bizUserId = splitInfo[1]; - return loadUserByAppIdAndBizUserId(app,bizUserId); - } - - /** - * 获取前端登陆的用户信息 - * - * @param app - * @param bizUserId openId - * @return UserDetails - * @throws UsernameNotFoundExceptionBase - */ - @Override - public YamiUser loadUserByAppIdAndBizUserId(App app, String bizUserId) { - - String cacheKey = app.value() + StrUtil.COLON + bizUserId; - - User user = userMapper.getUserByBizUserId(app.value(), bizUserId); - if (user == null) { - throw new UsernameNotFoundExceptionBase("无法获取用户信息"); - } - String name = StrUtil.isBlank(user.getRealName()) ? user.getNickName() : user.getRealName(); - YamiUser yamiUser = new YamiUser(user.getUserId(), bizUserId, app.value(), user.getStatus() == 1); - yamiUser.setName(name); - yamiUser.setPic(user.getPic()); - - return yamiUser; - } - - @Override - @Transactional(rollbackFor = Exception.class) - @RedisLock(lockName = "insertUser", key = "#appConnect.appId + ':' + #appConnect.bizUserId") - @Caching(evict = { - @CacheEvict(cacheNames = "yami_user", key = "#appConnect.appId + ':' + #appConnect.bizUserId"), - @CacheEvict(cacheNames = "AppConnect", key = "#appConnect.appId + ':' + #appConnect.bizUserId") - }) - public void insertUserIfNecessary(AppConnect appConnect) { - // 进入锁后再重新判断一遍用户是否创建 - AppConnect dbAppConnect = appConnectMapper.getByBizUserId(appConnect.getBizUserId(), appConnect.getAppId()); - if(dbAppConnect != null) { - return; - } - - String bizUnionId = appConnect.getBizUnionid(); - String userId = null; - User user; - - if (StrUtil.isNotBlank(bizUnionId)) { - userId = appConnectMapper.getUserIdByUnionId(bizUnionId); - } - if (StrUtil.isBlank(userId)) { - userId = IdUtil.simpleUUID(); - Date now = new Date(); - user = new User(); - user.setUserId(userId); - user.setModifyTime(now); - user.setUserRegtime(now); - user.setStatus(1); - user.setNickName(EmojiUtil.toAlias(StrUtil.isBlank(appConnect.getNickName()) ? "" : appConnect.getNickName())); - user.setPic(appConnect.getImageUrl()); - userMapper.insert(user); - } else { - user = userMapper.selectById(userId); - } - - appConnect.setUserId(user.getUserId()); - - appConnectMapper.insert(appConnect); - } - - @Override - public YamiUser loadUserByUserMail(String userMail, String loginPassword) { - User user = userMapper.getUserByUserMail(userMail); - if (user == null) { - throw new UsernameNotFoundException("用户不存在"); - } - - if (!passwordEncoder.matches(loginPassword, user.getLoginPassword())) { - // 原密码不正确 - throw new UsernameNotFoundException("密码不正确"); - } - String name = StrUtil.isBlank(user.getRealName()) ? user.getNickName() : user.getRealName(); - YamiUser yamiUser = new YamiUser(user.getUserId(), loginPassword, user.getStatus() == 1); - yamiUser.setName(name); - yamiUser.setPic(user.getPic()); - return yamiUser; - } - - @Override - public User loadUserByMobileOrUserName(String mobileOrUserName, Integer loginType) { - User user = null; - // 手机验证码登陆,或传过来的账号很像手机号 - if (Objects.equals(loginType, 1) || PrincipalUtil.isMobile(mobileOrUserName)) { - user = userMapper.selectOne(new LambdaQueryWrapper().eq(User::getUserMobile, mobileOrUserName)); - } - return user; - } - - @Override - public YamiUser getYamiUser(Integer appId, User user, String bizUserId) { - String name = StrUtil.isBlank(user.getRealName()) ? user.getNickName() : user.getRealName(); - YamiUser yamiUser = new YamiUser(); - yamiUser.setEnabled(user.getStatus() == 1); - yamiUser.setUserId(user.getUserId()); - yamiUser.setBizUserId(bizUserId); - yamiUser.setAppType(appId); - yamiUser.setName(name); - yamiUser.setPic(user.getPic()); - yamiUser.setPassword(user.getLoginPassword()); - return yamiUser; - } -} diff --git a/yami-shop-api/src/main/resources/application-dev.yml b/yami-shop-api/src/main/resources/application-dev.yml index 5d74e21..de4328f 100644 --- a/yami-shop-api/src/main/resources/application-dev.yml +++ b/yami-shop-api/src/main/resources/application-dev.yml @@ -14,7 +14,7 @@ spring: connection-test-query: select 1 redis: redisson: - config: classpath:redisson.yml + config: classpath:redisson/redisson.yml logging: - config: classpath:logback-dev.xml + config: classpath:logback/logback-dev.xml diff --git a/yami-shop-api/src/main/resources/application-docker.yml b/yami-shop-api/src/main/resources/application-docker.yml index b947ee4..a26ed59 100644 --- a/yami-shop-api/src/main/resources/application-docker.yml +++ b/yami-shop-api/src/main/resources/application-docker.yml @@ -14,6 +14,6 @@ spring: connection-test-query: select 1 redis: redisson: - config: classpath:redisson-docker.yml + config: classpath:redisson/redisson-docker.yml logging: - config: classpath:logback-prod.xml + config: classpath:logback/logback-prod.xml diff --git a/yami-shop-api/src/main/resources/application-prod.yml b/yami-shop-api/src/main/resources/application-prod.yml index 923143e..09322d9 100644 --- a/yami-shop-api/src/main/resources/application-prod.yml +++ b/yami-shop-api/src/main/resources/application-prod.yml @@ -16,6 +16,6 @@ spring: connection-test-query: select 1 redis: redisson: - config: classpath:redisson.yml + config: classpath:redisson/redisson.yml logging: - config: classpath:logback-prod.xml + config: classpath:logback/logback-prod.xml diff --git a/yami-shop-api/src/main/resources/logback-dev.xml b/yami-shop-api/src/main/resources/logback/logback-dev.xml similarity index 100% rename from yami-shop-api/src/main/resources/logback-dev.xml rename to yami-shop-api/src/main/resources/logback/logback-dev.xml diff --git a/yami-shop-api/src/main/resources/logback-prod.xml b/yami-shop-api/src/main/resources/logback/logback-prod.xml similarity index 100% rename from yami-shop-api/src/main/resources/logback-prod.xml rename to yami-shop-api/src/main/resources/logback/logback-prod.xml diff --git a/yami-shop-admin/src/main/resources/redisson-docker.yml b/yami-shop-api/src/main/resources/redisson/redisson-docker.yml similarity index 80% rename from yami-shop-admin/src/main/resources/redisson-docker.yml rename to yami-shop-api/src/main/resources/redisson/redisson-docker.yml index 4ba23b7..a79943a 100644 --- a/yami-shop-admin/src/main/resources/redisson-docker.yml +++ b/yami-shop-api/src/main/resources/redisson/redisson-docker.yml @@ -4,28 +4,25 @@ singleServerConfig: database: ${REDIS_DATABASE} password: ${REDIS_PASSWORD} idleConnectionTimeout: 10000 - pingTimeout: 1000 connectTimeout: 10000 timeout: 3000 retryAttempts: 3 retryInterval: 1500 - reconnectionTimeout: 3000 - failedAttempts: 3 clientName: null # 发布和订阅连接的最小空闲连接数 默认1 subscriptionConnectionMinimumIdleSize: 1 # 发布和订阅连接池大小 默认50 - subscriptionConnectionPoolSize: 10 + subscriptionConnectionPoolSize: 1 # 单个连接最大订阅数量 默认5 - subscriptionsPerConnection: 5 + subscriptionsPerConnection: 1 # 最小空闲连接数 默认32,现在暂时不需要那么多的线程 connectionMinimumIdleSize: 4 # connectionPoolSize 默认64,现在暂时不需要那么多的线程 - connectionPoolSize: 20 + connectionPoolSize: 4 # 这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。 threads: 0 # 这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。 nettyThreads: 0 codec: - class: com.yami.shop.common.serializer.redisson.FstCodec -transportMode: NIO \ No newline at end of file + class: org.redisson.codec.KryoCodec +transportMode: NIO diff --git a/yami-shop-api/src/main/resources/redisson.yml b/yami-shop-api/src/main/resources/redisson/redisson.yml similarity index 77% rename from yami-shop-api/src/main/resources/redisson.yml rename to yami-shop-api/src/main/resources/redisson/redisson.yml index 1c8989e..01883be 100644 --- a/yami-shop-api/src/main/resources/redisson.yml +++ b/yami-shop-api/src/main/resources/redisson/redisson.yml @@ -4,28 +4,25 @@ singleServerConfig: database: 0 password: null idleConnectionTimeout: 10000 - pingTimeout: 1000 connectTimeout: 10000 timeout: 3000 retryAttempts: 3 retryInterval: 1500 - reconnectionTimeout: 3000 - failedAttempts: 3 clientName: null # 发布和订阅连接的最小空闲连接数 默认1 subscriptionConnectionMinimumIdleSize: 1 # 发布和订阅连接池大小 默认50 - subscriptionConnectionPoolSize: 10 + subscriptionConnectionPoolSize: 1 # 单个连接最大订阅数量 默认5 - subscriptionsPerConnection: 5 + subscriptionsPerConnection: 1 # 最小空闲连接数 默认32,现在暂时不需要那么多的线程 - connectionMinimumIdleSize: 4 + connectionMinimumIdleSize: 2 # connectionPoolSize 默认64,现在暂时不需要那么多的线程 - connectionPoolSize: 20 + connectionPoolSize: 4 # 这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。 threads: 0 # 这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。 nettyThreads: 0 codec: - class: com.yami.shop.common.serializer.redisson.FstCodec -transportMode: NIO \ No newline at end of file + class: org.redisson.codec.KryoCodec +transportMode: NIO diff --git a/yami-shop-bean/src/main/java/com/yami/shop/bean/enums/SendType.java b/yami-shop-bean/src/main/java/com/yami/shop/bean/enums/SendType.java new file mode 100644 index 0000000..85b7959 --- /dev/null +++ b/yami-shop-bean/src/main/java/com/yami/shop/bean/enums/SendType.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.bean.enums; + +/** + * @author lh + */ +public enum SendType { + /** + * 用户注册验证码 + */ + REGISTER(12, 1,"用户注册验证码"), + /** + * 发送登录验证码 + */ + LOGIN(13, 1,"发送登录验证码"), + /** + * 修改密码验证码 + */ + UPDATE_PASSWORD(14, 1,"修改密码验证码"), + /** + * 身份验证验证码 + */ + VALID(15, 1,"身份验证验证码") + ; + + private Integer value; + /** + * 1为全部平台发送的消息,2为根据情况 + */ + private Integer type; + private String desc; + SendType(Integer value, Integer type, String desc) { + this.value = value; + this.type = type; + this.desc = desc; + } + public Integer getValue() { + return value; + } + + public String getDesc() { + return desc; + } + + public static SendType instance(Integer value) { + SendType[] enums = values(); + for (SendType statusEnum : enums) { + if (statusEnum.getValue().equals(value)) { + return statusEnum; + } + } + return null; + } + + public Integer getType() { + return type; + } +} diff --git a/yami-shop-bean/src/main/java/com/yami/shop/bean/param/UserRegisterParam.java b/yami-shop-bean/src/main/java/com/yami/shop/bean/param/UserRegisterParam.java index a13a1e8..8973120 100644 --- a/yami-shop-bean/src/main/java/com/yami/shop/bean/param/UserRegisterParam.java +++ b/yami-shop-bean/src/main/java/com/yami/shop/bean/param/UserRegisterParam.java @@ -14,12 +14,15 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +/** + * @author lh + */ @Data @ApiModel(value= "设置用户信息") public class UserRegisterParam { @ApiModelProperty(value = "密码") - private String password; + private String passWord; @ApiModelProperty(value = "邮箱") private String userMail; @@ -30,30 +33,18 @@ public class UserRegisterParam { @ApiModelProperty(value = "用户名") private String userName; - @ApiModelProperty(value = "应用类型 1小程序 2微信公众号 3 PC 4 h5") - private Integer appType; - @ApiModelProperty(value = "手机号") private String mobile; - @ApiModelProperty(value = "验证码") - private String validCode; - - @ApiModelProperty(value = "微信小程序的encryptedData") - private String encryptedData; - - @ApiModelProperty(value = "微信小程序的ivStr") - private String ivStr; - @ApiModelProperty(value = "头像") private String img; @ApiModelProperty(value = "校验登陆注册验证码成功的标识") private String checkRegisterSmsFlag; - @ApiModelProperty(value = "验证类型 1验证码验证 2 小程序encryptedData验证 3 密码验证 ") - private Integer validateType; + @ApiModelProperty(value = "当账户未绑定时,临时的uid") + private String tempUid; - @ApiModelProperty(value = "验证类型 1注册 2绑定 ") - private Integer registerOrBind; + @ApiModelProperty(value = "用户id") + private Long userId; } diff --git a/yami-shop-common/pom.xml b/yami-shop-common/pom.xml index 9fcbfb9..e4c3c85 100644 --- a/yami-shop-common/pom.xml +++ b/yami-shop-common/pom.xml @@ -82,8 +82,8 @@ emoji-java - de.ruedigermoeller - fst + com.esotericsoftware + kryo com.github.binarywang @@ -97,5 +97,9 @@ com.github.binarywang weixin-java-mp + + com.alibaba + transmittable-thread-local + diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/config/DefaultExceptionHandlerConfig.java b/yami-shop-common/src/main/java/com/yami/shop/common/config/DefaultExceptionHandlerConfig.java index cc27d86..4cf17cc 100644 --- a/yami-shop-common/src/main/java/com/yami/shop/common/config/DefaultExceptionHandlerConfig.java +++ b/yami-shop-common/src/main/java/com/yami/shop/common/config/DefaultExceptionHandlerConfig.java @@ -11,6 +11,7 @@ package com.yami.shop.common.config; import com.yami.shop.common.exception.YamiShopBindException; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; @@ -23,6 +24,7 @@ import org.springframework.web.bind.annotation.RestControllerAdvice; * 自定义错误处理器 * @author LGH */ +@Slf4j @Controller @RestControllerAdvice public class DefaultExceptionHandlerConfig { @@ -30,20 +32,20 @@ public class DefaultExceptionHandlerConfig { @ExceptionHandler(BindException.class) public ResponseEntity bindExceptionHandler(BindException e){ - e.printStackTrace(); + log.error("BindException:", e); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getBindingResult().getFieldErrors().get(0).getDefaultMessage()); } @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e){ - e.printStackTrace(); + log.error("MethodArgumentNotValidException:", e); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getBindingResult().getFieldErrors().get(0).getDefaultMessage()); } @ExceptionHandler(YamiShopBindException.class) public ResponseEntity unauthorizedExceptionHandler(YamiShopBindException e){ - e.printStackTrace(); + log.error("YamiShopBindException Message :{}",e.getMessage()); return ResponseEntity.status(e.getHttpStatusCode()).body(e.getMessage()); } } \ No newline at end of file diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/config/RedisCacheConfig.java b/yami-shop-common/src/main/java/com/yami/shop/common/config/RedisCacheConfig.java index 8526f29..d600dc0 100644 --- a/yami-shop-common/src/main/java/com/yami/shop/common/config/RedisCacheConfig.java +++ b/yami-shop-common/src/main/java/com/yami/shop/common/config/RedisCacheConfig.java @@ -10,11 +10,7 @@ package com.yami.shop.common.config; -import java.time.Duration; -import java.util.HashMap; -import java.util.Map; - -import com.yami.shop.common.serializer.redis.FstRedisSerializer; +import com.yami.shop.common.serializer.redis.KryoRedisSerializer; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; @@ -24,7 +20,13 @@ import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.cache.RedisCacheWriter; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.serializer.*; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.serializer.RedisSerializationContext; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; /** * redis 缓存配置,仅当配置文件中spring.cache.type = redis时生效 @@ -57,14 +59,11 @@ public class RedisCacheConfig { } private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) { - - FstRedisSerializer kryoRedisSerializer = new FstRedisSerializer(); - RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig(); redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith( RedisSerializationContext .SerializationPair - .fromSerializer(kryoRedisSerializer) + .fromSerializer(new KryoRedisSerializer<>()) ).entryTtl(Duration.ofSeconds(seconds)); return redisCacheConfiguration; @@ -72,14 +71,24 @@ public class RedisCacheConfig { @Bean public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { + KryoRedisSerializer kryoRedisSerializer = new KryoRedisSerializer(); RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); - redisTemplate.setValueSerializer(new FstRedisSerializer()); - redisTemplate.setHashValueSerializer(new FstRedisSerializer()); + redisTemplate.setValueSerializer(kryoRedisSerializer); + redisTemplate.setHashValueSerializer(kryoRedisSerializer); + redisTemplate.setEnableTransactionSupport(false); + redisTemplate.afterPropertiesSet(); return redisTemplate; } + @Bean + public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory){ + StringRedisTemplate redisTemplate = new StringRedisTemplate(redisConnectionFactory); + redisTemplate.setEnableTransactionSupport(false); + return redisTemplate; + } + } diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/constants/OauthCacheNames.java b/yami-shop-common/src/main/java/com/yami/shop/common/constants/OauthCacheNames.java new file mode 100644 index 0000000..dac1954 --- /dev/null +++ b/yami-shop-common/src/main/java/com/yami/shop/common/constants/OauthCacheNames.java @@ -0,0 +1,33 @@ +package com.yami.shop.common.constants; + +/** + * @author 菠萝凤梨 + * @date 2022/3/28 14:32 + */ +public interface OauthCacheNames { + + /** + * oauth 授权相关key + */ + String OAUTH_PREFIX = "mall4j_oauth:"; + + /** + * token 授权相关key + */ + String OAUTH_TOKEN_PREFIX = OAUTH_PREFIX + "token:"; + + /** + * 保存token 缓存使用key + */ + String ACCESS = OAUTH_TOKEN_PREFIX + "access:"; + + /** + * 刷新token 缓存使用key + */ + String REFRESH_TO_ACCESS = OAUTH_TOKEN_PREFIX + "refresh_to_access:"; + + /** + * 根据uid获取保存的token key缓存使用的key + */ + String UID_TO_ACCESS = OAUTH_TOKEN_PREFIX + "uid_to_access:"; +} diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/enums/YamiHttpStatus.java b/yami-shop-common/src/main/java/com/yami/shop/common/enums/YamiHttpStatus.java index 4bc0692..017550c 100644 --- a/yami-shop-common/src/main/java/com/yami/shop/common/enums/YamiHttpStatus.java +++ b/yami-shop-common/src/main/java/com/yami/shop/common/enums/YamiHttpStatus.java @@ -21,6 +21,9 @@ public enum YamiHttpStatus { UNAUTHORIZED(401, "未授权"), COUPONCANNOTUSETOGETHER(601, "优惠券不能共用"), + + SOCIAL_ACCOUNT_NOT_BIND(475, "social account not bind"), + ACCOUNT_NOT_REGISTER(476, "account not register"), ; diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/exception/YamiShopBindException.java b/yami-shop-common/src/main/java/com/yami/shop/common/exception/YamiShopBindException.java index 3aef841..5b063a5 100644 --- a/yami-shop-common/src/main/java/com/yami/shop/common/exception/YamiShopBindException.java +++ b/yami-shop-common/src/main/java/com/yami/shop/common/exception/YamiShopBindException.java @@ -25,6 +25,8 @@ public class YamiShopBindException extends RuntimeException{ */ private Integer httpStatusCode; + private Object object; + /** * @param httpStatus http状态码 @@ -48,6 +50,11 @@ public class YamiShopBindException extends RuntimeException{ this.httpStatusCode = HttpStatus.BAD_REQUEST.value(); } + public YamiShopBindException(String msg, Object object) { + super(msg); + this.httpStatusCode = HttpStatus.BAD_REQUEST.value(); + this.object = object; + } public Integer getHttpStatusCode() { return httpStatusCode; diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/filter/FilterConfig.java b/yami-shop-common/src/main/java/com/yami/shop/common/filter/FilterConfig.java deleted file mode 100644 index 1ba995c..0000000 --- a/yami-shop-common/src/main/java/com/yami/shop/common/filter/FilterConfig.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.common.filter; - -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import javax.servlet.DispatcherType; - -/** - * @author lgh - */ -@Configuration -public class FilterConfig { - - @Bean - public FilterRegistrationBean filterRegistration() { - FilterRegistrationBean registration = new FilterRegistrationBean<>(); - //添加过滤器 - registration.setFilter(new XssFilter()); - //设置过滤路径,/*所有路径 - registration.addUrlPatterns("/*"); - registration.setName("xssFilter"); - //设置优先级 - registration.setOrder(Integer.MAX_VALUE); - registration.setDispatcherTypes(DispatcherType.REQUEST); - return registration; - } -} diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/filter/XssFilter.java b/yami-shop-common/src/main/java/com/yami/shop/common/filter/XssFilter.java index 0109b43..89fc5f7 100644 --- a/yami-shop-common/src/main/java/com/yami/shop/common/filter/XssFilter.java +++ b/yami-shop-common/src/main/java/com/yami/shop/common/filter/XssFilter.java @@ -10,27 +10,22 @@ package com.yami.shop.common.filter; -import java.io.IOException; - -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.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import com.yami.shop.common.xss.XssWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; -import com.yami.shop.common.xss.XssWrapper; +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; /** * 一些简单的安全过滤: * xss * @author lgh */ +@Component public class XssFilter implements Filter { Logger logger = LoggerFactory.getLogger(getClass().getName()); diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/handler/HttpHandler.java b/yami-shop-common/src/main/java/com/yami/shop/common/handler/HttpHandler.java new file mode 100644 index 0000000..7e42838 --- /dev/null +++ b/yami-shop-common/src/main/java/com/yami/shop/common/handler/HttpHandler.java @@ -0,0 +1,51 @@ +package com.yami.shop.common.handler; + +import cn.hutool.core.util.CharsetUtil; +import com.yami.shop.common.exception.YamiShopBindException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +/** + * @author 菠萝凤梨 + * @date 2022/3/28 14:15 + */ +@Component +public class HttpHandler { + + private static final Logger logger = LoggerFactory.getLogger(HttpHandler.class); + + public void printServerResponseToWeb(String str, int status) { + + ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder + .getRequestAttributes(); + if (requestAttributes == null) { + logger.error("requestAttributes is null, can not print to web"); + return; + } + HttpServletResponse response = requestAttributes.getResponse(); + if (response == null) { + logger.error("httpServletResponse is null, can not print to web"); + return; + } + logger.error("response error: " + str); + response.setCharacterEncoding(CharsetUtil.UTF_8); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + response.setStatus(status); + PrintWriter printWriter = null; + try { + printWriter = response.getWriter(); + printWriter.write(str); + } + catch (IOException e) { + throw new YamiShopBindException("io 异常", e); + } + } +} diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/serializer/FSTSerializer.java b/yami-shop-common/src/main/java/com/yami/shop/common/serializer/FSTSerializer.java deleted file mode 100644 index 12d616e..0000000 --- a/yami-shop-common/src/main/java/com/yami/shop/common/serializer/FSTSerializer.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.common.serializer; - -import org.nustaq.serialization.FSTConfiguration; -import org.nustaq.serialization.FSTDecoder; -import org.nustaq.serialization.FSTEncoder; -import org.nustaq.serialization.coders.FSTStreamDecoder; -import org.nustaq.serialization.coders.FSTStreamEncoder; - -import java.io.IOException; -import java.lang.reflect.Field; - -/** - * 使用fts进行序列化 - * @author LGH - */ -public class FSTSerializer { - - static class FSTDefaultStreamCoderFactory implements FSTConfiguration.StreamCoderFactory { - - Field chBufField; - Field ascStringCacheField; - - { - try { - chBufField = FSTStreamDecoder.class.getDeclaredField("chBufS"); - ascStringCacheField = FSTStreamDecoder.class.getDeclaredField("ascStringCache"); - } catch (Exception e) { - throw new IllegalStateException(e); - } - ascStringCacheField.setAccessible(true); - chBufField.setAccessible(true); - } - - private FSTConfiguration fstConfiguration; - - FSTDefaultStreamCoderFactory(FSTConfiguration fstConfiguration) { - this.fstConfiguration = fstConfiguration; - } - - @Override - public FSTEncoder createStreamEncoder() { - return new FSTStreamEncoder(fstConfiguration); - } - - @Override - public FSTDecoder createStreamDecoder() { - return new FSTStreamDecoder(fstConfiguration) { - @Override - public String readStringUTF() throws IOException { - try { - String res = super.readStringUTF(); - chBufField.set(this, null); - return res; - } catch (Exception e) { - throw new IOException(e); - } - } - - @Override - public String readStringAsc() throws IOException { - try { - String res = super.readStringAsc(); - ascStringCacheField.set(this, null); - return res; - } catch (Exception e) { - throw new IOException(e); - } - } - }; - } - - static ThreadLocal input = new ThreadLocal(); - static ThreadLocal output = new ThreadLocal(); - - @Override - public ThreadLocal getInput() { - return input; - } - - @Override - public ThreadLocal getOutput() { - return output; - } - - } - - private static class InstanceHolder { - private static final FSTConfiguration INSTANCE = FSTConfiguration.createDefaultConfiguration(); - static { - INSTANCE.setStreamCoderFactory(new FSTDefaultStreamCoderFactory(INSTANCE)); - } - } - - public FSTConfiguration getConfig() { - return InstanceHolder.INSTANCE; - } -} diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/serializer/redis/FstRedisSerializer.java b/yami-shop-common/src/main/java/com/yami/shop/common/serializer/redis/FstRedisSerializer.java deleted file mode 100644 index aa55cae..0000000 --- a/yami-shop-common/src/main/java/com/yami/shop/common/serializer/redis/FstRedisSerializer.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.common.serializer.redis; - -import com.yami.shop.common.serializer.FSTSerializer; -import lombok.SneakyThrows; -import org.springframework.data.redis.serializer.RedisSerializer; -import org.springframework.lang.Nullable; - -/** - * 使用fst 进行reids的序列化 - * @author LGH - */ -public class FstRedisSerializer implements RedisSerializer { - - private static final byte[] EMPTY_ARRAY = new byte[0]; - - @Override - @SneakyThrows - public byte[] serialize(Object o) { - if (o == null) { - return EMPTY_ARRAY; - } - return new FSTSerializer().getConfig().asByteArray(o); - } - - @Override - @SneakyThrows - public Object deserialize(byte[] bytes) { - if (isEmpty(bytes)) { - return null; - } - return new FSTSerializer().getConfig().asObject(bytes); - } - - private static boolean isEmpty(@Nullable byte[] data) { - return (data == null || data.length == 0); - } -} diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/serializer/redis/KryoRedisSerializer.java b/yami-shop-common/src/main/java/com/yami/shop/common/serializer/redis/KryoRedisSerializer.java new file mode 100644 index 0000000..d27ed3d --- /dev/null +++ b/yami-shop-common/src/main/java/com/yami/shop/common/serializer/redis/KryoRedisSerializer.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.common.serializer.redis; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import lombok.extern.slf4j.Slf4j; +import org.redisson.codec.KryoCodec; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.SerializationException; + +import java.io.ByteArrayOutputStream; +import java.util.Collections; + +/** + * 使用Kryo 进行reids的序列化 + * @author LGH + */ +@Slf4j +public class KryoRedisSerializer implements RedisSerializer { + + private final KryoCodec kryoPool; + + public KryoRedisSerializer() { + kryoPool = new KryoCodec(Collections.emptyList(), null); + } + + private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; + + + @Override + public byte[] serialize(T t) throws SerializationException { + if (t == null) { + return EMPTY_BYTE_ARRAY; + } + + Kryo kryo = kryoPool.get(); + + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + Output output = new Output(baos)) { + kryo.writeClassAndObject(output, t); + output.flush(); + return baos.toByteArray(); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + + return EMPTY_BYTE_ARRAY; + } + + @Override + @SuppressWarnings("unchecked") + public T deserialize(byte[] bytes) throws SerializationException { + if (bytes == null || bytes.length <= 0) { + return null; + } + Kryo kryo = kryoPool.get(); + + try (Input input = new Input(bytes)) { + return (T) kryo.readClassAndObject(input); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return null; + } +} diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/serializer/redisson/FstCodec.java b/yami-shop-common/src/main/java/com/yami/shop/common/serializer/redisson/FstCodec.java deleted file mode 100644 index d2f9e95..0000000 --- a/yami-shop-common/src/main/java/com/yami/shop/common/serializer/redisson/FstCodec.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.common.serializer.redisson; - -import java.io.IOException; - -import com.yami.shop.common.serializer.FSTSerializer; -import org.nustaq.serialization.FSTConfiguration; -import org.nustaq.serialization.FSTObjectInput; -import org.nustaq.serialization.FSTObjectOutput; -import org.redisson.client.codec.BaseCodec; -import org.redisson.client.handler.State; -import org.redisson.client.protocol.Decoder; -import org.redisson.client.protocol.Encoder; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import io.netty.buffer.ByteBufInputStream; -import io.netty.buffer.ByteBufOutputStream; - -/** - * 被redisson使用 - * Efficient and speedy serialization codec fully - * compatible with JDK Serialization codec. - * - * https://github.com/RuedigerMoeller/fast-serialization - * - * @author Nikita Koksharov - * - */ -public class FstCodec extends BaseCodec { - - - private final FSTConfiguration config; - - public FstCodec() { - config = new FSTSerializer().getConfig(); - } - - - private final Decoder decoder = new Decoder() { - @Override - public Object decode(ByteBuf buf, State state) throws IOException { - ByteBufInputStream in = new ByteBufInputStream(buf); - FSTObjectInput inputStream = config.getObjectInput(in); - try { - return inputStream.readObject(); - } catch (IOException e) { - throw e; - } catch (Exception e) { - throw new IOException(e); - } - } - }; - - private final Encoder encoder = new Encoder() { - - @Override - public ByteBuf encode(Object in) throws IOException { - ByteBuf out = ByteBufAllocator.DEFAULT.buffer(); - ByteBufOutputStream os = new ByteBufOutputStream(out); - FSTObjectOutput oos = config.getObjectOutput(os); - try { - oos.writeObject(in); - oos.flush(); - return os.buffer(); - } catch (IOException e) { - out.release(); - throw e; - } catch (Exception e) { - out.release(); - throw new IOException(e); - } - } - }; - - @Override - public Decoder getValueDecoder() { - return decoder; - } - - @Override - public Encoder getValueEncoder() { - return encoder; - } - - @Override - public ClassLoader getClassLoader() { - if (config.getClassLoader() != null) { - return config.getClassLoader(); - } - - return super.getClassLoader(); - } - -} diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/util/Json.java b/yami-shop-common/src/main/java/com/yami/shop/common/util/Json.java index 2cdaa7a..d6825f9 100644 --- a/yami-shop-common/src/main/java/com/yami/shop/common/util/Json.java +++ b/yami-shop-common/src/main/java/com/yami/shop/common/util/Json.java @@ -11,23 +11,20 @@ package com.yami.shop.common.util; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonGenerator.Feature; -import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import lombok.extern.slf4j.Slf4j; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +@Slf4j public class Json { private static ObjectMapper objectMapper = new ObjectMapper(); @@ -80,7 +77,7 @@ public class Json { try { return objectMapper.writeValueAsString(object); } catch (JsonProcessingException e) { - e.printStackTrace(); + log.error("对象转json错误:", e); } return null; } @@ -96,7 +93,7 @@ public class Json { try { result = objectMapper.readValue(json, clazz); } catch (Exception e) { - e.printStackTrace(); + log.error("对象转json错误:", e); } return result; } @@ -117,7 +114,7 @@ public class Json { try { result = objectMapper.readValue(json, clazz); } catch (Exception e) { - e.printStackTrace(); + log.error("Json转换错误:", e); } if (result == null) { return Collections.emptyList(); @@ -136,18 +133,8 @@ public class Json { try { jsonNode = objectMapper.readTree(jsonStr); } catch (Exception e) { - e.printStackTrace(); + log.error("Json转换错误:", e); } return jsonNode; } - -// public static void main(String[] args){ -// String arr = "[1.01,1.03,1.23]"; -// -// List doubles = parseArray(arr, Double[].class); -// for (Double aDouble : doubles) { -// System.out.println(aDouble); -// } -// -// } } diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/util/PageAdapter.java b/yami-shop-common/src/main/java/com/yami/shop/common/util/PageAdapter.java index 53a7a28..6a40c51 100644 --- a/yami-shop-common/src/main/java/com/yami/shop/common/util/PageAdapter.java +++ b/yami-shop-common/src/main/java/com/yami/shop/common/util/PageAdapter.java @@ -14,6 +14,9 @@ import cn.hutool.core.util.PageUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.Data; +/** + * @author lh + */ @Data public class PageAdapter{ @@ -22,7 +25,7 @@ public class PageAdapter{ private int size; public PageAdapter(Page page) { - int[] startEnd = PageUtil.transToStartEnd((int) page.getCurrent(), (int) page.getSize()); + int[] startEnd = PageUtil.transToStartEnd((int) page.getCurrent() - 1, (int) page.getSize()); this.begin = startEnd[0]; this.size = (int)page.getSize(); } diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/util/PrincipalUtil.java b/yami-shop-common/src/main/java/com/yami/shop/common/util/PrincipalUtil.java index b08aa1d..6a97064 100644 --- a/yami-shop-common/src/main/java/com/yami/shop/common/util/PrincipalUtil.java +++ b/yami-shop-common/src/main/java/com/yami/shop/common/util/PrincipalUtil.java @@ -20,6 +20,11 @@ public class PrincipalUtil { */ public static final String USER_NAME_REGEXP = "([a-zA-Z0-9_]{4,16})"; + /** + * 由简单的字母数字拼接而成的字符串 不含有下划线,大写字母 + */ + public static final String SIMPLE_CHAR_REGEXP = "([a-z0-9]+)"; + public static boolean isMobile(String value) { if(StrUtil.isBlank(value)) { return false; @@ -33,4 +38,20 @@ public class PrincipalUtil { } return Pattern.matches(USER_NAME_REGEXP, value); } + + public static boolean isMatching(String regexp, String value) { + if (StrUtil.isBlank(value)) { + return false; + } + return Pattern.matches(regexp, value); + } + + /** + * 是否是由简单的字母数字拼接而成的字符串 + * @param value 输入值 + * @return 匹配结果 + */ + public static boolean isSimpleChar(String value) { + return isMatching(SIMPLE_CHAR_REGEXP, value); + } } diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/util/RedisUtil.java b/yami-shop-common/src/main/java/com/yami/shop/common/util/RedisUtil.java index fb71ecb..bf16ecd 100644 --- a/yami-shop-common/src/main/java/com/yami/shop/common/util/RedisUtil.java +++ b/yami-shop-common/src/main/java/com/yami/shop/common/util/RedisUtil.java @@ -10,97 +10,107 @@ package com.yami.shop.common.util; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; - +import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.util.CollectionUtils; +import java.util.concurrent.TimeUnit; + +/** + * @author lh + */ +@Slf4j public class RedisUtil { - private static RedisTemplate redisTemplate = SpringContextUtils.getBean("redisTemplate",RedisTemplate.class); - + private static RedisTemplate redisTemplate = SpringContextUtils.getBean("redisTemplate", RedisTemplate.class); + //=============================common============================ + /** * 指定缓存失效时间 - * @param key 键 + * + * @param key 键 * @param time 时间(秒) * @return */ - public static boolean expire(String key,long time){ + public static boolean expire(String key, long time) { try { - if(time>0){ + if (time > 0) { redisTemplate.expire(key, time, TimeUnit.SECONDS); } return true; } catch (Exception e) { - e.printStackTrace(); + log.error("设置redis指定key失效时间错误:", e); return false; } } /** * 根据key 获取过期时间 + * * @param key 键 不能为null * @return 时间(秒) 返回0代表为永久有效 失效时间为负数,说明该主键未设置失效时间(失效时间默认为-1) */ - public static long getExpire(String key){ - return redisTemplate.getExpire(key,TimeUnit.SECONDS); + public static long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); } /** * 判断key是否存在 + * * @param key 键 * @return true 存在 false 不存在 */ - public static boolean hasKey(String key){ + public static boolean hasKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { - e.printStackTrace(); + log.error("redis判断key是否存在错误:", e); return false; } } /** * 删除缓存 + * * @param key 可以传一个值 或多个 */ @SuppressWarnings("unchecked") - public static void del(String ... key){ - if(key!=null&&key.length>0){ - if(key.length==1){ + public static void del(String... key) { + if (key != null && key.length > 0) { + if (key.length == 1) { redisTemplate.delete(key[0]); - }else{ + } else { redisTemplate.delete(CollectionUtils.arrayToList(key)); } } } //============================String============================= + /** * 普通缓存获取 + * * @param key 键 * @return 值 */ @SuppressWarnings("unchecked") - public static T get(String key){ - return key==null?null:(T)redisTemplate.opsForValue().get(key); + public static T get(String key) { + return key == null ? null : (T) redisTemplate.opsForValue().get(key); } /** * 普通缓存放入 - * @param key 键 + * + * @param key 键 * @param value 值 * @return true成功 false失败 */ - public static boolean set(String key,Object value) { + public static boolean set(String key, Object value) { try { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { - e.printStackTrace(); + log.error("设置redis缓存错误:", e); return false; } @@ -108,16 +118,17 @@ public class RedisUtil { /** * 普通缓存放入并设置时间 - * @param key 键 + * + * @param key 键 * @param value 值 - * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 * @return true成功 false 失败 */ - public static boolean set(String key,Object value,long time){ + public static boolean set(String key, Object value, long time) { try { - if(time>0){ + if (time > 0) { redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); - }else{ + } else { set(key, value); } return true; @@ -129,12 +140,13 @@ public class RedisUtil { /** * 递增 此时value值必须为int类型 否则报错 - * @param key 键 + * + * @param key 键 * @param delta 要增加几(大于0) * @return */ - public static long incr(String key, long delta){ - if(delta<0){ + public static long incr(String key, long delta) { + if (delta < 0) { throw new RuntimeException("递增因子必须大于0"); } return redisTemplate.opsForValue().increment(key, delta); @@ -142,12 +154,13 @@ public class RedisUtil { /** * 递减 - * @param key 键 + * + * @param key 键 * @param delta 要减少几(小于0) * @return */ - public static long decr(String key, long delta){ - if(delta<0){ + public static long decr(String key, long delta) { + if (delta < 0) { throw new RuntimeException("递减因子必须大于0"); } return redisTemplate.opsForValue().increment(key, -delta); diff --git a/yami-shop-common/src/main/java/com/yami/shop/common/util/SimpleCaptcha.java b/yami-shop-common/src/main/java/com/yami/shop/common/util/SimpleCaptcha.java deleted file mode 100644 index 0e0c7bd..0000000 --- a/yami-shop-common/src/main/java/com/yami/shop/common/util/SimpleCaptcha.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.common.util; - -import cn.hutool.captcha.LineCaptcha; -import cn.hutool.core.util.ImageUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.RandomUtil; - -import java.awt.*; -import java.awt.image.BufferedImage; -import java.util.concurrent.ThreadLocalRandom; - -public class SimpleCaptcha extends LineCaptcha{ - - private static final long serialVersionUID = -9042552338521307038L; - - private static final String CAPTCHA_CODE = "abcdefhjkmnpqrstuvwxyz2345678"; - - public SimpleCaptcha(int width, int height, int codeCount, int interfereCount) { - - super(width, height, codeCount, interfereCount); - } - - @Override - protected void generateCode() { - this.code = RandomUtil.randomString(CAPTCHA_CODE,this.generator.getLength()); - } - - @Override - public Image createImage(String code) { - // 图像buffer - final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); - final ThreadLocalRandom random = RandomUtil.getRandom(); - final Graphics2D g = ImageUtil.createGraphics(image, new Color(249,249,249)); - - // 干扰线 - drawInterfere(g, random); - - // 创建字体 - g.setFont(this.font); - final FontMetrics metrics = g.getFontMetrics(); - int minY = metrics.getAscent() - metrics.getLeading() - metrics.getDescent(); - // 文字 - final int len = this.generator.getLength(); - int charWidth = width / len; - for (int i = 0; i < len; i++) { - // 产生随机的颜色值,让输出的每个字符的颜色值都将不同。 - g.setColor(ImageUtil.randomColor(random)); - g.drawString(String.valueOf(code.charAt(i)), i * charWidth, RandomUtil.randomInt(minY, this.height)); - } - - return image; - } - - /** - * 绘制干扰线 - * - * @param g {@link Graphics2D}画笔 - * @param random 随机对象 - */ - private void drawInterfere(Graphics2D g, ThreadLocalRandom random) { - // 干扰线 - for (int i = 0; i < this.interfereCount; i++) { - int xs = random.nextInt(width); - int ys = random.nextInt(height); - int xe = xs + random.nextInt(width / 8); - int ye = ys + random.nextInt(height / 8); - g.setColor(ImageUtil.randomColor(random)); - g.drawLine(xs, ys, xe, ye); - } - } - -} diff --git a/yami-shop-mp/pom.xml b/yami-shop-mp/pom.xml deleted file mode 100644 index 01098e2..0000000 --- a/yami-shop-mp/pom.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - yami-shop - com.yami.shop - 0.0.1-SNAPSHOT - - 4.0.0 - - yami-shop-mp - - - - com.yami.shop - yami-shop-security - ${yami.shop.version} - - - \ No newline at end of file diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/builder/AbstractBuilder.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/builder/AbstractBuilder.java deleted file mode 100644 index ccc7a01..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/builder/AbstractBuilder.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.mp.builder; - -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; -import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author Binary Wang(https://github.com/binarywang) - */ -public abstract class AbstractBuilder { - protected final Logger logger = LoggerFactory.getLogger(getClass()); - - public abstract WxMpXmlOutMessage build(String content, - WxMpXmlMessage wxMessage, WxMpService service); -} diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/builder/ImageBuilder.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/builder/ImageBuilder.java deleted file mode 100644 index e718a38..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/builder/ImageBuilder.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.mp.builder; - -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; -import me.chanjar.weixin.mp.bean.message.WxMpXmlOutImageMessage; -import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; - -/** - * @author Binary Wang(https://github.com/binarywang) - */ -public class ImageBuilder extends AbstractBuilder { - - @Override - public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage, - WxMpService service) { - - WxMpXmlOutImageMessage m = WxMpXmlOutMessage.IMAGE().mediaId(content) - .fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()) - .build(); - - return m; - } - -} diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/builder/TextBuilder.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/builder/TextBuilder.java deleted file mode 100644 index d68939e..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/builder/TextBuilder.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.mp.builder; - - -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; -import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; -import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTextMessage; - -/** - * @author Binary Wang(https://github.com/binarywang) - */ -public class TextBuilder extends AbstractBuilder { - - @Override - public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage, - WxMpService service) { - WxMpXmlOutTextMessage m = WxMpXmlOutMessage.TEXT().content(content) - .fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()) - .build(); - return m; - } - -} diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/component/WxMaInRedisConfig.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/component/WxMaInRedisConfig.java deleted file mode 100644 index f5730af..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/component/WxMaInRedisConfig.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.mp.component; - -import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; -import com.yami.shop.common.annotation.RedisLock; -import com.yami.shop.common.util.RedisUtil; -import com.yami.shop.mp.config.bean.WxMiniApp; -import me.chanjar.weixin.common.bean.WxAccessToken; -import org.redisson.api.RedissonClient; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.util.concurrent.locks.Lock; - -/** - * 基于Redis的微信配置provider. - * - * 已加入分布式锁的实现 - * - * @author LGH - */ -@Component -public class WxMaInRedisConfig extends WxMaDefaultConfigImpl { - - private static final String ACCESS_TOKEN_KEY = "wxMa:access_token:"; - - private static final String JSAPI_TICKET_KEY = "wxMa:jsapi_ticket:"; - - private static final String CARD_API_TICKET_KEY = "wxMa:card_api_ticket:"; - - private static final String WX_MA_ACCESS_TOKEN_LOCK = "wxMa:access_token_lock:"; - - private static final String WX_MA_JSAPI_TICKET_LOCK = "wxMa:jsapi_ticket_lock:"; - - private static final String WX_MA_CARD_API_TICKET_LOCK = "wxMa:card_api_ticket_lock:"; - - private String accessTokenKey; - - private String jsapiTicketKey; - - private String cardApiTicketKey; - - @Autowired - private RedissonClient redissonClient; - - public WxMaInRedisConfig (WxMiniApp wxMiniApp) { - this.setAppid(wxMiniApp.getAppid()); - this.setSecret(wxMiniApp.getSecret()); - } - - /** - * 每个公众号生成独有的存储key. - */ - @Override - public void setAppid(String appId) { - super.setAppid(appId); - this.accessTokenKey = ACCESS_TOKEN_KEY.concat(appId); - this.jsapiTicketKey = JSAPI_TICKET_KEY.concat(appId); - this.cardApiTicketKey = CARD_API_TICKET_KEY.concat(appId); - } - - @Override - public String getAccessToken() { - return RedisUtil.get(accessTokenKey); - } - - @Override - public Lock getAccessTokenLock(){ - return redissonClient.getLock(WX_MA_ACCESS_TOKEN_LOCK); - } - - @Override - public boolean isAccessTokenExpired() { - return !RedisUtil.hasKey(accessTokenKey); - } - - @Override - public void expireAccessToken() { - RedisUtil.del(accessTokenKey); - } - - @Override - @RedisLock(lockName = "updateMaAccessToken") - public void updateAccessToken(WxAccessToken accessToken) { - updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); - } - - - @Override - @RedisLock(lockName = "updateMaAccessToken") - public void updateAccessToken(String accessToken, int expiresInSeconds) { - RedisUtil.set(accessTokenKey, accessToken, expiresInSeconds - 200); - } - - @Override - public String getJsapiTicket() { - return RedisUtil.get(jsapiTicketKey); - } - - @Override - public Lock getJsapiTicketLock() { - return redissonClient.getLock(WX_MA_JSAPI_TICKET_LOCK); - } - - @Override - public boolean isJsapiTicketExpired() { - return !RedisUtil.hasKey(jsapiTicketKey); - } - - @Override - public void expireJsapiTicket() { - RedisUtil.del(jsapiTicketKey); - } - - @Override - @RedisLock(lockName = "updateMaJsapiTicket") - public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) { - RedisUtil.set(jsapiTicketKey, jsapiTicket, expiresInSeconds - 200); - } - - @Override - public String getCardApiTicket() { - return RedisUtil.get(cardApiTicketKey); - } - - @Override - public Lock getCardApiTicketLock() { - return redissonClient.getLock(WX_MA_CARD_API_TICKET_LOCK); - } - - @Override - public boolean isCardApiTicketExpired() { - return !RedisUtil.hasKey(cardApiTicketKey); - } - - @Override - public void expireCardApiTicket() { - RedisUtil.del(cardApiTicketKey); - } - - @Override - @RedisLock(lockName = "updateMaCardJsapiTicket") - public void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) { - RedisUtil.set(cardApiTicketKey, cardApiTicket, expiresInSeconds - 200); - } - -} diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/component/WxMaServiceClusterImpl.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/component/WxMaServiceClusterImpl.java deleted file mode 100644 index a36601c..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/component/WxMaServiceClusterImpl.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.yami.shop.mp.component; - -import cn.binarywang.wx.miniapp.api.WxMaService; -import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; -import cn.hutool.http.HttpUtil; -import com.yami.shop.common.exception.YamiShopBindException; -import lombok.extern.slf4j.Slf4j; -import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.common.error.WxError; -import me.chanjar.weixin.common.error.WxErrorException; -import org.redisson.api.RLock; -import org.redisson.api.RedissonClient; - -import java.util.concurrent.TimeUnit; - -/** - * WxMaServiceImpl 在集群模式获取accessToken的方式 - * @author LGH - */ -@Slf4j -public class WxMaServiceClusterImpl extends WxMaServiceImpl { - - private static final String REDISSON_LOCK_PREFIX = "redisson_lock:"; - - private RedissonClient redissonClient; - - public void setRedissonClient(RedissonClient redissonClient) { - this.redissonClient = redissonClient; - } - - @Override - public String getAccessToken(boolean forceRefresh) throws WxErrorException { - if (!this.getWxMaConfig().isAccessTokenExpired() && !forceRefresh) { - return this.getWxMaConfig().getAccessToken(); - } - - RLock rLock = redissonClient.getLock(REDISSON_LOCK_PREFIX + ":WxMaServiceCluster:getAccessToken"); - - try { - boolean lockSuccess; - try { - lockSuccess = rLock.tryLock(10, TimeUnit.SECONDS); - } catch (InterruptedException e) { - return this.getWxMaConfig().getAccessToken(); - } - - if (!lockSuccess) { - throw new YamiShopBindException("服务器繁忙,请稍后再试"); - } - - if (!this.getWxMaConfig().isAccessTokenExpired()) { - return this.getWxMaConfig().getAccessToken(); - } - - String url = String.format(WxMaService.GET_ACCESS_TOKEN_URL, this.getWxMaConfig().getAppid(), - this.getWxMaConfig().getSecret()); - String resultContent = HttpUtil.get(url); - WxError error = WxError.fromJson(resultContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } - WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); - this.getWxMaConfig().updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); - - return this.getWxMaConfig().getAccessToken(); - - } finally { - rLock.unlock(); - } - - } -} diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/component/WxMpInRedisConfigStorage.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/component/WxMpInRedisConfigStorage.java deleted file mode 100644 index fb6e9ac..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/component/WxMpInRedisConfigStorage.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.mp.component; - -import com.yami.shop.common.annotation.RedisLock; -import com.yami.shop.common.util.RedisUtil; -import com.yami.shop.mp.config.bean.WxMp; -import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; -import me.chanjar.weixin.mp.enums.TicketType; -import org.springframework.stereotype.Component; - -/** - * 基于Redis的微信配置provider. - * - * 已加入分布式锁的实现 - * - * @author LGH - */ -@Component -public class WxMpInRedisConfigStorage extends WxMpDefaultConfigImpl { - - private static final String ACCESS_TOKEN_KEY = "wxMp:access_token:"; - - private String accessTokenKey; - - public WxMpInRedisConfigStorage (WxMp wxMp) { - this.setAppId(wxMp.getAppid()); - this.setSecret(wxMp.getSecret()); - this.setToken(wxMp.getToken()); - this.setAesKey(wxMp.getAesKey()); - } - - /** - * 每个公众号生成独有的存储key. - */ - @Override - public void setAppId(String appId) { - super.setAppId(appId); - this.accessTokenKey = ACCESS_TOKEN_KEY.concat(appId); - } - - private String getTicketRedisKey(TicketType type) { - return String.format("wx:ticket:key:%s:%s", this.appId, type.getCode()); - } - - @Override - public String getAccessToken() { - return RedisUtil.get(accessTokenKey); - } - - @Override - public boolean isAccessTokenExpired() { - return !RedisUtil.hasKey(accessTokenKey); - } - - @Override - @RedisLock(lockName = "updateMpAccessToken") - public void updateAccessToken(WxAccessToken accessToken) { - updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); - } - - - @Override - @RedisLock(lockName = "updateMpAccessToken") - public void updateAccessToken(String accessToken, int expiresInSeconds) { - RedisUtil.set(accessTokenKey, accessToken, expiresInSeconds - 200); - } - - @Override - public void expireAccessToken() { - RedisUtil.del(accessTokenKey); - } - - @Override - public String getTicket(TicketType type) { - return RedisUtil.get(this.getTicketRedisKey(type)); - } - - @Override - public boolean isTicketExpired(TicketType type) { - return !RedisUtil.hasKey(this.getTicketRedisKey(type)); - } - - @Override - @RedisLock(lockName = "updateMpJsapiTicket") - public void updateTicket(TicketType type, String jsapiTicket, int expiresInSeconds) { - RedisUtil.set(this.getTicketRedisKey(type), jsapiTicket, expiresInSeconds - 200); - } - - @Override - public void expireTicket(TicketType type) { - RedisUtil.del(this.getTicketRedisKey(type)); - } - -} diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/component/WxMpServiceClusterImpl.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/component/WxMpServiceClusterImpl.java deleted file mode 100644 index bae99df..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/component/WxMpServiceClusterImpl.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.yami.shop.mp.component; - -import cn.hutool.http.HttpUtil; -import com.yami.shop.common.exception.YamiShopBindException; -import me.chanjar.weixin.common.WxType; -import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.common.error.WxError; -import me.chanjar.weixin.common.error.WxErrorException; -import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl; -import org.redisson.api.RLock; -import org.redisson.api.RedissonClient; - -import java.util.concurrent.TimeUnit; - -import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.GET_ACCESS_TOKEN_URL; - -/** - * WxMpServiceImpl 在集群模式获取accessToken的方式 - * @author LGH - */ -public class WxMpServiceClusterImpl extends WxMpServiceHttpClientImpl { - - - private static final String REDISSON_LOCK_PREFIX = "redisson_lock:"; - - private RedissonClient redissonClient; - - public void setRedissonClient(RedissonClient redissonClient) { - this.redissonClient = redissonClient; - } - - @Override - public String getAccessToken(boolean forceRefresh) throws WxErrorException { - if (!this.getWxMpConfigStorage().isAccessTokenExpired() && !forceRefresh) { - return this.getWxMpConfigStorage().getAccessToken(); - } - - RLock rLock = redissonClient.getLock(REDISSON_LOCK_PREFIX + ":WxMpServiceCluster:getAccessToken"); - - try { - boolean doingUpdateAccessToken; - try { - doingUpdateAccessToken = rLock.tryLock(10, TimeUnit.SECONDS); - } catch (InterruptedException e) { - return this.getWxMpConfigStorage().getAccessToken(); - } - - if (!doingUpdateAccessToken) { - throw new YamiShopBindException("服务器繁忙,请稍后再试"); - } - - if (!this.getWxMpConfigStorage().isAccessTokenExpired()) { - return this.getWxMpConfigStorage().getAccessToken(); - } - String url = String.format(GET_ACCESS_TOKEN_URL.getUrl(this.getWxMpConfigStorage()), this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret()); - String resultContent = HttpUtil.get(url); - - WxError error = WxError.fromJson(resultContent, WxType.MP); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } - WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); - this.getWxMpConfigStorage().updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); - return this.getWxMpConfigStorage().getAccessToken(); - - } finally { - rLock.unlock(); - } - } -} diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/config/WxMaConfiguration.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/config/WxMaConfiguration.java deleted file mode 100644 index 6670f37..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/config/WxMaConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.mp.config; - -import cn.binarywang.wx.miniapp.api.WxMaService; -import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; -import com.yami.shop.mp.component.WxMaInRedisConfig; -import com.yami.shop.mp.component.WxMaServiceClusterImpl; -import lombok.AllArgsConstructor; -import org.redisson.api.RedissonClient; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * 微信小程序配置文件 - * @author LGH - */ -@Configuration -@AllArgsConstructor -@ConditionalOnClass(WxMaService.class) -public class WxMaConfiguration { - - - private final WxMaInRedisConfig wxMaInRedisConfig; - - private final RedissonClient redissonClient; - - @Bean - public WxMaService wxMaService() { - WxMaServiceClusterImpl service = new WxMaServiceClusterImpl(); - service.setWxMaConfig(wxMaInRedisConfig); - service.setRedissonClient(redissonClient); - return service; - } - - -} diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/config/WxMpConfiguration.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/config/WxMpConfiguration.java deleted file mode 100644 index 44d5c61..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/config/WxMpConfiguration.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.mp.config; - -import com.yami.shop.mp.component.WxMpInRedisConfigStorage; -import com.yami.shop.mp.component.WxMpServiceClusterImpl; -import com.yami.shop.mp.handler.MenuHandler; -import lombok.AllArgsConstructor; -import me.chanjar.weixin.mp.api.WxMpMessageRouter; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; -import org.redisson.api.RedissonClient; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static me.chanjar.weixin.common.api.WxConsts.MenuButtonType; -import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType; - -/** - * 微信公众号配置文件 - * @author LGH - */ -@Configuration -@AllArgsConstructor -@ConditionalOnClass(WxMpService.class) -public class WxMpConfiguration { - - private final MenuHandler menuHandler; - private final WxMpInRedisConfigStorage wxMpInRedisConfigStorage; - private final RedissonClient redissonClient; - - @Bean - public WxMpService wxMpService() { - WxMpServiceClusterImpl service = new WxMpServiceClusterImpl(); - service.setWxMpConfigStorage(wxMpInRedisConfigStorage); - service.setRedissonClient(redissonClient); - return service; - } - - @Bean - public WxMpMessageRouter messageRouter() { - final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService()); - - // 自定义菜单事件 - newRouter.rule().async(false).msgType(XmlMsgType.EVENT) - .event(MenuButtonType.CLICK).handler(this.menuHandler).end(); - - - return newRouter; - } - -} diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/config/WxPayConfiguration.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/config/WxPayConfiguration.java deleted file mode 100644 index 260c3fd..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/config/WxPayConfiguration.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.mp.config; - -import com.github.binarywang.wxpay.config.WxPayConfig; -import com.github.binarywang.wxpay.constant.WxPayConstants; -import com.github.binarywang.wxpay.exception.WxPayException; -import com.github.binarywang.wxpay.service.WxPayService; -import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; -import com.yami.shop.mp.config.bean.WxMiniApp; -import com.yami.shop.mp.config.bean.WxMp; -import com.yami.shop.mp.config.bean.WxPay; -import lombok.AllArgsConstructor; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import java.util.Objects; - -/** - * 微信公众号配置文件 - * - * @author LGH - */ -@Configuration -@RequiredArgsConstructor -@ConditionalOnClass(WxPayService.class) -public class WxPayConfiguration { - - private final WxMp wxMp; - - private final WxMiniApp wxMiniApp; - - private final WxPay wxPay; - - @Value("${spring.profiles.active}") - private String profile; - - - @Bean - public WxPayService wxMiniPayService() { - return getWxMpPayServiceByAppId(wxMiniApp.getAppid()); - } - - @Bean - public WxPayService wxMpPayService() { - return getWxMpPayServiceByAppId(wxMp.getAppid()); - } - - - private WxPayService getWxMpPayServiceByAppId(String appid) { - WxPayConfig payConfig = new WxPayConfig(); - payConfig.setAppId(appid); - payConfig.setMchId(wxPay.getMchId()); - payConfig.setMchKey(wxPay.getMchKey()); - payConfig.setKeyPath(wxPay.getKeyPath()); - payConfig.setSignType(WxPayConstants.SignType.MD5); - - WxPayService wxPayService = new WxPayServiceImpl(); - -// 打开下面的代码,开启沙箱模式 -// if (Objects.equals(profile, "dev")) { -// String sandboxSignKey = null; -// try { -// wxPayService.setConfig(payConfig); -// sandboxSignKey = wxPayService.getSandboxSignKey(); -// } catch (WxPayException e) { -// e.printStackTrace(); -// } -// payConfig.setUseSandboxEnv(true); -// payConfig.setMchKey(sandboxSignKey); -// } - - wxPayService.setConfig(payConfig); - return wxPayService; - } -} diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/config/bean/WxMiniApp.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/config/bean/WxMiniApp.java deleted file mode 100644 index 5c268c6..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/config/bean/WxMiniApp.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.mp.config.bean; - - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.PropertySource; -import org.springframework.stereotype.Component; - -@Data -@Component -@PropertySource("classpath:ma.properties") -@ConfigurationProperties(prefix = "ma") -public class WxMiniApp { - /** - * 设置微信小程序的appid - */ - private String appid; - - /** - * 设置微信小程序的Secret - */ - private String secret; - -} diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/config/bean/WxMp.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/config/bean/WxMp.java deleted file mode 100644 index e372019..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/config/bean/WxMp.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.mp.config.bean; - - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.PropertySource; -import org.springframework.stereotype.Component; - -@Data -@Component -@PropertySource("classpath:mp.properties") -@ConfigurationProperties(prefix = "mp") -public class WxMp { - /** - * 设置微信公众号的appid - */ - private String appid; - - /** - * 设置微信公众号的Secret - */ - private String secret; - - /** - * 微信公众号消息加解密token - */ - private String token; - - /** - * 微信公众号消息加解密aesKey - */ - private String aesKey; -} diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/config/bean/WxPay.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/config/bean/WxPay.java deleted file mode 100644 index 8dc1541..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/config/bean/WxPay.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.mp.config.bean; - - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.PropertySource; -import org.springframework.stereotype.Component; - -@Data -@Component -@PropertySource("classpath:pay.properties") -@ConfigurationProperties(prefix = "pay") -public class WxPay { - /** - * 微信支付mchId - */ - private String mchId; - - /** - * 微信支付mchKey - */ - private String mchKey; - - /** - * 签名类型 - */ - private String signType; - - /** - * 支付证书路径 - */ - private String keyPath; - - -} diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/controller/api/WxPortalController.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/controller/api/WxPortalController.java deleted file mode 100644 index f38633d..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/controller/api/WxPortalController.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.mp.controller.api; - -import me.chanjar.weixin.mp.api.WxMpMessageRouter; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; -import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Lazy; -import org.springframework.web.bind.annotation.*; - -/** - */ -@RestController -@RequestMapping("/wx/portal") -public class WxPortalController { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private WxMpService wxMpService; - - @Autowired - private WxMpMessageRouter wxMpMessageRouter; - - /** - * 用来进行微信认证,也就是当在: - * 公众号官方管理后台->开发->基本配置->修改配置 时,需要进行的校验 - * - * @return - */ - @GetMapping(produces = "text/plain;charset=utf-8") - public String authGet(@RequestParam(name = "signature", required = false) String signature, - @RequestParam(name = "timestamp", required = false) String timestamp, - @RequestParam(name = "nonce", required = false) String nonce, - @RequestParam(name = "echostr", required = false) String echostr) { - - this.logger.info("\n接收到来自微信服务器的认证消息:[{}, {}, {}, {}]", signature, - timestamp, nonce, echostr); - if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) { - throw new IllegalArgumentException("请求参数非法,请核实!"); - } - - if (wxMpService.checkSignature(timestamp, nonce, signature)) { - return echostr; - } - - return "非法请求"; - } - - /** - * 接收公众号的消息 - * - * @return - */ - @PostMapping(produces = "application/xml; charset=UTF-8") - public String post(@RequestBody String requestBody, - @RequestParam("signature") String signature, - @RequestParam("timestamp") String timestamp, - @RequestParam("nonce") String nonce, - @RequestParam("openid") String openid, - @RequestParam(name = "encrypt_type", required = false) String encType, - @RequestParam(name = "msg_signature", required = false) String msgSignature) { - this.logger.info("\n接收微信请求:[openid=[{}], [signature=[{}], encType=[{}], msgSignature=[{}]," - + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ", - openid, signature, encType, msgSignature, timestamp, nonce, requestBody); - - - String out = null; - if (encType == null) { - // 明文传输的消息 - WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody); - WxMpXmlOutMessage outMessage = this.route(inMessage); - if (outMessage == null) { - return ""; - } - - out = outMessage.toXml(); - } else if ("aes".equalsIgnoreCase(encType)) { - // aes加密的消息 - WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, wxMpService.getWxMpConfigStorage(), - timestamp, nonce, msgSignature); - this.logger.debug("\n消息解密后内容为:\n{} ", inMessage.toString()); - WxMpXmlOutMessage outMessage = this.route(inMessage); - if (outMessage == null) { - return ""; - } - - out = outMessage.toEncryptedXml(wxMpService.getWxMpConfigStorage()); - } - - this.logger.debug("\n组装回复信息:{}", out); - return out; - } - - private WxMpXmlOutMessage route(WxMpXmlMessage message) { - try { - return wxMpMessageRouter.route(message); - } catch (Exception e) { - this.logger.error("路由消息时出现异常!", e); - } - return null; - } - -} \ No newline at end of file diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/handler/AbstractHandler.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/handler/AbstractHandler.java deleted file mode 100644 index b9415f1..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/handler/AbstractHandler.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.mp.handler; - -import me.chanjar.weixin.mp.api.WxMpMessageHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author Binary Wang(https://github.com/binarywang) - */ -public abstract class AbstractHandler implements WxMpMessageHandler { - protected Logger logger = LoggerFactory.getLogger(getClass()); -} diff --git a/yami-shop-mp/src/main/java/com/yami/shop/mp/handler/MenuHandler.java b/yami-shop-mp/src/main/java/com/yami/shop/mp/handler/MenuHandler.java deleted file mode 100644 index 465a1c3..0000000 --- a/yami-shop-mp/src/main/java/com/yami/shop/mp/handler/MenuHandler.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.mp.handler; - -import me.chanjar.weixin.common.session.WxSessionManager; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; -import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; -import org.springframework.stereotype.Component; - -import java.util.Map; - -import static me.chanjar.weixin.common.api.WxConsts.MenuButtonType; - -/** - * @author Binary Wang(https://github.com/binarywang) - */ -@Component -public class MenuHandler extends AbstractHandler { - - @Override - public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, - Map context, WxMpService weixinService, - WxSessionManager sessionManager) { - - String msg = String.format("type:%s, event:%s, key:%s", - wxMessage.getMsgType(), wxMessage.getEvent(), - wxMessage.getEventKey()); - if (MenuButtonType.VIEW.equals(wxMessage.getEvent())) { - return null; - } - - return WxMpXmlOutMessage.TEXT().content(msg) - .fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()) - .build(); - } - -} diff --git a/yami-shop-mp/src/main/resources/ma.properties b/yami-shop-mp/src/main/resources/ma.properties deleted file mode 100644 index 5b3cc3b..0000000 --- a/yami-shop-mp/src/main/resources/ma.properties +++ /dev/null @@ -1,2 +0,0 @@ -ma.appid= -ma.secret= \ No newline at end of file diff --git a/yami-shop-mp/src/main/resources/mp.properties b/yami-shop-mp/src/main/resources/mp.properties deleted file mode 100644 index a3c4d4d..0000000 --- a/yami-shop-mp/src/main/resources/mp.properties +++ /dev/null @@ -1,4 +0,0 @@ -mp.appid= -mp.secret= -mp.token= -mp.aesKey= diff --git a/yami-shop-mp/src/main/resources/pay.properties b/yami-shop-mp/src/main/resources/pay.properties deleted file mode 100644 index 8e802d4..0000000 --- a/yami-shop-mp/src/main/resources/pay.properties +++ /dev/null @@ -1,3 +0,0 @@ -pay.mchId= -pay.mchKey= -pay.keyPath=classpath:xxx.p12 \ No newline at end of file diff --git a/yami-shop-mp/src/main/resources/xxx.p12 b/yami-shop-mp/src/main/resources/xxx.p12 deleted file mode 100644 index e69de29..0000000 diff --git a/yami-shop-quartz/pom.xml b/yami-shop-quartz/pom.xml index cf6fe32..944f36b 100644 --- a/yami-shop-quartz/pom.xml +++ b/yami-shop-quartz/pom.xml @@ -23,7 +23,7 @@ com.yami.shop - yami-shop-security + yami-shop-security-admin ${yami.shop.version} diff --git a/yami-shop-quartz/src/main/java/com/yami/shop/quartz/controller/ScheduleJobController.java b/yami-shop-quartz/src/main/java/com/yami/shop/quartz/controller/ScheduleJobController.java index d231cce..8e12466 100644 --- a/yami-shop-quartz/src/main/java/com/yami/shop/quartz/controller/ScheduleJobController.java +++ b/yami-shop-quartz/src/main/java/com/yami/shop/quartz/controller/ScheduleJobController.java @@ -10,32 +10,21 @@ package com.yami.shop.quartz.controller; -import javax.validation.Valid; - - +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.yami.shop.common.annotation.SysLog; import com.yami.shop.common.exception.YamiShopBindException; +import com.yami.shop.common.util.PageParam; import com.yami.shop.quartz.model.ScheduleJob; import com.yami.shop.quartz.service.ScheduleJobService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; - -import com.yami.shop.common.util.PageParam; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.yami.shop.common.annotation.SysLog; - -import cn.hutool.core.util.StrUtil; +import javax.validation.Valid; diff --git a/yami-shop-quartz/src/main/java/com/yami/shop/quartz/util/SpringBeanTaskUtil.java b/yami-shop-quartz/src/main/java/com/yami/shop/quartz/util/SpringBeanTaskUtil.java index f80e9a3..09bf2b1 100644 --- a/yami-shop-quartz/src/main/java/com/yami/shop/quartz/util/SpringBeanTaskUtil.java +++ b/yami-shop-quartz/src/main/java/com/yami/shop/quartz/util/SpringBeanTaskUtil.java @@ -39,7 +39,7 @@ public class SpringBeanTaskUtil { method.invoke(target); } } catch (Exception e) { - e.printStackTrace(); + log.error("执行定时任务失败:", e); throw new RuntimeException("执行定时任务失败", e); } } diff --git a/yami-shop-security/pom.xml b/yami-shop-security/pom.xml index a5c1db0..d1c4c72 100644 --- a/yami-shop-security/pom.xml +++ b/yami-shop-security/pom.xml @@ -11,16 +11,12 @@ yami-shop-security - - - com.yami.shop - yami-shop-service - ${yami.shop.version} - - - - org.springframework.security.oauth.boot - spring-security-oauth2-autoconfigure - - + 商城安全模块 + pom + + + yami-shop-security-api + yami-shop-security-admin + yami-shop-security-common + \ No newline at end of file diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/config/AuthorizationServerConfig.java b/yami-shop-security/src/main/java/com/yami/shop/security/config/AuthorizationServerConfig.java deleted file mode 100644 index 87a179a..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/config/AuthorizationServerConfig.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.config; - - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; -import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; -import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; -import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; -import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; -import org.springframework.security.oauth2.provider.token.TokenEnhancer; -import org.springframework.security.oauth2.provider.token.TokenStore; - -/** - * @author LGH - */ -@Configuration -//@Order(2) -@EnableAuthorizationServer -public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { - - @Autowired - private AuthenticationManager authenticationManager; - - @Autowired - private TokenStore tokenStore; - - @Autowired - private AuthorizationServerTokenServices yamiTokenServices; - - @Autowired - private TokenEnhancer tokenEnhancer; - - @Autowired - private UserDetailsService userDetailsService; - - - @Override - public void configure(AuthorizationServerEndpointsConfigurer endpoints) { - endpoints.authenticationManager(authenticationManager) - .tokenStore(tokenStore) - .tokenEnhancer(tokenEnhancer) - // refresh_token需要userDetailsService - .reuseRefreshTokens(false) - .userDetailsService(userDetailsService); - endpoints.tokenServices(yamiTokenServices); - } - - - @Override - public void configure(AuthorizationServerSecurityConfigurer oauthServer) { - oauthServer - // 开启/oauth/token_key验证端口无权限访问 - .tokenKeyAccess("permitAll()") - // 开启/oauth/check_token验证端口认证权限访问 - .checkTokenAccess("isAuthenticated()"); - } - - - - - - -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/config/TokenConfig.java b/yami-shop-security/src/main/java/com/yami/shop/security/config/TokenConfig.java deleted file mode 100644 index 3e31c24..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/config/TokenConfig.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.yami.shop.security.config; - -import com.yami.shop.security.constants.SecurityConstants; -import com.yami.shop.security.util.YamiTokenServices; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; -import org.springframework.context.annotation.Primary; -import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.security.authentication.ProviderManager; -import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; -import org.springframework.security.oauth2.provider.token.TokenEnhancer; -import org.springframework.security.oauth2.provider.token.TokenStore; -import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore; -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider; - -import java.util.Collections; - -/** - * @author LGH - */ -@Configuration -public class TokenConfig { - - - @Autowired - private UserDetailsService userDetailsService; - - @Autowired - private RedisConnectionFactory redisConnectionFactory; - - @Autowired - private TokenEnhancer tokenEnhancer; - - @Bean - public TokenStore tokenStore() { - RedisTokenStore tokenStore = new RedisTokenStore(redisConnectionFactory); - tokenStore.setPrefix(SecurityConstants.YAMI_OAUTH_PREFIX); - return tokenStore; - } - - - @Primary - @Bean - @Lazy - public AuthorizationServerTokenServices yamiTokenServices() { - YamiTokenServices tokenServices = new YamiTokenServices(); - tokenServices.setTokenStore(tokenStore()); - //支持刷新token - tokenServices.setSupportRefreshToken(true); - tokenServices.setReuseRefreshToken(true); - tokenServices.setTokenEnhancer(tokenEnhancer); - addUserDetailsService(tokenServices); - return tokenServices; - } - - private void addUserDetailsService(YamiTokenServices tokenServices) { - PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider(); - provider.setPreAuthenticatedUserDetailsService(new UserDetailsByNameServiceWrapper<>(userDetailsService)); - tokenServices.setAuthenticationManager(new ProviderManager(Collections.singletonList(provider))); - } - -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/constants/SecurityConstants.java b/yami-shop-security/src/main/java/com/yami/shop/security/constants/SecurityConstants.java deleted file mode 100644 index b6560c8..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/constants/SecurityConstants.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.constants; - -public interface SecurityConstants { - /** - * oauth 相关前缀 - */ - String YAMI_OAUTH_PREFIX = "yami_oauth:"; - - - String SPRING_SECURITY_RESTFUL_IMAGE_CODE = "imageCode"; -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/controller/SysLoginController.java b/yami-shop-security/src/main/java/com/yami/shop/security/controller/SysLoginController.java deleted file mode 100644 index e5ee1d3..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/controller/SysLoginController.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.controller; - - -import java.awt.*; -import java.io.IOException; - -import javax.servlet.http.HttpServletResponse; - -import com.yami.shop.security.constants.SecurityConstants; - -import com.yami.shop.security.service.YamiSysUser; -import com.yami.shop.security.util.SecurityUtils; -import lombok.AllArgsConstructor; -import org.redisson.api.RedissonClient; -import org.springframework.cache.Cache; -import org.springframework.cache.CacheManager; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; - -import com.yami.shop.common.util.RedisUtil; -import com.yami.shop.common.util.SimpleCaptcha; -import springfox.documentation.annotations.ApiIgnore; - -/** - * 登录相关 - * @author lgh - */ -@Controller -@AllArgsConstructor -@ApiIgnore -public class SysLoginController { - - private final CacheManager cacheManager; - - - @GetMapping("/captcha.jpg") - public void login(HttpServletResponse response,String uuid) { - //定义图形验证码的长、宽、验证码字符数、干扰元素个数 - SimpleCaptcha simpleCaptcha = new SimpleCaptcha(200, 50, 4, 20); - try { - simpleCaptcha.write(response.getOutputStream()); - RedisUtil.set(SecurityConstants.SPRING_SECURITY_RESTFUL_IMAGE_CODE+uuid, simpleCaptcha.getCode(), 300); - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * 退出 - */ - @PostMapping(value = "/sys/logout") - public ResponseEntity logout() { - SecurityContextHolder.clearContext(); - return ResponseEntity.ok().build(); - } - -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/dao/AppConnectMapper.java b/yami-shop-security/src/main/java/com/yami/shop/security/dao/AppConnectMapper.java deleted file mode 100644 index b77fbe3..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/dao/AppConnectMapper.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.dao; - -import com.yami.shop.security.model.AppConnect; -import org.apache.ibatis.annotations.Param; - - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; - -public interface AppConnectMapper extends BaseMapper { - - AppConnect getByBizUserId(@Param("bizUserId") String bizUserId, @Param("appId") Integer appId); - - AppConnect getByUserId(@Param("userId") String userId, @Param("appId") Integer appId); - - String getUserIdByUnionId(@Param("bizUnionId") String bizUnionId); -} \ No newline at end of file diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/enums/App.java b/yami-shop-security/src/main/java/com/yami/shop/security/enums/App.java deleted file mode 100644 index ad1e182..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/enums/App.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.enums; - -public enum App { - - /** - * 小程序 - */ - MINI(1), - - /** - * 微信公众号 - */ - MP(2), - - /** - * H5 - */ - H5(3) - ; - - private Integer num; - - public Integer value() { - return num; - } - - App(Integer num){ - this.num = num; - } - - public static App instance(Integer value) { - App[] enums = values(); - for (App statusEnum : enums) { - if (statusEnum.value().equals(value)) { - return statusEnum; - } - } - return null; - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/exception/BadCredentialsException.java b/yami-shop-security/src/main/java/com/yami/shop/security/exception/BadCredentialsException.java deleted file mode 100644 index b485b98..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/exception/BadCredentialsException.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.exception; - -/** - * 密码不正确 - */ -public class BadCredentialsException extends YamiAuth2Exception{ - public BadCredentialsException(String msg) { - super(msg); - } - - @Override - public String getOAuth2ErrorCode() { - return "bad_credentials"; - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/exception/BadCredentialsExceptionBase.java b/yami-shop-security/src/main/java/com/yami/shop/security/exception/BadCredentialsExceptionBase.java deleted file mode 100644 index 325cc7a..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/exception/BadCredentialsExceptionBase.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.exception; - -/** - * 密码不正确 - */ -public class BadCredentialsExceptionBase extends BaseYamiAuth2Exception { - public BadCredentialsExceptionBase(String msg) { - super(msg); - } - - @Override - public String getOAuth2ErrorCode() { - return "bad_credentials"; - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/exception/BaseYamiAuth2Exception.java b/yami-shop-security/src/main/java/com/yami/shop/security/exception/BaseYamiAuth2Exception.java deleted file mode 100644 index aa72e23..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/exception/BaseYamiAuth2Exception.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.exception; - -import lombok.Getter; -import org.springframework.http.HttpStatus; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; - -/** - */ -public abstract class BaseYamiAuth2Exception extends AuthenticationException { - - public BaseYamiAuth2Exception(String msg) { - super(msg); - } - - public int getHttpErrorCode() { - // 400 not 401 - return HttpStatus.BAD_REQUEST.value(); - } - - public abstract String getOAuth2ErrorCode(); -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/exception/ImageCodeNotMatchException.java b/yami-shop-security/src/main/java/com/yami/shop/security/exception/ImageCodeNotMatchException.java deleted file mode 100644 index b3716d2..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/exception/ImageCodeNotMatchException.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.exception; - -public class ImageCodeNotMatchException extends YamiAuth2Exception { - - public ImageCodeNotMatchException(String msg) { - super(msg); - } - - @Override - public String getOAuth2ErrorCode() { - return "image_code_not_match"; - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/exception/ImageCodeNotMatchExceptionBase.java b/yami-shop-security/src/main/java/com/yami/shop/security/exception/ImageCodeNotMatchExceptionBase.java deleted file mode 100644 index 7d66a45..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/exception/ImageCodeNotMatchExceptionBase.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.exception; - -public class ImageCodeNotMatchExceptionBase extends BaseYamiAuth2Exception { - - public ImageCodeNotMatchExceptionBase(String msg) { - super(msg); - } - - @Override - public String getOAuth2ErrorCode() { - return "image_code_not_match"; - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/exception/UnauthorizedException.java b/yami-shop-security/src/main/java/com/yami/shop/security/exception/UnauthorizedException.java deleted file mode 100644 index 0765a8c..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/exception/UnauthorizedException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.exception; - -import org.springframework.http.HttpStatus; - -/** - */ -public class UnauthorizedException extends YamiAuth2Exception { - - public UnauthorizedException(String msg) { - super(msg); - } - - - public UnauthorizedException(String msg, Throwable t) { - super(msg); - } - - @Override - public String getOAuth2ErrorCode() { - return "unauthorized"; - } - - @Override - public int getHttpErrorCode() { - return HttpStatus.UNAUTHORIZED.value(); - } - -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/exception/UnauthorizedExceptionBase.java b/yami-shop-security/src/main/java/com/yami/shop/security/exception/UnauthorizedExceptionBase.java deleted file mode 100644 index ae56ecc..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/exception/UnauthorizedExceptionBase.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.exception; - -import org.springframework.http.HttpStatus; - -/** - */ -public class UnauthorizedExceptionBase extends BaseYamiAuth2Exception { - - public UnauthorizedExceptionBase(String msg) { - super(msg); - } - - - public UnauthorizedExceptionBase(String msg, Throwable t) { - super(msg); - } - - @Override - public String getOAuth2ErrorCode() { - return "unauthorized"; - } - - @Override - public int getHttpErrorCode() { - return HttpStatus.UNAUTHORIZED.value(); - } - -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/exception/UnknownGrantTypeException.java b/yami-shop-security/src/main/java/com/yami/shop/security/exception/UnknownGrantTypeException.java deleted file mode 100644 index 415e819..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/exception/UnknownGrantTypeException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.exception; - -import org.springframework.http.HttpStatus; - -public class UnknownGrantTypeException extends YamiAuth2Exception { - - public UnknownGrantTypeException(String msg) { - super(msg); - } - - - public UnknownGrantTypeException(String msg, Throwable t) { - super(msg); - } - - @Override - public String getOAuth2ErrorCode() { - return "unknown_grant_type"; - } - - @Override - public int getHttpErrorCode() { - return HttpStatus.UNAUTHORIZED.value(); - } - -} \ No newline at end of file diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/exception/UnknownGrantTypeExceptionBase.java b/yami-shop-security/src/main/java/com/yami/shop/security/exception/UnknownGrantTypeExceptionBase.java deleted file mode 100644 index 9a57a52..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/exception/UnknownGrantTypeExceptionBase.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.exception; - -import org.springframework.http.HttpStatus; - -public class UnknownGrantTypeExceptionBase extends BaseYamiAuth2Exception { - - public UnknownGrantTypeExceptionBase(String msg) { - super(msg); - } - - - public UnknownGrantTypeExceptionBase(String msg, Throwable t) { - super(msg); - } - - @Override - public String getOAuth2ErrorCode() { - return "unknown_grant_type"; - } - - @Override - public int getHttpErrorCode() { - return HttpStatus.UNAUTHORIZED.value(); - } - -} \ No newline at end of file diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/exception/UsernameNotFoundException.java b/yami-shop-security/src/main/java/com/yami/shop/security/exception/UsernameNotFoundException.java deleted file mode 100644 index 5eb6afa..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/exception/UsernameNotFoundException.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.exception; - -public class UsernameNotFoundException extends BaseYamiAuth2Exception { - - public UsernameNotFoundException(String msg) { - super(msg); - } - - @Override - public String getOAuth2ErrorCode() { - return "username_not_found"; - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/exception/UsernameNotFoundExceptionBase.java b/yami-shop-security/src/main/java/com/yami/shop/security/exception/UsernameNotFoundExceptionBase.java deleted file mode 100644 index 1ebcad7..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/exception/UsernameNotFoundExceptionBase.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.exception; - -public class UsernameNotFoundExceptionBase extends BaseYamiAuth2Exception { - - public UsernameNotFoundExceptionBase(String msg) { - super(msg); - } - - @Override - public String getOAuth2ErrorCode() { - return "username_not_found"; - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/exception/WxErrorException.java b/yami-shop-security/src/main/java/com/yami/shop/security/exception/WxErrorException.java deleted file mode 100644 index 22817f7..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/exception/WxErrorException.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.exception; - -/** - * 密码不正确 - */ -public class WxErrorException extends YamiAuth2Exception{ - public WxErrorException(String msg) { - super(msg); - } - - @Override - public String getOAuth2ErrorCode() { - return "wx_error_exception"; - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/exception/WxErrorExceptionBase.java b/yami-shop-security/src/main/java/com/yami/shop/security/exception/WxErrorExceptionBase.java deleted file mode 100644 index ad2aa76..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/exception/WxErrorExceptionBase.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.exception; - -/** - * 密码不正确 - */ -public class WxErrorExceptionBase extends BaseYamiAuth2Exception { - public WxErrorExceptionBase(String msg) { - super(msg); - } - - @Override - public String getOAuth2ErrorCode() { - return "wx_error_exception"; - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/exception/YamiAuth2Exception.java b/yami-shop-security/src/main/java/com/yami/shop/security/exception/YamiAuth2Exception.java deleted file mode 100644 index a513e93..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/exception/YamiAuth2Exception.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.exception; - -import lombok.Getter; -import org.springframework.http.HttpStatus; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; - -/** - */ -public abstract class YamiAuth2Exception extends AuthenticationException { - - public YamiAuth2Exception(String msg) { - super(msg); - } - - public int getHttpErrorCode() { - // 400 not 401 - return HttpStatus.BAD_REQUEST.value(); - } - - public abstract String getOAuth2ErrorCode(); -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/handler/LoginAuthFailedHandler.java b/yami-shop-security/src/main/java/com/yami/shop/security/handler/LoginAuthFailedHandler.java deleted file mode 100644 index fed60b4..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/handler/LoginAuthFailedHandler.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.handler; - -import cn.hutool.core.util.CharsetUtil; -import com.yami.shop.security.exception.BaseYamiAuth2Exception; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.MediaType; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; -import org.springframework.stereotype.Component; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.PrintWriter; - -/** - * 登陆失败处理 - */ -@Component -@Slf4j -public class LoginAuthFailedHandler implements AuthenticationFailureHandler { - - /** - * {@inheritDoc} - */ - @Override - @SneakyThrows - public void onAuthenticationFailure(HttpServletRequest request, - HttpServletResponse response, AuthenticationException exception) { - - if (!(exception instanceof BaseYamiAuth2Exception)) { - return; - } - - BaseYamiAuth2Exception auth2Exception = (BaseYamiAuth2Exception) exception; - - response.setCharacterEncoding(CharsetUtil.UTF_8); - response.setContentType(MediaType.APPLICATION_JSON_VALUE); - response.setStatus(auth2Exception.getHttpErrorCode()); - PrintWriter printWriter = response.getWriter(); - printWriter.append(auth2Exception.getMessage()); - } - -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/handler/LoginAuthSuccessHandler.java b/yami-shop-security/src/main/java/com/yami/shop/security/handler/LoginAuthSuccessHandler.java deleted file mode 100644 index a1993a4..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/handler/LoginAuthSuccessHandler.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.handler; - -import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.CharsetUtil; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.Sets; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Lazy; -import org.springframework.http.MediaType; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.common.OAuth2AccessToken; -import org.springframework.security.oauth2.common.util.OAuth2Utils; -import org.springframework.security.oauth2.provider.*; -import org.springframework.security.oauth2.provider.client.BaseClientDetails; -import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; -import org.springframework.stereotype.Component; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.io.PrintWriter; - - -/** - * 登录成功,返回oauth token - * - */ -@Component -@Slf4j -public class LoginAuthSuccessHandler implements AuthenticationSuccessHandler { - @Autowired - private ObjectMapper objectMapper; - @Autowired - @Lazy - private AuthorizationServerTokenServices yamiTokenServices; - - /** - * Called when a user has been successfully authenticated. - * 调用spring security oauth API 生成 oAuth2AccessToken - * - * @param request the request which caused the successful authentication - * @param response the response - * @param authentication the Authentication object which was created during - */ - @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { - - try { - - TokenRequest tokenRequest = new TokenRequest(null, null, null, null); - - // 简化 - OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(new BaseClientDetails()); - OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication); - - - OAuth2AccessToken oAuth2AccessToken = yamiTokenServices.createAccessToken(oAuth2Authentication); - log.info("获取token 成功:{}", oAuth2AccessToken.getValue()); - - response.setCharacterEncoding(CharsetUtil.UTF_8); - response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); - PrintWriter printWriter = response.getWriter(); - printWriter.append(objectMapper.writeValueAsString(oAuth2AccessToken)); - } catch (IOException e) { - throw new BadCredentialsException( - "Failed to decode basic authentication token"); - } - - } - - -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/model/AppConnect.java b/yami-shop-security/src/main/java/com/yami/shop/security/model/AppConnect.java deleted file mode 100644 index 13d011e..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/model/AppConnect.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.model; - - -import java.util.Date; -import com.baomidou.mybatisplus.annotation.*; -import lombok.Data; - -@Data -@TableName("tz_app_connect") -public class AppConnect { - /** - * id - */ - @TableId - private Long id; - - /** - * 本系统userId - */ - - private String userId; - - /** - * 第三方系统id 1:微信小程序 - */ - - private Integer appId; - - /** - * 第三方系统昵称 - */ - - private String nickName; - - /** - * 第三方系统头像 - */ - - private String imageUrl; - - /** - * 第三方系统userid - */ - - private String bizUserId; - - /** - * 第三方系统unionid - */ - - private String bizUnionid; - -} \ No newline at end of file diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/provider/AbstractUserDetailsAuthenticationProvider.java b/yami-shop-security/src/main/java/com/yami/shop/security/provider/AbstractUserDetailsAuthenticationProvider.java deleted file mode 100644 index f9c284e..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/provider/AbstractUserDetailsAuthenticationProvider.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.provider; - -import com.yami.shop.security.enums.App; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UsernameNotFoundException; - -/** - * 自定义 AuthenticationProvider, 以使用自定义的 MyAuthenticationToken - * @author LGH - */ -@Slf4j -public abstract class AbstractUserDetailsAuthenticationProvider implements AuthenticationProvider, InitializingBean { - - - - @Override - public final void afterPropertiesSet() { - } - - @Override - public Authentication authenticate(Authentication authentication) throws AuthenticationException { - String username = authentication.getPrincipal() == null?"NONE_PROVIDED":authentication.getName(); - UserDetails user; - - try { - user = this.retrieveUser(username, authentication); - } catch (UsernameNotFoundException var6) { - log.debug("User \'" + username + "\' not found"); - - throw var6; - } - - return this.createSuccessAuthentication(authentication, user); - } - - protected abstract Authentication createSuccessAuthentication(Authentication authentication, UserDetails user); - - protected abstract App getAppInfo(); - - protected abstract UserDetails retrieveUser(String username, Authentication authentication) throws AuthenticationException; - - - -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/provider/AuthenticationTokenParser.java b/yami-shop-security/src/main/java/com/yami/shop/security/provider/AuthenticationTokenParser.java deleted file mode 100644 index 94d6add..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/provider/AuthenticationTokenParser.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.yami.shop.security.provider; - -import org.springframework.security.authentication.AbstractAuthenticationToken; - -/** - * AuthenticationTokenParser - * - * @author hanfeng - * @date 2019-08-21 - */ -public interface AuthenticationTokenParser { - AbstractAuthenticationToken parse(String authenticationTokenStr); -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/provider/MpAuthenticationProvider.java b/yami-shop-security/src/main/java/com/yami/shop/security/provider/MpAuthenticationProvider.java deleted file mode 100644 index 0e54efc..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/provider/MpAuthenticationProvider.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.provider; - - - -import cn.hutool.core.util.BooleanUtil; -import cn.hutool.core.util.StrUtil; -import cn.hutool.extra.emoji.EmojiUtil; -import com.yami.shop.security.enums.App; -import com.yami.shop.security.exception.UsernameNotFoundExceptionBase; -import com.yami.shop.security.exception.WxErrorExceptionBase; -import com.yami.shop.security.model.AppConnect; -import com.yami.shop.security.service.YamiUser; -import com.yami.shop.security.service.YamiUserDetailsService; -import com.yami.shop.security.token.MpAuthenticationToken; -import com.yami.shop.security.token.MyAuthenticationToken; -import lombok.AllArgsConstructor; -import me.chanjar.weixin.common.error.WxErrorException; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; -import me.chanjar.weixin.mp.bean.result.WxMpUser; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.userdetails.UserDetails; - -/** - * 微信公众号登陆 - * @author LGH - */ -//@Component -@AllArgsConstructor -public class MpAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider { - - private final YamiUserDetailsService yamiUserDetailsService; - - private final WxMpService wxMpService; - - - - @Override - protected Authentication createSuccessAuthentication(Authentication authentication, UserDetails user) { - MpAuthenticationToken result = new MpAuthenticationToken(user, authentication.getCredentials()); - result.setDetails(authentication.getDetails()); - return result; - } - - @Override - protected UserDetails retrieveUser(String code, Authentication authentication) throws AuthenticationException { - YamiUser loadedUser = null; - // 如果使用debugger 模式,则返回debugger的用户 - if (BooleanUtil.isTrue(((MyAuthenticationToken)authentication).getDebugger())) { - loadedUser = new YamiUser("1" , "debuggerOpenId" , this.getAppInfo().value(), true); - loadedUser.setDebugger(true); - return loadedUser; - } - - WxMpOAuth2AccessToken wxMpOAuth2AccessToken = null; - - AppConnect appConnect = new AppConnect(); - appConnect.setAppId(this.getAppInfo().value()); - - try { - - wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code); - loadedUser = yamiUserDetailsService.loadUserByAppIdAndBizUserId(this.getAppInfo(),wxMpOAuth2AccessToken.getOpenId()); - - } catch (WxErrorException e) { - throw new WxErrorExceptionBase(e.getMessage()); - } catch (UsernameNotFoundExceptionBase var6) { - WxMpUser wxMpUser = null; - try { - wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, null); - } catch (WxErrorException e) { - throw new WxErrorExceptionBase(e.getMessage()); - } - appConnect.setNickName(EmojiUtil.toAlias(StrUtil.isBlank(wxMpUser.getNickname())? "": wxMpUser.getNickname())); - appConnect.setImageUrl(wxMpUser.getHeadImgUrl()); - appConnect.setBizUserId(wxMpUser.getOpenId()); - appConnect.setBizUnionid(wxMpUser.getUnionId()); - yamiUserDetailsService.insertUserIfNecessary(appConnect); - - } - - if (loadedUser == null) { - loadedUser = yamiUserDetailsService.loadUserByAppIdAndBizUserId(this.getAppInfo(), appConnect.getBizUserId()); - } - return loadedUser; - } - - @Override - public boolean supports(Class authentication) { - return MpAuthenticationToken.class.isAssignableFrom(authentication); - } - - - @Override - protected App getAppInfo() { - return App.MP; - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/service/AppConnectService.java b/yami-shop-security/src/main/java/com/yami/shop/security/service/AppConnectService.java deleted file mode 100644 index 6c0e58f..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/service/AppConnectService.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.service; - - -import com.baomidou.mybatisplus.extension.service.IService; -import com.yami.shop.bean.model.User; -import com.yami.shop.security.enums.App; -import com.yami.shop.security.model.AppConnect; - -/** - * - * @author lgh on 2018/09/07. - */ -public interface AppConnectService extends IService { - - AppConnect getByBizUserId(String bizUserId, App app); - - User registerOrBindUser(User user, AppConnect appConnect, Integer appId); - -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiClientDetailsService.java b/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiClientDetailsService.java deleted file mode 100644 index da1402b..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiClientDetailsService.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.service; - -import com.yami.shop.security.constants.SecurityConstants; -import lombok.SneakyThrows; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.security.oauth2.common.exceptions.InvalidClientException; -import org.springframework.security.oauth2.provider.ClientDetails; -import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService; - -import javax.sql.DataSource; - -/** - * @author - * @tate 2019/03/30 - * 获取客户端 - */ -public class YamiClientDetailsService extends JdbcClientDetailsService { - - public YamiClientDetailsService(DataSource dataSource) { - super(dataSource); - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiSysUser.java b/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiSysUser.java deleted file mode 100644 index 62bfe51..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiSysUser.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.service; - -import lombok.Getter; -import lombok.Setter; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.User; - -import java.util.Collection; - -/** - * 用户详细信息 - * - * @author - */ -@Getter -@Setter -public class YamiSysUser extends User { - /** - * 用户ID - */ - @Getter - private Long userId; - - /** - * 租户ID - */ - @Getter - private Long shopId; - - public YamiSysUser(Long userId, Long shopId, String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection authorities) { - super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); - this.userId = userId; - this.shopId = shopId; - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiUser.java b/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiUser.java deleted file mode 100644 index 85f967c..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiUser.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.service; - -import cn.hutool.core.util.StrUtil; -import lombok.Data; -import lombok.Getter; -import lombok.Setter; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; - -import java.util.Collection; -import java.util.Collections; - -/** - * 用户详细信息 - */ -@Data -public class YamiUser implements UserDetails { - - /** - * 用户ID - */ - private String userId; - - private String bizUserId; - - private String pic; - - private String name; - - private boolean debugger; - - private String password; - - private Integer appType; - - private boolean enabled; - - /** - * 自提点Id - */ - private Long stationId; - - /** - * 店铺Id - */ - private Long shopId; - /** - * 小程序session_key - */ - private String sessionKey; - - public YamiUser() { - - } - - public YamiUser(String userId, String bizUserId, Integer appType, boolean enabled) { - this.userId = userId; - this.bizUserId = bizUserId; - this.appType = appType; - this.enabled = enabled; - } - - public YamiUser(String userId, String password, boolean enabled) { - this.userId = userId; - this.password = password; - this.enabled = enabled; - } - - @Override - public Collection getAuthorities() { - return Collections.emptyList(); - } - - @Override - public String getPassword() { - return this.password; - } - - @Override - public String getUsername() { - return StrUtil.isBlank(userId)? bizUserId: userId; - } - - @Override - public boolean isAccountNonExpired() { - return true; - } - - @Override - public boolean isAccountNonLocked() { - return true; - } - - @Override - public boolean isCredentialsNonExpired() { - return true; - } - - @Override - public boolean isEnabled() { - return this.enabled; - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiUserDetailsService.java b/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiUserDetailsService.java deleted file mode 100644 index ff08abf..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiUserDetailsService.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.service; - -import com.yami.shop.bean.model.User; -import com.yami.shop.security.enums.App; -import com.yami.shop.security.exception.UsernameNotFoundExceptionBase; -import com.yami.shop.security.model.AppConnect; -import org.springframework.security.core.userdetails.UserDetailsService; - -/** - * 用户详细信息 - * - * @author - */ -public interface YamiUserDetailsService extends UserDetailsService { - - /** - * 获取前端登陆的用户信息 - * - * @param app 所登陆的应用 - * @param bizUserId openId - * @return UserDetails - * @throws UsernameNotFoundExceptionBase - */ - YamiUser loadUserByAppIdAndBizUserId(App app, String bizUserId); - - /** - * 如果必要的话,插入新增用户 - * @param appConnect - */ - void insertUserIfNecessary(AppConnect appConnect); - - /** - * 账号、密码登录 - * @param userMail - * @param loginPassword - * @return - */ - YamiUser loadUserByUserMail(String userMail, String loginPassword); - - User loadUserByMobileOrUserName(String mobileOrUserName, Integer loginType); - - YamiUser getYamiUser(Integer appId, User user, String bizUserId); -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/service/impl/AppConnectServiceImpl.java b/yami-shop-security/src/main/java/com/yami/shop/security/service/impl/AppConnectServiceImpl.java deleted file mode 100644 index 32e01e4..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/service/impl/AppConnectServiceImpl.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.service.impl; - -import cn.hutool.core.util.IdUtil; -import cn.hutool.core.util.StrUtil; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.yami.shop.bean.model.User; -import com.yami.shop.common.exception.YamiShopBindException; -import com.yami.shop.dao.UserMapper; -import com.yami.shop.security.dao.AppConnectMapper; -import com.yami.shop.security.enums.App; -import com.yami.shop.security.model.AppConnect; -import com.yami.shop.security.service.AppConnectService; -import com.yami.shop.service.UserService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cache.annotation.CacheEvict; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Date; -import java.util.Objects; - - -/** - * - * @author lgh on 2018/09/07. - */ -@Service -public class AppConnectServiceImpl extends ServiceImpl implements AppConnectService { - - @Autowired - private AppConnectMapper appConnectMapper; - - @Autowired - private UserMapper userMapper; - - @Autowired - private UserService userService; - - /** - * YamiUserServiceImpl#insertUserIfNecessary 将会清楚该缓存信息 - * @param bizUserId - * @param app - * @return - */ - @Override - @Cacheable(cacheNames = "AppConnect", key = "#app.value() + ':' + #bizUserId") - public AppConnect getByBizUserId(String bizUserId, App app) { - return appConnectMapper.getByBizUserId(bizUserId, app.value()); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public User registerOrBindUser(User user, AppConnect appConnect, Integer appId) { - if (StrUtil.isBlank(user.getUserId())) { - if (userMapper.selectCount(new LambdaQueryWrapper().eq(User::getUserMobile, user.getUserMobile())) > 0) { - // 该电话号码已存在 - throw new YamiShopBindException("该电话号码已存在"); - } - String userId = IdUtil.simpleUUID(); - user.setUserId(userId); - userMapper.insert(user); - } else { - if (appConnect != null&& StrUtil.isBlank(user.getPic())) { - User userParam = new User(); - userParam.setUserId(user.getUserId()); - userParam.setModifyTime(new Date()); - userParam.setPic(appConnect.getImageUrl()); - userService.updateById(userParam); - } - } - if (appConnect == null) { - // 避免重复插入数据 - if (appConnectMapper.getByBizUserId(user.getUserId(), appId) != null) { - return user; - } - appConnect = new AppConnect(); - appConnect.setUserId(user.getUserId()); - appConnect.setNickName(user.getNickName()); - appConnect.setImageUrl(user.getPic()); - - // 0表示是系统的用户,不是第三方的 - appConnect.setAppId(appId); - appConnectMapper.insert(appConnect); - } else if (StrUtil.isBlank(appConnect.getUserId()) || Objects.isNull(appId)) { - appConnect.setAppId(appId); - appConnect.setUserId(user.getUserId()); - appConnect.setUserId(user.getUserId()); - appConnectMapper.updateById(appConnect); - } - - return user; - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/token/MpAuthenticationToken.java b/yami-shop-security/src/main/java/com/yami/shop/security/token/MpAuthenticationToken.java deleted file mode 100644 index 011e90f..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/token/MpAuthenticationToken.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.token; - -import lombok.NoArgsConstructor; -import org.springframework.security.core.userdetails.UserDetails; - -/** - * 二维码Token - */ -@NoArgsConstructor -public class MpAuthenticationToken extends MyAuthenticationToken { - - - public MpAuthenticationToken(UserDetails principal, Object credentials) { - super(principal, credentials, principal.getAuthorities()); - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/token/MyAuthenticationToken.java b/yami-shop-security/src/main/java/com/yami/shop/security/token/MyAuthenticationToken.java deleted file mode 100644 index e15b676..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/token/MyAuthenticationToken.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.token; - -import lombok.Getter; -import lombok.Setter; -import org.springframework.security.authentication.AbstractAuthenticationToken; -import org.springframework.security.core.GrantedAuthority; - -import java.util.Collection; - -/** - * 自定义AbstractAuthenticationToken, - */ -@Getter -@Setter -public class MyAuthenticationToken extends AbstractAuthenticationToken { - - private static final long serialVersionUID = 110L; - protected Object principal; - protected Object credentials; - protected Boolean debugger; - - public MyAuthenticationToken() { - super(null); - } - /** - * This constructor should only be used by AuthenticationManager or AuthenticationProvider - * implementations that are satisfied with producing a trusted (i.e. {@link #isAuthenticated()} = true) - * token token. - * - * @param principal - * @param credentials - * @param authorities - */ - public MyAuthenticationToken(Object principal, Object credentials, Collection authorities) { - super(authorities); - this.principal = principal; - this.credentials = credentials; - super.setAuthenticated(true); - } - public MyAuthenticationToken(Object principal, Object credentials) { - super(null); - this.principal = principal; - this.credentials = credentials; - this.setAuthenticated(false); - } - - - @Override - public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { - if(isAuthenticated) { - throw new IllegalArgumentException("Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); - } else { - super.setAuthenticated(false); - } - } - - @Override - public void eraseCredentials() { - super.eraseCredentials(); - this.credentials = null; - } - -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/util/SecurityUtils.java b/yami-shop-security/src/main/java/com/yami/shop/security/util/SecurityUtils.java deleted file mode 100644 index b1bbbe5..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/util/SecurityUtils.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.util; - - -import com.yami.shop.security.exception.UnauthorizedExceptionBase; -import com.yami.shop.security.service.YamiSysUser; -import com.yami.shop.security.service.YamiUser; -import lombok.experimental.UtilityClass; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; - -/** - * 安全工具类 - * - * @author L.cm - */ -@UtilityClass -public class SecurityUtils { - /** - * 获取Authentication - */ - public Authentication getAuthentication() { - return SecurityContextHolder.getContext().getAuthentication(); - } - - /** - * 获取用户 - */ - public YamiUser getUser() { - Authentication authentication = getAuthentication(); - Object principal = authentication.getPrincipal(); - if (principal instanceof YamiUser) { - return (YamiUser) principal; - } - throw new UnauthorizedExceptionBase("无法获取普通用户信息"); - } - - /** - * 获取系统用户 - */ - public YamiSysUser getSysUser() { - Authentication authentication = getAuthentication(); - Object principal = authentication.getPrincipal(); - if (principal instanceof YamiSysUser) { - return (YamiSysUser) principal; - } - throw new UnauthorizedExceptionBase("无法获取系统用户信息"); - } -} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/util/YamiTokenServices.java b/yami-shop-security/src/main/java/com/yami/shop/security/util/YamiTokenServices.java deleted file mode 100644 index acf6bfa..0000000 --- a/yami-shop-security/src/main/java/com/yami/shop/security/util/YamiTokenServices.java +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. - * - * https://www.mall4j.com/ - * - * 未经允许,不可做商业用途! - * - * 版权所有,侵权必究! - */ - -package com.yami.shop.security.util; - -import java.util.Date; -import java.util.Set; -import java.util.UUID; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken; -import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; -import org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken; -import org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken; -import org.springframework.security.oauth2.common.OAuth2AccessToken; -import org.springframework.security.oauth2.common.OAuth2RefreshToken; -import org.springframework.security.oauth2.common.exceptions.InvalidGrantException; -import org.springframework.security.oauth2.common.exceptions.InvalidScopeException; -import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; -import org.springframework.security.oauth2.provider.ClientDetails; -import org.springframework.security.oauth2.provider.ClientDetailsService; -import org.springframework.security.oauth2.provider.ClientRegistrationException; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; -import org.springframework.security.oauth2.provider.TokenRequest; -import org.springframework.security.oauth2.provider.token.*; -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.Assert; - -/** - * Base implementation for token services using random UUID values for the access token and refresh token values. The - * main extension point for customizations is the {@link TokenEnhancer} which will be called after the access and - * refresh tokens have been generated but before they are stored. - *

- * Persistence is delegated to a {@code TokenStore} implementation and customization of the access token to a - * {@link TokenEnhancer}. - * - * @author Ryan Heaton - * @author Luke Taylor - * @author Dave Syer - * @author LGH - */ -public class YamiTokenServices implements AuthorizationServerTokenServices, ResourceServerTokenServices, - ConsumerTokenServices, InitializingBean { - - // default 30 days. - private int refreshTokenValiditySeconds = 60 * 60 * 24 * 30; - - // default 12 hours. - private int accessTokenValiditySeconds = 60 * 60 * 12; - - private boolean supportRefreshToken = false; - - private boolean reuseRefreshToken = true; - - private TokenStore tokenStore; - - private ClientDetailsService clientDetailsService; - - private TokenEnhancer accessTokenEnhancer; - - private AuthenticationManager authenticationManager; - - /** - * Initialize these token services. If no random generator is set, one will be created. - */ - @Override - public void afterPropertiesSet() throws Exception { - Assert.notNull(tokenStore, "tokenStore must be set"); - } - - @Transactional(rollbackFor = Exception.class) - @Override - public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) { - -// OAuth2AccessToken existingAccessToken = tokenStore.getAccessToken(authentication); - OAuth2RefreshToken refreshToken = null; - // 如果有token,直接删除,更新token,避免出现缓存问题 -// if (existingAccessToken != null) { -// if (existingAccessToken.getRefreshToken() != null) { -// refreshToken = existingAccessToken.getRefreshToken(); -// // The token store could remove the refresh token when the -// // access token is removed, but we want to -// // be sure... -// tokenStore.removeRefreshToken(refreshToken); -// } -// tokenStore.removeAccessToken(existingAccessToken); -// -// } - - // Only create a new refresh token if there wasn't an existing one - // associated with an expired access token. - // Clients might be holding existing refresh tokens, so we re-use it in - // the case that the old access token - // expired. - if (refreshToken == null) { - refreshToken = createRefreshToken(authentication); - } - // But the refresh token itself might need to be re-issued if it has - // expired. - else if (refreshToken instanceof ExpiringOAuth2RefreshToken) { - ExpiringOAuth2RefreshToken expiring = (ExpiringOAuth2RefreshToken) refreshToken; - if (System.currentTimeMillis() > expiring.getExpiration().getTime()) { - refreshToken = createRefreshToken(authentication); - } - } - - OAuth2AccessToken accessToken = createAccessToken(authentication, refreshToken); - tokenStore.storeAccessToken(accessToken, authentication); - // In case it was modified - refreshToken = accessToken.getRefreshToken(); - if (refreshToken != null) { - tokenStore.storeRefreshToken(refreshToken, authentication); - } - return accessToken; - - } - - @Override - @Transactional(noRollbackFor={InvalidTokenException.class, InvalidGrantException.class}, rollbackFor = Exception.class) - public OAuth2AccessToken refreshAccessToken(String refreshTokenValue, TokenRequest tokenRequest) - throws AuthenticationException { - - if (!supportRefreshToken) { - throw new InvalidGrantException("Invalid refresh token: " + refreshTokenValue); - } - - OAuth2RefreshToken refreshToken = tokenStore.readRefreshToken(refreshTokenValue); - if (refreshToken == null) { - throw new InvalidGrantException("Invalid refresh token: " + refreshTokenValue); - } - - OAuth2Authentication authentication = tokenStore.readAuthenticationForRefreshToken(refreshToken); - if (this.authenticationManager != null && !authentication.isClientOnly()) { - // The client has already been authenticated, but the user authentication might be old now, so give it a - // chance to re-authenticate. - Authentication user = new PreAuthenticatedAuthenticationToken(authentication.getUserAuthentication(), "", authentication.getAuthorities()); - user = authenticationManager.authenticate(user); - Object details = authentication.getDetails(); - authentication = new OAuth2Authentication(authentication.getOAuth2Request(), user); - authentication.setDetails(details); - } - String clientId = authentication.getOAuth2Request().getClientId(); - if (clientId == null || !clientId.equals(tokenRequest.getClientId())) { - throw new InvalidGrantException("Wrong client for this refresh token: " + refreshTokenValue); - } - - // clear out any access tokens already associated with the refresh - // token. - tokenStore.removeAccessTokenUsingRefreshToken(refreshToken); - - if (isExpired(refreshToken)) { - tokenStore.removeRefreshToken(refreshToken); - throw new InvalidTokenException("Invalid refresh token (expired): " + refreshToken); - } - - authentication = createRefreshedAuthentication(authentication, tokenRequest); - - if (!reuseRefreshToken) { - tokenStore.removeRefreshToken(refreshToken); - refreshToken = createRefreshToken(authentication); - } - - OAuth2AccessToken accessToken = createAccessToken(authentication, refreshToken); - tokenStore.storeAccessToken(accessToken, authentication); - if (!reuseRefreshToken) { - tokenStore.storeRefreshToken(accessToken.getRefreshToken(), authentication); - } - return accessToken; - } - - @Override - public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) { - return tokenStore.getAccessToken(authentication); - } - - /** - * Create a refreshed authentication. - * - * @param authentication The authentication. - * @param request The scope for the refreshed token. - * @return The refreshed authentication. - * @throws InvalidScopeException If the scope requested is invalid or wider than the original scope. - */ - private OAuth2Authentication createRefreshedAuthentication(OAuth2Authentication authentication, TokenRequest request) { - OAuth2Authentication narrowed = authentication; - Set scope = request.getScope(); - OAuth2Request clientAuth = authentication.getOAuth2Request().refresh(request); - if (scope != null && !scope.isEmpty()) { - Set originalScope = clientAuth.getScope(); - if (originalScope == null || !originalScope.containsAll(scope)) { - throw new InvalidScopeException("Unable to narrow the scope of the client authentication to " + scope - + ".", originalScope); - } - else { - clientAuth = clientAuth.narrowScope(scope); - } - } - narrowed = new OAuth2Authentication(clientAuth, authentication.getUserAuthentication()); - return narrowed; - } - - protected boolean isExpired(OAuth2RefreshToken refreshToken) { - if (refreshToken instanceof ExpiringOAuth2RefreshToken) { - ExpiringOAuth2RefreshToken expiringToken = (ExpiringOAuth2RefreshToken) refreshToken; - return expiringToken.getExpiration() == null - || System.currentTimeMillis() > expiringToken.getExpiration().getTime(); - } - return false; - } - - @Override - public OAuth2AccessToken readAccessToken(String accessToken) { - return tokenStore.readAccessToken(accessToken); - } - - @Override - public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException, - InvalidTokenException { - OAuth2AccessToken accessToken = tokenStore.readAccessToken(accessTokenValue); - if (accessToken == null) { - throw new InvalidTokenException("Invalid access token: " + accessTokenValue); - } - else if (accessToken.isExpired()) { - tokenStore.removeAccessToken(accessToken); - throw new InvalidTokenException("Access token expired: " + accessTokenValue); - } - - OAuth2Authentication result = tokenStore.readAuthentication(accessToken); - if (result == null) { - // in case of race condition - throw new InvalidTokenException("Invalid access token: " + accessTokenValue); - } - if (clientDetailsService != null) { - String clientId = result.getOAuth2Request().getClientId(); - try { - clientDetailsService.loadClientByClientId(clientId); - } - catch (ClientRegistrationException e) { - throw new InvalidTokenException("Client not valid: " + clientId, e); - } - } - return result; - } - - public String getClientId(String tokenValue) { - OAuth2Authentication authentication = tokenStore.readAuthentication(tokenValue); - if (authentication == null) { - throw new InvalidTokenException("Invalid access token: " + tokenValue); - } - OAuth2Request clientAuth = authentication.getOAuth2Request(); - if (clientAuth == null) { - throw new InvalidTokenException("Invalid access token (no client id): " + tokenValue); - } - return clientAuth.getClientId(); - } - - @Override - public boolean revokeToken(String tokenValue) { - OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue); - if (accessToken == null) { - return false; - } - if (accessToken.getRefreshToken() != null) { - tokenStore.removeRefreshToken(accessToken.getRefreshToken()); - } - tokenStore.removeAccessToken(accessToken); - return true; - } - - private OAuth2RefreshToken createRefreshToken(OAuth2Authentication authentication) { - if (!isSupportRefreshToken(authentication.getOAuth2Request())) { - return null; - } - int validitySeconds = getRefreshTokenValiditySeconds(authentication.getOAuth2Request()); - String value = UUID.randomUUID().toString(); - if (validitySeconds > 0) { - return new DefaultExpiringOAuth2RefreshToken(value, new Date(System.currentTimeMillis() - + (validitySeconds * 1000L))); - } - return new DefaultOAuth2RefreshToken(value); - } - - private OAuth2AccessToken createAccessToken(OAuth2Authentication authentication, OAuth2RefreshToken refreshToken) { - DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(UUID.randomUUID().toString()); - int validitySeconds = getAccessTokenValiditySeconds(authentication.getOAuth2Request()); - if (validitySeconds > 0) { - token.setExpiration(new Date(System.currentTimeMillis() + (validitySeconds * 1000L))); - } - token.setRefreshToken(refreshToken); - token.setScope(authentication.getOAuth2Request().getScope()); - - return accessTokenEnhancer != null ? accessTokenEnhancer.enhance(token, authentication) : token; - } - - /** - * The access token validity period in seconds - * - * @param clientAuth the current authorization request - * @return the access token validity period in seconds - */ - protected int getAccessTokenValiditySeconds(OAuth2Request clientAuth) { - if (clientDetailsService != null) { - ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId()); - Integer validity = client.getAccessTokenValiditySeconds(); - if (validity != null) { - return validity; - } - } - return accessTokenValiditySeconds; - } - - /** - * The refresh token validity period in seconds - * - * @param clientAuth the current authorization request - * @return the refresh token validity period in seconds - */ - protected int getRefreshTokenValiditySeconds(OAuth2Request clientAuth) { - if (clientDetailsService != null) { - ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId()); - Integer validity = client.getRefreshTokenValiditySeconds(); - if (validity != null) { - return validity; - } - } - return refreshTokenValiditySeconds; - } - - /** - * Is a refresh token supported for this client (or the global setting if - * {@link #setClientDetailsService(ClientDetailsService) clientDetailsService} is not set. - * - * @param clientAuth the current authorization request - * @return boolean to indicate if refresh token is supported - */ - protected boolean isSupportRefreshToken(OAuth2Request clientAuth) { - if (clientDetailsService != null) { - ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId()); - return client.getAuthorizedGrantTypes().contains("refresh_token"); - } - return this.supportRefreshToken; - } - - /** - * An access token enhancer that will be applied to a new token before it is saved in the token store. - * - * @param accessTokenEnhancer the access token enhancer to set - */ - public void setTokenEnhancer(TokenEnhancer accessTokenEnhancer) { - this.accessTokenEnhancer = accessTokenEnhancer; - } - - /** - * The validity (in seconds) of the refresh token. If less than or equal to zero then the tokens will be - * non-expiring. - * - * @param refreshTokenValiditySeconds The validity (in seconds) of the refresh token. - */ - public void setRefreshTokenValiditySeconds(int refreshTokenValiditySeconds) { - this.refreshTokenValiditySeconds = refreshTokenValiditySeconds; - } - - /** - * The default validity (in seconds) of the access token. Zero or negative for non-expiring tokens. If a client - * details service is set the validity period will be read from the client, defaulting to this value if not defined - * by the client. - * - * @param accessTokenValiditySeconds The validity (in seconds) of the access token. - */ - public void setAccessTokenValiditySeconds(int accessTokenValiditySeconds) { - this.accessTokenValiditySeconds = accessTokenValiditySeconds; - } - - /** - * Whether to support the refresh token. - * - * @param supportRefreshToken Whether to support the refresh token. - */ - public void setSupportRefreshToken(boolean supportRefreshToken) { - this.supportRefreshToken = supportRefreshToken; - } - - /** - * Whether to reuse refresh tokens (until expired). - * - * @param reuseRefreshToken Whether to reuse refresh tokens (until expired). - */ - public void setReuseRefreshToken(boolean reuseRefreshToken) { - this.reuseRefreshToken = reuseRefreshToken; - } - - /** - * The persistence strategy for token storage. - * - * @param tokenStore the store for access and refresh tokens. - */ - public void setTokenStore(TokenStore tokenStore) { - this.tokenStore = tokenStore; - } - - /** - * An authentication manager that will be used (if provided) to check the user authentication when a token is - * refreshed. - * - * @param authenticationManager the authenticationManager to set - */ - public void setAuthenticationManager(AuthenticationManager authenticationManager) { - this.authenticationManager = authenticationManager; - } - - /** - * The client details service to use for looking up clients (if necessary). Optional if the access token expiry is - * set globally via {@link #setAccessTokenValiditySeconds(int)}. - * - * @param clientDetailsService the client details service - */ - public void setClientDetailsService(ClientDetailsService clientDetailsService) { - this.clientDetailsService = clientDetailsService; - } - -} diff --git a/yami-shop-security/src/main/resources/mapper/AppConnectMapper.xml b/yami-shop-security/src/main/resources/mapper/AppConnectMapper.xml deleted file mode 100644 index c650a8b..0000000 --- a/yami-shop-security/src/main/resources/mapper/AppConnectMapper.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/yami-shop-security/yami-shop-security-admin/pom.xml b/yami-shop-security/yami-shop-security-admin/pom.xml new file mode 100644 index 0000000..2efe489 --- /dev/null +++ b/yami-shop-security/yami-shop-security-admin/pom.xml @@ -0,0 +1,24 @@ + + + + com.yami.shop + yami-shop-security + 0.0.1-SNAPSHOT + + + yami-shop-security-admin + 4.0.0 + + 商城安全模块后台管理部分 + + + + com.yami.shop + yami-shop-security-common + ${yami.shop.version} + + + + \ No newline at end of file diff --git a/yami-shop-security/yami-shop-security-admin/src/main/java/com/yami/shop/security/admin/adapter/ResourceServerAdapter.java b/yami-shop-security/yami-shop-security-admin/src/main/java/com/yami/shop/security/admin/adapter/ResourceServerAdapter.java new file mode 100644 index 0000000..ad8f519 --- /dev/null +++ b/yami-shop-security/yami-shop-security-admin/src/main/java/com/yami/shop/security/admin/adapter/ResourceServerAdapter.java @@ -0,0 +1,29 @@ +package com.yami.shop.security.admin.adapter; + +import com.yami.shop.security.common.adapter.DefaultAuthConfigAdapter; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; + +/** + * @author 菠萝凤梨 + * @date 2022/3/28 14:57 + */ +@Component +public class ResourceServerAdapter extends DefaultAuthConfigAdapter { + public static final List EXCLUDE_PATH = Arrays.asList( + "/webjars/**", + "/swagger/**", + "/v2/api-docs", + "/doc.html", + "/swagger-ui.html", + "/swagger-resources/**", + "/captcha/**", + "/adminLogin"); + + @Override + public List excludePathPatterns() { + return EXCLUDE_PATH; + } +} diff --git a/yami-shop-security/yami-shop-security-admin/src/main/java/com/yami/shop/security/admin/dto/CaptchaAuthenticationDTO.java b/yami-shop-security/yami-shop-security-admin/src/main/java/com/yami/shop/security/admin/dto/CaptchaAuthenticationDTO.java new file mode 100644 index 0000000..82d41a0 --- /dev/null +++ b/yami-shop-security/yami-shop-security-admin/src/main/java/com/yami/shop/security/admin/dto/CaptchaAuthenticationDTO.java @@ -0,0 +1,17 @@ +package com.yami.shop.security.admin.dto; + +import com.yami.shop.security.common.dto.AuthenticationDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 验证码登录 + * @author 菠萝凤梨 + * @date 2022/3/28 14:57 + */ +@Data +public class CaptchaAuthenticationDTO extends AuthenticationDTO { + + @ApiModelProperty(value = "验证码", required = true) + private String captchaVerification; +} diff --git a/yami-shop-security/yami-shop-security-admin/src/main/java/com/yami/shop/security/admin/model/YamiSysUser.java b/yami-shop-security/yami-shop-security-admin/src/main/java/com/yami/shop/security/admin/model/YamiSysUser.java new file mode 100644 index 0000000..24c1821 --- /dev/null +++ b/yami-shop-security/yami-shop-security-admin/src/main/java/com/yami/shop/security/admin/model/YamiSysUser.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.admin.model; + +import lombok.Data; + +import java.util.Set; + +/** + * 用户详细信息 + * + * @author + */ +@Data +public class YamiSysUser { + + /** + * 用户ID + */ + private Long userId; + + private boolean enabled; + + private Set authorities; + + private String username; + + private Long shopId; +} diff --git a/yami-shop-security/yami-shop-security-admin/src/main/java/com/yami/shop/security/admin/util/SecurityUtils.java b/yami-shop-security/yami-shop-security-admin/src/main/java/com/yami/shop/security/admin/util/SecurityUtils.java new file mode 100644 index 0000000..76916d7 --- /dev/null +++ b/yami-shop-security/yami-shop-security-admin/src/main/java/com/yami/shop/security/admin/util/SecurityUtils.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.admin.util; + +import com.yami.shop.security.admin.model.YamiSysUser; +import com.yami.shop.security.common.bo.UserInfoInTokenBO; +import com.yami.shop.security.common.util.AuthUserContext; +import lombok.experimental.UtilityClass; + +/** + * + * @author LGH + */ +@UtilityClass +public class SecurityUtils { + /** + * 获取用户 + */ + public YamiSysUser getSysUser() { + UserInfoInTokenBO userInfoInTokenBO = AuthUserContext.get(); + + YamiSysUser details = new YamiSysUser(); + details.setUserId(Long.valueOf(userInfoInTokenBO.getUserId())); + details.setEnabled(userInfoInTokenBO.getEnabled()); + details.setUsername(userInfoInTokenBO.getNickName()); + details.setAuthorities(userInfoInTokenBO.getPerms()); + details.setShopId(userInfoInTokenBO.getShopId()); + return details; + } +} + diff --git a/yami-shop-security/yami-shop-security-api/pom.xml b/yami-shop-security/yami-shop-security-api/pom.xml new file mode 100644 index 0000000..081f370 --- /dev/null +++ b/yami-shop-security/yami-shop-security-api/pom.xml @@ -0,0 +1,23 @@ + + + + yami-shop-security + com.yami.shop + 0.0.1-SNAPSHOT + + 4.0.0 + + yami-shop-security-api + 商城安全模块接口部分 + + + + com.yami.shop + yami-shop-security-common + ${yami.shop.version} + + + + \ No newline at end of file diff --git a/yami-shop-security/yami-shop-security-api/src/main/java/com/yami/shop/security/api/adapter/ResourceServerAdapter.java b/yami-shop-security/yami-shop-security-api/src/main/java/com/yami/shop/security/api/adapter/ResourceServerAdapter.java new file mode 100644 index 0000000..5d5bb51 --- /dev/null +++ b/yami-shop-security/yami-shop-security-api/src/main/java/com/yami/shop/security/api/adapter/ResourceServerAdapter.java @@ -0,0 +1,20 @@ +package com.yami.shop.security.api.adapter; + +import com.yami.shop.security.common.adapter.DefaultAuthConfigAdapter; +import org.springframework.stereotype.Component; + +import java.util.Collections; +import java.util.List; + +/** + * @author 菠萝凤梨 + * @date 2022/3/28 15:17 + */ +@Component +public class ResourceServerAdapter extends DefaultAuthConfigAdapter { + + @Override + public List pathPatterns() { + return Collections.singletonList("/p/*"); + } +} diff --git a/yami-shop-security/yami-shop-security-api/src/main/java/com/yami/shop/security/api/controller/LoginController.java b/yami-shop-security/yami-shop-security-api/src/main/java/com/yami/shop/security/api/controller/LoginController.java new file mode 100644 index 0000000..d2b49a7 --- /dev/null +++ b/yami-shop-security/yami-shop-security-api/src/main/java/com/yami/shop/security/api/controller/LoginController.java @@ -0,0 +1,80 @@ +package com.yami.shop.security.api.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.yami.shop.bean.model.User; +import com.yami.shop.common.exception.YamiShopBindException; +import com.yami.shop.common.util.PrincipalUtil; +import com.yami.shop.dao.UserMapper; +import com.yami.shop.security.common.bo.UserInfoInTokenBO; +import com.yami.shop.security.common.dto.AuthenticationDTO; +import com.yami.shop.security.common.enums.SysTypeEnum; +import com.yami.shop.security.common.manager.PasswordCheckManager; +import com.yami.shop.security.common.manager.PasswordManager; +import com.yami.shop.security.common.manager.TokenStore; +import com.yami.shop.security.common.vo.TokenInfoVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +/** + * @author 菠萝凤梨 + * @date 2022/3/28 15:20 + */ +@RestController +@Api(tags = "登录") +public class LoginController { + @Autowired + private TokenStore tokenStore; + + @Autowired + private UserMapper userMapper; + + @Autowired + private PasswordCheckManager passwordCheckManager; + + @Autowired + private PasswordManager passwordManager; + + @PostMapping("/login") + @ApiOperation(value = "账号密码(用于前端登录)", notes = "通过账号/手机号/用户名密码登录,还要携带用户的类型,也就是用户所在的系统") + public ResponseEntity login( + @Valid @RequestBody AuthenticationDTO authenticationDTO) { + String mobileOrUserName = authenticationDTO.getUserName(); + User user = getUser(mobileOrUserName); + + String decryptPassword = passwordManager.decryptPassword(authenticationDTO.getPassWord()); + + // 半小时内密码输入错误十次,已限制登录30分钟 + passwordCheckManager.checkPassword(SysTypeEnum.ORDINARY,authenticationDTO.getUserName(), decryptPassword, user.getLoginPassword()); + + UserInfoInTokenBO userInfoInToken = new UserInfoInTokenBO(); + userInfoInToken.setUserId(user.getUserId()); + userInfoInToken.setSysType(SysTypeEnum.ORDINARY.value()); + userInfoInToken.setEnabled(user.getStatus() == 1); + // 存储token返回vo + TokenInfoVO tokenInfoVO = tokenStore.storeAndGetVo(userInfoInToken); + return ResponseEntity.ok(tokenInfoVO); + } + + private User getUser(String mobileOrUserName) { + User user = null; + // 手机验证码登陆,或传过来的账号很像手机号 + if (PrincipalUtil.isMobile(mobileOrUserName)) { + user = userMapper.selectOne(new LambdaQueryWrapper().eq(User::getUserMobile, mobileOrUserName)); + } + // 如果不是手机验证码登陆, 找不到手机号就找用户名 + if (user == null) { + user = userMapper.selectOneByUserName(mobileOrUserName); + } + if (user == null) { + throw new YamiShopBindException("账号或密码不正确"); + } + return user; + } +} diff --git a/yami-shop-security/yami-shop-security-api/src/main/java/com/yami/shop/security/api/model/YamiUser.java b/yami-shop-security/yami-shop-security-api/src/main/java/com/yami/shop/security/api/model/YamiUser.java new file mode 100644 index 0000000..ac39c8b --- /dev/null +++ b/yami-shop-security/yami-shop-security-api/src/main/java/com/yami/shop/security/api/model/YamiUser.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.api.model; + +import lombok.Data; + +/** + * 用户详细信息 + * @author LGH + */ +@Data +public class YamiUser { + + /** + * 用户ID + */ + private String userId; + + private String bizUserId; + + private Boolean enabled; + + /** + * 自提点Id + */ + private Long stationId; + + /** + * 店铺Id + */ + private Long shopId; +} diff --git a/yami-shop-security/yami-shop-security-api/src/main/java/com/yami/shop/security/api/util/SecurityUtils.java b/yami-shop-security/yami-shop-security-api/src/main/java/com/yami/shop/security/api/util/SecurityUtils.java new file mode 100644 index 0000000..d015960 --- /dev/null +++ b/yami-shop-security/yami-shop-security-api/src/main/java/com/yami/shop/security/api/util/SecurityUtils.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.api.util; + +import com.yami.shop.common.util.HttpContextUtils; +import com.yami.shop.security.api.model.YamiUser; +import com.yami.shop.security.common.bo.UserInfoInTokenBO; +import com.yami.shop.security.common.util.AuthUserContext; +import lombok.experimental.UtilityClass; + +/** + * @author LGH + */ +@UtilityClass +public class SecurityUtils { + + private static final String USER_REQUEST = "/p/"; + + /** + * 获取用户 + */ + public YamiUser getUser() { + if (!HttpContextUtils.getHttpServletRequest().getRequestURI().startsWith(USER_REQUEST)) { + // 用户相关的请求,应该以/p开头!!! + throw new RuntimeException("yami.user.request.error"); + } + UserInfoInTokenBO userInfoInTokenBO = AuthUserContext.get(); + + YamiUser yamiUser = new YamiUser(); + yamiUser.setUserId(userInfoInTokenBO.getUserId()); + yamiUser.setBizUserId(userInfoInTokenBO.getBizUserId()); + yamiUser.setEnabled(userInfoInTokenBO.getEnabled()); + yamiUser.setShopId(userInfoInTokenBO.getShopId()); + yamiUser.setStationId(userInfoInTokenBO.getOtherId()); + return yamiUser; + } +} diff --git a/yami-shop-security/yami-shop-security-common/pom.xml b/yami-shop-security/yami-shop-security-common/pom.xml new file mode 100644 index 0000000..ebbe526 --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/pom.xml @@ -0,0 +1,33 @@ + + + + com.yami.shop + yami-shop-security + 0.0.1-SNAPSHOT + + + 4.0.0 + + yami-shop-security-common + + + + com.yami.shop + yami-shop-service + ${yami.shop.version} + + + + org.springframework.boot + spring-boot-starter-security + + + com.anji-plus + captcha + 1.3.0 + + + + \ No newline at end of file diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/adapter/AuthConfigAdapter.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/adapter/AuthConfigAdapter.java new file mode 100644 index 0000000..3ee2153 --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/adapter/AuthConfigAdapter.java @@ -0,0 +1,27 @@ +package com.yami.shop.security.common.adapter; + +import java.util.List; + +/** + * 实现该接口之后,修改需要授权登陆的路径,不需要授权登陆的路径 + * @author 菠萝凤梨 + * @date 2022/3/25 17:31 + */ +public interface AuthConfigAdapter { + /** + * 也许需要登录才可用的url + */ + String MAYBE_AUTH_URI = "/**/ma/**"; + + /** + * 需要授权登陆的路径 + * @return 需要授权登陆的路径列表 + */ + List pathPatterns(); + + /** + * 不需要授权登陆的路径 + * @return 不需要授权登陆的路径列表 + */ + List excludePathPatterns(); +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/adapter/CaptchaCacheServiceRedisImpl.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/adapter/CaptchaCacheServiceRedisImpl.java new file mode 100644 index 0000000..748ec0d --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/adapter/CaptchaCacheServiceRedisImpl.java @@ -0,0 +1,36 @@ +package com.yami.shop.security.common.adapter; + +import com.anji.captcha.service.CaptchaCacheService; +import com.yami.shop.common.util.RedisUtil; + +/** + * 适配验证码在redis的存储 + * @author 菠萝凤梨 + * @date 2022/3/25 17:33 + */ +public class CaptchaCacheServiceRedisImpl implements CaptchaCacheService { + @Override + public void set(String key, String value, long expiresInSeconds) { + RedisUtil.set(key, value, expiresInSeconds); + } + + @Override + public boolean exists(String key) { + return RedisUtil.hasKey(key); + } + + @Override + public void delete(String key) { + RedisUtil.del(key); + } + + @Override + public String get(String key) { + return RedisUtil.get(key); + } + + @Override + public String type() { + return "redis"; + } +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/adapter/DefaultAuthConfigAdapter.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/adapter/DefaultAuthConfigAdapter.java new file mode 100644 index 0000000..e5c35f5 --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/adapter/DefaultAuthConfigAdapter.java @@ -0,0 +1,29 @@ +package com.yami.shop.security.common.adapter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collections; +import java.util.List; + +/** + * @author 菠萝凤梨 + * @date 2022/3/25 17:33 + */ +public class DefaultAuthConfigAdapter implements AuthConfigAdapter { + private static final Logger logger = LoggerFactory.getLogger(DefaultAuthConfigAdapter.class); + + public DefaultAuthConfigAdapter() { + logger.info("not implement other AuthConfigAdapter, use DefaultAuthConfigAdapter... all url need auth..."); + } + + @Override + public List pathPatterns() { + return Collections.singletonList("/*"); + } + + @Override + public List excludePathPatterns() { + return Collections.emptyList(); + } +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/adapter/MallWebSecurityConfigurerAdapter.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/adapter/MallWebSecurityConfigurerAdapter.java new file mode 100644 index 0000000..ed289d4 --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/adapter/MallWebSecurityConfigurerAdapter.java @@ -0,0 +1,25 @@ +package com.yami.shop.security.common.adapter; + +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.stereotype.Component; +import org.springframework.web.cors.CorsUtils; + +/** + * 使用security的防火墙功能,但不使用security的认证授权登录 + * @author 菠萝凤梨 + * @date 2022/3/25 17:33 + */ +@Component +public class MallWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { + @Override + public void configure(HttpSecurity http) throws Exception { + http.csrf().disable().cors() // We don't need CSRF for token based authentication + .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and().authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll() + .and() + .authorizeRequests().antMatchers( + "/**").permitAll(); + } +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/bo/TokenInfoBO.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/bo/TokenInfoBO.java new file mode 100644 index 0000000..0219166 --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/bo/TokenInfoBO.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.bo; + + +import lombok.Data; + +/** + * token信息,该信息存在redis中 + * + * @author 菠萝凤梨 + * @date 2022/3/25 17:33 + */ +@Data +public class TokenInfoBO { + + /** + * 保存在token信息里面的用户信息 + */ + private UserInfoInTokenBO userInfoInToken; + + private String accessToken; + + private String refreshToken; + + /** + * 在多少秒后过期 + */ + private Integer expiresIn; + +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/bo/UserInfoInTokenBO.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/bo/UserInfoInTokenBO.java new file mode 100644 index 0000000..8b74ed5 --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/bo/UserInfoInTokenBO.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.bo; + +import lombok.Data; + +import java.util.Set; + +/** + * 保存在token信息里面的用户信息 + * + * @author 菠萝凤梨 + * @date 2022/3/25 17:33 + */ +@Data +public class UserInfoInTokenBO { + + /** + * 用户在自己系统的用户id + */ + private String userId; + + /** + * 租户id (商家id) + */ + private Long shopId; + + /** + * 昵称 + */ + private String nickName; + + /** + * 系统类型 + * @see com.yami.shop.security.common.enums.SysTypeEnum + */ + private Integer sysType; + + /** + * 是否是管理员 + */ + private Integer isAdmin; + + private String bizUserId; + + /** + * 权限列表 + */ + private Set perms; + + /** + * 状态 1 正常 0 无效 + */ + private Boolean enabled; + + /** + * 其他Id + */ + private Long otherId; + +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/config/AuthConfig.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/config/AuthConfig.java new file mode 100644 index 0000000..e841b12 --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/config/AuthConfig.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.config; + +import cn.hutool.core.util.ArrayUtil; +import com.yami.shop.security.common.adapter.AuthConfigAdapter; +import com.yami.shop.security.common.adapter.DefaultAuthConfigAdapter; +import com.yami.shop.security.common.filter.AuthFilter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; + +import javax.servlet.DispatcherType; + +/** + * 授权配置 + * + * @author 菠萝凤梨 + * @date 2022/3/25 17:33 + */ +@Configuration +@EnableGlobalMethodSecurity(prePostEnabled=true) +public class AuthConfig { + + @Autowired + private AuthFilter authFilter; + + @Bean + @ConditionalOnMissingBean + public AuthConfigAdapter authConfigAdapter() { + return new DefaultAuthConfigAdapter(); + } + + + @Bean + @Lazy + public FilterRegistrationBean filterRegistration(AuthConfigAdapter authConfigAdapter) { + FilterRegistrationBean registration = new FilterRegistrationBean<>(); + // 添加过滤器 + registration.setFilter(authFilter); + // 设置过滤路径,/*所有路径 + registration.addUrlPatterns(ArrayUtil.toArray(authConfigAdapter.pathPatterns(), String.class)); + registration.setName("authFilter"); + // 设置优先级 + registration.setOrder(0); + registration.setDispatcherTypes(DispatcherType.REQUEST); + return registration; + } + +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/config/CaptchaConfig.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/config/CaptchaConfig.java new file mode 100644 index 0000000..a9aa3df --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/config/CaptchaConfig.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.config; + +import com.anji.captcha.model.common.CaptchaTypeEnum; +import com.anji.captcha.model.common.Const; +import com.anji.captcha.service.CaptchaService; +import com.anji.captcha.service.impl.CaptchaServiceFactory; +import com.anji.captcha.util.ImageUtils; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.util.Base64Utils; +import org.springframework.util.FileCopyUtils; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * 这里把验证码的底图存入redis中,如果报获取验证码失败找管理员什么的可以看下redis的情况 + * @author 菠萝凤梨 + * @date 2022/3/25 17:33 + */ +@Configuration +public class CaptchaConfig { + + @Bean + public CaptchaService captchaService() { + Properties config = new Properties(); + config.put(Const.CAPTCHA_CACHETYPE, "redis"); + config.put(Const.CAPTCHA_WATER_MARK, ""); + // 滑动验证 + config.put(Const.CAPTCHA_TYPE, CaptchaTypeEnum.BLOCKPUZZLE.getCodeValue()); + config.put(Const.CAPTCHA_INIT_ORIGINAL, "true"); + initializeBaseMap(); + return CaptchaServiceFactory.getInstance(config); + } + + private static void initializeBaseMap() { + ImageUtils.cacheBootImage(getResourcesImagesFile("classpath:captcha" + "/original/*.png"), getResourcesImagesFile("classpath:captcha" + "/slidingBlock/*.png"), Collections.emptyMap()); + } + + public static Map getResourcesImagesFile(String path) { + Map imgMap = new HashMap<>(16); + PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + + try { + Resource[] resources = resolver.getResources(path); + Resource[] var4 = resources; + int var5 = resources.length; + + for(int var6 = 0; var6 < var5; ++var6) { + Resource resource = var4[var6]; + byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream()); + String string = Base64Utils.encodeToString(bytes); + String filename = resource.getFilename(); + imgMap.put(filename, string); + } + } catch (Exception var11) { + var11.printStackTrace(); + } + + return imgMap; + } + +} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/config/CorsConfig.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/config/CorsConfig.java similarity index 96% rename from yami-shop-security/src/main/java/com/yami/shop/security/config/CorsConfig.java rename to yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/config/CorsConfig.java index 0534790..890272a 100644 --- a/yami-shop-security/src/main/java/com/yami/shop/security/config/CorsConfig.java +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/config/CorsConfig.java @@ -1,4 +1,4 @@ -package com.yami.shop.security.config; +package com.yami.shop.security.common.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/config/WebSecurityConfig.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/config/PasswordConfig.java similarity index 53% rename from yami-shop-security/src/main/java/com/yami/shop/security/config/WebSecurityConfig.java rename to yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/config/PasswordConfig.java index 93f35ec..e09ec7a 100644 --- a/yami-shop-security/src/main/java/com/yami/shop/security/config/WebSecurityConfig.java +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/config/PasswordConfig.java @@ -7,37 +7,22 @@ * * 版权所有,侵权必究! */ +package com.yami.shop.security.common.config; -package com.yami.shop.security.config; - - -import lombok.SneakyThrows; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.password.PasswordEncoder; - /** - * @author LGH + * @author 菠萝凤梨 + * @date 2022/3/25 17:33 */ @Configuration -@Order(90) -public class WebSecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - @Bean - @SneakyThrows - public AuthenticationManager authenticationManagerBean() { - return super.authenticationManagerBean(); - } +public class PasswordConfig { @Bean public PasswordEncoder passwordEncoder(){ return PasswordEncoderFactories.createDelegatingPasswordEncoder(); } - } diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/controller/CaptchaController.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/controller/CaptchaController.java new file mode 100644 index 0000000..eee5070 --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/controller/CaptchaController.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.controller; + +import com.anji.captcha.model.common.RepCodeEnum; +import com.anji.captcha.model.common.ResponseModel; +import com.anji.captcha.model.vo.CaptchaVO; +import com.anji.captcha.service.CaptchaService; +import io.swagger.annotations.Api; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author 菠萝凤梨 + * @date 2022/3/25 17:33 + */ +@RestController +@RequestMapping("/captcha") +@Api(tags = "验证码") +public class CaptchaController { + + private final CaptchaService captchaService; + + public CaptchaController(CaptchaService captchaService) { + this.captchaService = captchaService; + } + + @PostMapping({ "/get" }) + public ResponseEntity get(@RequestBody CaptchaVO captchaVO) { + return ResponseEntity.ok(captchaService.get(captchaVO)); + } + + @PostMapping({ "/check" }) + public ResponseEntity check(@RequestBody CaptchaVO captchaVO) { + ResponseModel responseModel; + try { + responseModel = captchaService.check(captchaVO); + }catch (Exception e) { + return ResponseEntity.ok(ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_COORDINATE_ERROR)); + } + return ResponseEntity.ok(responseModel); + } + +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/controller/LogoutController.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/controller/LogoutController.java new file mode 100644 index 0000000..88510ce --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/controller/LogoutController.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.controller; + +import cn.hutool.core.util.StrUtil; +import com.yami.shop.security.common.manager.TokenStore; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author 菠萝凤梨 + * @date 2022/3/25 17:33 + */ +@RestController +@Api(tags = "注销") +public class LogoutController { + + @Autowired + private TokenStore tokenStore; + + @PostMapping("/logOut") + @ApiOperation(value = "退出登陆", notes = "点击退出登陆,清除token,清除菜单缓存") + public ResponseEntity logOut(HttpServletRequest request) { + String accessToken = request.getHeader("Authorization"); + if (StrUtil.isBlank(accessToken)) { + return ResponseEntity.ok().build(); + } + // 删除该用户在该系统当前的token + tokenStore.deleteCurrentToken(accessToken); + return ResponseEntity.ok().build(); + } +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/controller/TokenController.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/controller/TokenController.java new file mode 100644 index 0000000..acb1528 --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/controller/TokenController.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.controller; + +import com.yami.shop.security.common.bo.TokenInfoBO; +import com.yami.shop.security.common.dto.RefreshTokenDTO; +import com.yami.shop.security.common.manager.TokenStore; +import com.yami.shop.security.common.vo.TokenInfoVO; +import io.swagger.annotations.Api; +import ma.glasnost.orika.MapperFacade; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +/** + * @author 菠萝凤梨 + * @date 2022/3/25 17:33 + */ +@RestController +@Api(tags = "token") +public class TokenController { + + @Autowired + private TokenStore tokenStore; + + @Autowired + private MapperFacade mapperFacade; + + @PostMapping("/token/refresh") + public ResponseEntity refreshToken(@Valid @RequestBody RefreshTokenDTO refreshTokenDTO) { + TokenInfoBO tokenInfoServerResponseEntity = tokenStore + .refreshToken(refreshTokenDTO.getRefreshToken()); + return ResponseEntity + .ok(mapperFacade.map(tokenInfoServerResponseEntity, TokenInfoVO.class)); + } + +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/dto/AuthenticationDTO.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/dto/AuthenticationDTO.java new file mode 100644 index 0000000..d58040c --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/dto/AuthenticationDTO.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 用于登陆传递账号密码 + * + * @author 菠萝凤梨 + * @date 2022/3/25 17:33 + */ +@Data +public class AuthenticationDTO { + + /** + * 用户名 + */ + @NotBlank(message = "userName不能为空") + @ApiModelProperty(value = "用户名/邮箱/手机号", required = true) + protected String userName; + + /** + * 密码 + */ + @NotBlank(message = "passWord不能为空") + @ApiModelProperty(value = "一般用作密码", required = true) + protected String passWord; + +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/dto/RefreshTokenDTO.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/dto/RefreshTokenDTO.java new file mode 100644 index 0000000..57b6b9d --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/dto/RefreshTokenDTO.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.dto; + +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotBlank; + +/** + * 刷新token + * + * @author 菠萝凤梨 + * @date 2022/3/25 17:33 + */ +public class RefreshTokenDTO { + + /** + * refreshToken + */ + @NotBlank(message = "refreshToken不能为空") + @ApiModelProperty(value = "refreshToken", required = true) + private String refreshToken; + + public String getRefreshToken() { + return refreshToken; + } + + public void setRefreshToken(String refreshToken) { + this.refreshToken = refreshToken; + } + + @Override + public String toString() { + return "RefreshTokenDTO{" + "refreshToken='" + refreshToken + '\'' + '}'; + } + +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/enums/SysTypeEnum.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/enums/SysTypeEnum.java new file mode 100644 index 0000000..8622a8d --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/enums/SysTypeEnum.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.enums; + +/** + * 系统类型 + * @author 菠萝凤梨 + * @date 2022/3/25 17:33 + */ +public enum SysTypeEnum { + + /** + * 普通用户系统 + */ + ORDINARY(0), + + /** + * 后台 + */ + ADMIN(1), + ; + + private final Integer value; + + public Integer value() { + return value; + } + + SysTypeEnum(Integer value) { + this.value = value; + } + +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/filter/AuthFilter.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/filter/AuthFilter.java new file mode 100644 index 0000000..6f71748 --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/filter/AuthFilter.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.filter; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.yami.shop.common.exception.YamiShopBindException; +import com.yami.shop.common.handler.HttpHandler; +import com.yami.shop.security.common.adapter.AuthConfigAdapter; +import com.yami.shop.security.common.bo.UserInfoInTokenBO; +import com.yami.shop.security.common.manager.TokenStore; +import com.yami.shop.security.common.util.AuthUserContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.util.AntPathMatcher; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** + * 授权过滤,只要实现AuthConfigAdapter接口,添加对应路径即可: + * + * @author 菠萝凤梨 + * @date 2022/3/25 17:33 + */ +@Component +public class AuthFilter implements Filter { + + private static final Logger logger = LoggerFactory.getLogger(AuthFilter.class); + + @Autowired + private AuthConfigAdapter authConfigAdapter; + + @Autowired + private HttpHandler httpHandler; + + @Autowired + private TokenStore tokenStore; + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse resp = (HttpServletResponse) response; + + String requestUri = req.getRequestURI(); + + List excludePathPatterns = authConfigAdapter.excludePathPatterns(); + + AntPathMatcher pathMatcher = new AntPathMatcher(); + // 如果匹配不需要授权的路径,就不需要校验是否需要授权 + if (CollectionUtil.isNotEmpty(excludePathPatterns)) { + for (String excludePathPattern : excludePathPatterns) { + if (pathMatcher.match(excludePathPattern, requestUri)) { + chain.doFilter(req, resp); + return; + } + } + } + + String accessToken = req.getHeader("Authorization"); + // 也许需要登录,不登陆也能用的uri + boolean mayAuth = pathMatcher.match(AuthConfigAdapter.MAYBE_AUTH_URI, requestUri); + + + UserInfoInTokenBO userInfoInToken = null; + + try { + // 如果有token,就要获取token + if (StrUtil.isNotBlank(accessToken)) { + userInfoInToken = tokenStore.getUserInfoByAccessToken(accessToken, true); + } + else if (!mayAuth) { + // 返回前端401 + httpHandler.printServerResponseToWeb(HttpStatus.UNAUTHORIZED.getReasonPhrase(), HttpStatus.UNAUTHORIZED.value()); + return; + } + // 保存上下文 + AuthUserContext.set(userInfoInToken); + + chain.doFilter(req, resp); + + }catch (Exception e) { + // 手动捕获下非controller异常 + if (e instanceof YamiShopBindException) { + httpHandler.printServerResponseToWeb(e.getMessage(), ((YamiShopBindException) e).getHttpStatusCode()); + } else { + throw e; + } + } finally { + AuthUserContext.clean(); + } + } +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/manager/PasswordCheckManager.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/manager/PasswordCheckManager.java new file mode 100644 index 0000000..ff35036 --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/manager/PasswordCheckManager.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.manager; + +import cn.hutool.core.util.StrUtil; +import com.yami.shop.common.exception.YamiShopBindException; +import com.yami.shop.common.util.IPHelper; +import com.yami.shop.common.util.RedisUtil; +import com.yami.shop.security.common.enums.SysTypeEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; + +/** + * @date 2022/3/25 17:33 + * @author lh + */ +@Component +public class PasswordCheckManager { + + + @Autowired + private PasswordEncoder passwordEncoder; + + /** + * 半小时内最多错误10次 + */ + private static final int TIMES_CHECK_INPUT_PASSWORD_NUM = 10; + + /** + * 检查用户输入错误的验证码次数 + */ + private static final String CHECK_VALID_CODE_NUM_PREFIX = "checkUserInputErrorPassword_"; + public void checkPassword(SysTypeEnum sysTypeEnum,String userNameOrMobile, String rawPassword, String encodedPassword) { + + String checkPrefix = sysTypeEnum.value() + CHECK_VALID_CODE_NUM_PREFIX + IPHelper.getIpAddr(); + + int count = 0; + if(RedisUtil.hasKey(checkPrefix + userNameOrMobile)){ + count = RedisUtil.get(checkPrefix + userNameOrMobile); + } + if(count > TIMES_CHECK_INPUT_PASSWORD_NUM){ + throw new YamiShopBindException("半小时内密码输入错误十次,已限制登录30分钟"); + } + // 半小时后失效 + RedisUtil.set(checkPrefix + userNameOrMobile,count,1800); + // 密码不正确 + if (StrUtil.isBlank(encodedPassword) || !passwordEncoder.matches(rawPassword,encodedPassword)){ + count++; + // 半小时后失效 + RedisUtil.set(checkPrefix + userNameOrMobile,count,1800); + throw new YamiShopBindException("账号或密码不正确"); + } + } +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/manager/PasswordManager.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/manager/PasswordManager.java new file mode 100644 index 0000000..e73f98e --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/manager/PasswordManager.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.manager; + +import cn.hutool.crypto.symmetric.AES; +import com.yami.shop.common.exception.YamiShopBindException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.nio.charset.StandardCharsets; + +/** + * @author 菠萝凤梨 + * @date 2022/1/19 16:02 + */ +@Component +public class PasswordManager { + private static final Logger logger = LoggerFactory.getLogger(PasswordManager.class); + + /** + * 用于aes签名的key,16位 + */ + @Value("${auth.password.signKey:-mall4j-password}") + public String passwordSignKey; + + public String decryptPassword(String data) { + AES aes = new AES(passwordSignKey.getBytes(StandardCharsets.UTF_8)); + String decryptStr; + String decryptPassword; + try { + decryptStr = aes.decryptStr(data); + decryptPassword = decryptStr.substring(13); + } catch (Exception e) { + logger.error("Exception:", e); + throw new YamiShopBindException("AES解密错误", e); + } + return decryptPassword; + } +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/manager/TokenStore.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/manager/TokenStore.java new file mode 100644 index 0000000..1379e58 --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/manager/TokenStore.java @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.manager; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.BooleanUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.symmetric.AES; +import com.yami.shop.common.constants.OauthCacheNames; +import com.yami.shop.common.enums.YamiHttpStatus; +import com.yami.shop.common.exception.YamiShopBindException; +import com.yami.shop.common.serializer.redis.KryoRedisSerializer; +import com.yami.shop.common.util.PrincipalUtil; +import com.yami.shop.security.common.bo.TokenInfoBO; +import com.yami.shop.security.common.bo.UserInfoInTokenBO; +import com.yami.shop.security.common.enums.SysTypeEnum; +import com.yami.shop.security.common.vo.TokenInfoVO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.RedisCallback; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.stereotype.Component; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * token管理 1. 登陆返回token 2. 刷新token 3. 清除用户过去token 4. 校验token + * + * @author FrozenWatermelon + * @date 2020/7/2 + */ +@Component +public class TokenStore { + + private static final Logger logger = LoggerFactory.getLogger(TokenStore.class); + + /** + * 用于aes签名的key,16位 + */ + @Value("${auth.token.signKey:-mall4j--mall4j-}") + public String tokenSignKey; + + private final RedisTemplate redisTemplate; + + private final RedisSerializer redisSerializer; + + private final StringRedisTemplate stringRedisTemplate; + + public TokenStore(RedisTemplate redisTemplate, + StringRedisTemplate stringRedisTemplate) { + this.redisTemplate = redisTemplate; + this.redisSerializer = new KryoRedisSerializer<>(); + this.stringRedisTemplate = stringRedisTemplate; + } + + /** + * 将用户的部分信息存储在token中,并返回token信息 + * @param userInfoInToken 用户在token中的信息 + * @return token信息 + */ + public TokenInfoBO storeAccessToken(UserInfoInTokenBO userInfoInToken) { + TokenInfoBO tokenInfoBO = new TokenInfoBO(); + String accessToken = IdUtil.simpleUUID(); + String refreshToken = IdUtil.simpleUUID(); + + tokenInfoBO.setUserInfoInToken(userInfoInToken); + tokenInfoBO.setExpiresIn(getExpiresIn(userInfoInToken.getSysType())); + + String uidToAccessKeyStr = getUserIdToAccessKey(getApprovalKey(userInfoInToken)); + String accessKeyStr = getAccessKey(accessToken); + String refreshToAccessKeyStr = getRefreshToAccessKey(refreshToken); + + // 一个用户会登陆很多次,每次登陆的token都会存在 uid_to_access里面 + // 但是每次保存都会更新这个key的时间,而key里面的token有可能会过期,过期就要移除掉 + List existsAccessTokensBytes = new ArrayList<>(); + // 新的token数据 + existsAccessTokensBytes.add((accessToken + StrUtil.COLON + refreshToken).getBytes(StandardCharsets.UTF_8)); + + Long size = redisTemplate.opsForSet().size(uidToAccessKeyStr); + if (size != null && size != 0) { + List tokenInfoBoList = stringRedisTemplate.opsForSet().pop(uidToAccessKeyStr, size); + if (tokenInfoBoList != null) { + for (String accessTokenWithRefreshToken : tokenInfoBoList) { + String[] accessTokenWithRefreshTokenArr = accessTokenWithRefreshToken.split(StrUtil.COLON); + String accessTokenData = accessTokenWithRefreshTokenArr[0]; + if (BooleanUtil.isTrue(stringRedisTemplate.hasKey(getAccessKey(accessTokenData)))) { + existsAccessTokensBytes.add(accessTokenWithRefreshToken.getBytes(StandardCharsets.UTF_8)); + } + } + } + } + + redisTemplate.executePipelined((RedisCallback) connection -> { + + long expiresIn = tokenInfoBO.getExpiresIn(); + + byte[] uidKey = uidToAccessKeyStr.getBytes(StandardCharsets.UTF_8); + byte[] refreshKey = refreshToAccessKeyStr.getBytes(StandardCharsets.UTF_8); + byte[] accessKey = accessKeyStr.getBytes(StandardCharsets.UTF_8); + + connection.sAdd(uidKey, ArrayUtil.toArray(existsAccessTokensBytes, byte[].class)); + + // 通过uid + sysType 保存access_token,当需要禁用用户的时候,可以根据uid + sysType 禁用用户 + connection.expire(uidKey, expiresIn); + + // 通过refresh_token获取用户的access_token从而刷新token + connection.setEx(refreshKey, expiresIn, accessToken.getBytes(StandardCharsets.UTF_8)); + + // 通过access_token保存用户的租户id,用户id,uid + connection.setEx(accessKey, expiresIn, Objects.requireNonNull(redisSerializer.serialize(userInfoInToken))); + + return null; + }); + + // 返回给前端是加密的token + tokenInfoBO.setAccessToken(encryptToken(accessToken,userInfoInToken.getSysType())); + tokenInfoBO.setRefreshToken(encryptToken(refreshToken,userInfoInToken.getSysType())); + + return tokenInfoBO; + } + + private int getExpiresIn(int sysType) { + // 3600秒 + int expiresIn = 3600; + + // 普通用户token过期时间 1小时 + if (Objects.equals(sysType, SysTypeEnum.ORDINARY.value())) { + expiresIn = expiresIn * 24 * 30; + } + // 系统管理员的token过期时间 2小时 + if (Objects.equals(sysType, SysTypeEnum.ADMIN.value())) { + expiresIn = expiresIn * 24 * 30; + } + return expiresIn; + } + + /** + * 根据accessToken 获取用户信息 + * @param accessToken accessToken + * @param needDecrypt 是否需要解密 + * @return 用户信息 + */ + public UserInfoInTokenBO getUserInfoByAccessToken(String accessToken, boolean needDecrypt) { + if (StrUtil.isBlank(accessToken)) { + throw new YamiShopBindException(YamiHttpStatus.UNAUTHORIZED,"accessToken is blank"); + } + String realAccessToken; + if (needDecrypt) { + realAccessToken = decryptToken(accessToken); + } + else { + realAccessToken = accessToken; + } + UserInfoInTokenBO userInfoInTokenBO = (UserInfoInTokenBO) redisTemplate.opsForValue() + .get(getAccessKey(realAccessToken)); + + if (userInfoInTokenBO == null) { + throw new YamiShopBindException(YamiHttpStatus.UNAUTHORIZED,"accessToken 已过期"); + } + return userInfoInTokenBO; + } + + /** + * 刷新token,并返回新的token + * @param refreshToken + * @return + */ + public TokenInfoBO refreshToken(String refreshToken) { + if (StrUtil.isBlank(refreshToken)) { + throw new YamiShopBindException(YamiHttpStatus.UNAUTHORIZED,"refreshToken is blank"); + } + String realRefreshToken = decryptToken(refreshToken); + String accessToken = stringRedisTemplate.opsForValue().get(getRefreshToAccessKey(realRefreshToken)); + + if (StrUtil.isBlank(accessToken)) { + throw new YamiShopBindException(YamiHttpStatus.UNAUTHORIZED,"refreshToken 已过期"); + } + UserInfoInTokenBO userInfoInTokenBO = getUserInfoByAccessToken(accessToken, + false); + + // 删除旧的refresh_token + stringRedisTemplate.delete(getRefreshToAccessKey(realRefreshToken)); + // 删除旧的access_token + stringRedisTemplate.delete(getAccessKey(accessToken)); + // 保存一份新的token + return storeAccessToken(userInfoInTokenBO); + } + + /** + * 删除全部的token + */ + public void deleteAllToken(String sysType, String userId) { + String uidKey = getUserIdToAccessKey(getApprovalKey(sysType, userId)); + Long size = redisTemplate.opsForSet().size(uidKey); + if (size == null || size == 0) { + return; + } + List tokenInfoBoList = stringRedisTemplate.opsForSet().pop(uidKey, size); + + if (CollUtil.isEmpty(tokenInfoBoList)) { + return; + } + + for (String accessTokenWithRefreshToken : tokenInfoBoList) { + String[] accessTokenWithRefreshTokenArr = accessTokenWithRefreshToken.split(StrUtil.COLON); + String accessToken = accessTokenWithRefreshTokenArr[0]; + String refreshToken = accessTokenWithRefreshTokenArr[1]; + redisTemplate.delete(getRefreshToAccessKey(refreshToken)); + redisTemplate.delete(getAccessKey(accessToken)); + } + redisTemplate.delete(uidKey); + + } + + private static String getApprovalKey(UserInfoInTokenBO userInfoInToken) { + return getApprovalKey(userInfoInToken.getSysType().toString(), userInfoInToken.getUserId()); + } + + private static String getApprovalKey(String sysType, String userId) { + return userId == null? sysType : sysType + StrUtil.COLON + userId; + } + + private String encryptToken(String accessToken,Integer sysType) { + AES aes = new AES(tokenSignKey.getBytes(StandardCharsets.UTF_8)); + return aes.encryptBase64(accessToken + System.currentTimeMillis() + sysType); + } + + private String decryptToken(String data) { + AES aes = new AES(tokenSignKey.getBytes(StandardCharsets.UTF_8)); + String decryptStr; + String decryptToken; + try { + decryptStr = aes.decryptStr(data); + decryptToken = decryptStr.substring(0,32); + // 创建token的时间,token使用时效性,防止攻击者通过一堆的尝试找到aes的密码,虽然aes是目前几乎最好的加密算法 + long createTokenTime = Long.parseLong(decryptStr.substring(32,45)); + // 系统类型 + int sysType = Integer.parseInt(decryptStr.substring(45)); + // token的过期时间 + int expiresIn = getExpiresIn(sysType); + long second = 1000L; + if (System.currentTimeMillis() - createTokenTime > expiresIn * second) { + throw new YamiShopBindException(YamiHttpStatus.UNAUTHORIZED,"token error"); + } + } + catch (Exception e) { + throw new YamiShopBindException(YamiHttpStatus.UNAUTHORIZED,"token error"); + } + + // 防止解密后的token是脚本,从而对redis进行攻击,uuid只能是数字和小写字母 + if (!PrincipalUtil.isSimpleChar(decryptToken)) { + throw new YamiShopBindException(YamiHttpStatus.UNAUTHORIZED,"token error"); + } + return decryptToken; + } + + public String getAccessKey(String accessToken) { + return OauthCacheNames.ACCESS + accessToken; + } + + public String getUserIdToAccessKey(String approvalKey) { + return OauthCacheNames.UID_TO_ACCESS + approvalKey; + } + + public String getRefreshToAccessKey(String refreshToken) { + return OauthCacheNames.REFRESH_TO_ACCESS + refreshToken; + } + + public TokenInfoVO storeAndGetVo(UserInfoInTokenBO userInfoInToken) { + TokenInfoBO tokenInfoBO = storeAccessToken(userInfoInToken); + + TokenInfoVO tokenInfoVO = new TokenInfoVO(); + tokenInfoVO.setAccessToken(tokenInfoBO.getAccessToken()); + tokenInfoVO.setRefreshToken(tokenInfoBO.getRefreshToken()); + tokenInfoVO.setExpiresIn(tokenInfoBO.getExpiresIn()); + return tokenInfoVO; + } + + public void deleteCurrentToken(String accessToken) { + String decryptToken = decryptToken(accessToken); + + UserInfoInTokenBO userInfoInToken = getUserInfoByAccessToken(accessToken, true); + + String uidKey = getUserIdToAccessKey(getApprovalKey(userInfoInToken.getSysType().toString(), userInfoInToken.getUserId())); + Long size = redisTemplate.opsForSet().size(uidKey); + if (size == null || size == 0) { + return; + } + List tokenInfoBoList = stringRedisTemplate.opsForSet().pop(uidKey, size); + + if (CollUtil.isEmpty(tokenInfoBoList)) { + return; + } + String dbAccessToken = null; + String dbRefreshToken = null; + List list = new ArrayList<>(); + for (String accessTokenWithRefreshToken : tokenInfoBoList) { + String[] accessTokenWithRefreshTokenArr = accessTokenWithRefreshToken.split(StrUtil.COLON); + dbAccessToken = accessTokenWithRefreshTokenArr[0]; + if (decryptToken.equals(dbAccessToken)) { + dbRefreshToken = accessTokenWithRefreshTokenArr[1]; + redisTemplate.delete(getRefreshToAccessKey(dbRefreshToken)); + redisTemplate.delete(getAccessKey(dbAccessToken)); + continue; + } + list.add(accessTokenWithRefreshToken.getBytes(StandardCharsets.UTF_8)); + } + + if (CollUtil.isNotEmpty(list)) { + redisTemplate.executePipelined((RedisCallback) connection -> { + connection.sAdd(uidKey.getBytes(StandardCharsets.UTF_8), ArrayUtil.toArray(list, byte[].class)); + return null; + }); + } + } +} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/permission/PermissionService.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/permission/PermissionService.java similarity index 62% rename from yami-shop-security/src/main/java/com/yami/shop/security/permission/PermissionService.java rename to yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/permission/PermissionService.java index 15cd26b..b728c86 100644 --- a/yami-shop-security/src/main/java/com/yami/shop/security/permission/PermissionService.java +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/permission/PermissionService.java @@ -8,21 +8,18 @@ * 版权所有,侵权必究! */ -package com.yami.shop.security.permission; +package com.yami.shop.security.common.permission; import cn.hutool.core.util.StrUtil; +import com.yami.shop.security.common.util.AuthUserContext; import lombok.extern.slf4j.Slf4j; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import org.springframework.util.PatternMatchUtils; import org.springframework.util.StringUtils; -import java.util.Collection; - /** * 接口权限判断工具 + * @author lh */ @Slf4j @Component("pms") @@ -37,14 +34,8 @@ public class PermissionService { if (StrUtil.isBlank(permission)) { return false; } - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if (authentication == null) { - return false; - } - return authentication - .getAuthorities() + return AuthUserContext.get().getPerms() .stream() - .map(GrantedAuthority::getAuthority) .filter(StringUtils::hasText) .anyMatch(x -> PatternMatchUtils.simpleMatch(permission, x)); } diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/util/AuthUserContext.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/util/AuthUserContext.java new file mode 100644 index 0000000..747f67c --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/util/AuthUserContext.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.util; + + +import com.alibaba.ttl.TransmittableThreadLocal; +import com.yami.shop.security.common.bo.UserInfoInTokenBO; + +/** + * @author FrozenWatermelon + * @date 2020/7/16 + */ +public class AuthUserContext { + + private static final ThreadLocal USER_INFO_IN_TOKEN_HOLDER = new TransmittableThreadLocal<>(); + + public static UserInfoInTokenBO get() { + return USER_INFO_IN_TOKEN_HOLDER.get(); + } + + public static void set(UserInfoInTokenBO userInfoInTokenBo) { + USER_INFO_IN_TOKEN_HOLDER.set(userInfoInTokenBo); + } + + public static void clean() { + if (USER_INFO_IN_TOKEN_HOLDER.get() != null) { + USER_INFO_IN_TOKEN_HOLDER.remove(); + } + } +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/vo/TokenInfoVO.java b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/vo/TokenInfoVO.java new file mode 100644 index 0000000..a1642f1 --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/vo/TokenInfoVO.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. + * + * https://www.mall4j.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ +package com.yami.shop.security.common.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * token信息,该信息用户返回给前端,前端请求携带accessToken进行用户校验 + * + * @author FrozenWatermelon + * @date 2020/7/2 + */ +@Data +public class TokenInfoVO { + + @ApiModelProperty("accessToken") + private String accessToken; + + @ApiModelProperty("refreshToken") + private String refreshToken; + + @ApiModelProperty("在多少秒后过期") + private Integer expiresIn; +} diff --git a/yami-shop-security/yami-shop-security-common/src/main/resources/META-INF/services/com.anji.captcha.service.CaptchaCacheService b/yami-shop-security/yami-shop-security-common/src/main/resources/META-INF/services/com.anji.captcha.service.CaptchaCacheService new file mode 100644 index 0000000..544f3e4 --- /dev/null +++ b/yami-shop-security/yami-shop-security-common/src/main/resources/META-INF/services/com.anji.captcha.service.CaptchaCacheService @@ -0,0 +1 @@ +com.yami.shop.security.common.adapter.CaptchaCacheServiceRedisImpl diff --git a/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/1.png b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/1.png new file mode 100644 index 0000000..51573a0 Binary files /dev/null and b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/1.png differ diff --git a/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/2.png b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/2.png new file mode 100644 index 0000000..909dc39 Binary files /dev/null and b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/2.png differ diff --git a/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/3.png b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/3.png new file mode 100644 index 0000000..59bc59c Binary files /dev/null and b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/3.png differ diff --git a/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/4.png b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/4.png new file mode 100644 index 0000000..c856f4d Binary files /dev/null and b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/4.png differ diff --git a/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/5.png b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/5.png new file mode 100644 index 0000000..4594fcf Binary files /dev/null and b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/5.png differ diff --git a/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/6.png b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/6.png new file mode 100644 index 0000000..1e04492 Binary files /dev/null and b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/original/6.png differ diff --git a/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/slidingBlock/1.png b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/slidingBlock/1.png new file mode 100644 index 0000000..1905026 Binary files /dev/null and b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/slidingBlock/1.png differ diff --git a/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/slidingBlock/2.png b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/slidingBlock/2.png new file mode 100644 index 0000000..b1482d4 Binary files /dev/null and b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/slidingBlock/2.png differ diff --git a/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/slidingBlock/3.png b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/slidingBlock/3.png new file mode 100644 index 0000000..cdbb0b1 Binary files /dev/null and b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/slidingBlock/3.png differ diff --git a/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/slidingBlock/4.png b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/slidingBlock/4.png new file mode 100644 index 0000000..bc69c96 Binary files /dev/null and b/yami-shop-security/yami-shop-security-common/src/main/resources/captcha/slidingBlock/4.png differ diff --git a/yami-shop-service/src/main/java/com/yami/shop/dao/ProdPropMapper.java b/yami-shop-service/src/main/java/com/yami/shop/dao/ProdPropMapper.java index 85aeec5..779eb2e 100644 --- a/yami-shop-service/src/main/java/com/yami/shop/dao/ProdPropMapper.java +++ b/yami-shop-service/src/main/java/com/yami/shop/dao/ProdPropMapper.java @@ -19,7 +19,7 @@ import java.util.List; public interface ProdPropMapper extends BaseMapper { - List listPropAndValue(@Param("adapter") PageAdapter adapter, @Param("prodProp") ProdProp prodProp); + List listPropAndValue(@Param("com.yami.shop.security.common.adapter") PageAdapter adapter, @Param("prodProp") ProdProp prodProp); long countPropAndValue(@Param("prodProp") ProdProp prodProp); diff --git a/yami-shop-service/src/main/java/com/yami/shop/dao/UserMapper.java b/yami-shop-service/src/main/java/com/yami/shop/dao/UserMapper.java index 9447e36..f5a2b95 100644 --- a/yami-shop-service/src/main/java/com/yami/shop/dao/UserMapper.java +++ b/yami-shop-service/src/main/java/com/yami/shop/dao/UserMapper.java @@ -12,12 +12,11 @@ package com.yami.shop.dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.yami.shop.bean.model.User; -import com.yami.shop.bean.vo.UserVO; import org.apache.ibatis.annotations.Param; public interface UserMapper extends BaseMapper { - User getUserByBizUserId(@Param("appId")Integer appId, @Param("bizUserId")String bizUserId); - User getUserByUserMail(@Param("userMail") String userMail); + + User selectOneByUserName(@Param("userName") String userName); } diff --git a/yami-shop-service/src/main/java/com/yami/shop/service/SmsLogService.java b/yami-shop-service/src/main/java/com/yami/shop/service/SmsLogService.java index e67593d..84d377b 100644 --- a/yami-shop-service/src/main/java/com/yami/shop/service/SmsLogService.java +++ b/yami-shop-service/src/main/java/com/yami/shop/service/SmsLogService.java @@ -10,19 +10,17 @@ package com.yami.shop.service; -import java.util.Map; - import com.baomidou.mybatisplus.extension.service.IService; import com.yami.shop.bean.enums.SmsType; import com.yami.shop.bean.model.SmsLog; +import java.util.Map; + /** * * @author lgh on 2018/11/29. */ public interface SmsLogService extends IService { - public void sendSms(SmsType smsType,String userId,String mobile,Map params); - - public boolean checkValidCode(String mobile, String code,SmsType smsType); + void sendSms(SmsType smsType, String userId, String mobile, Map params); } diff --git a/yami-shop-service/src/main/java/com/yami/shop/service/UserService.java b/yami-shop-service/src/main/java/com/yami/shop/service/UserService.java index 4643c43..5643d09 100644 --- a/yami-shop-service/src/main/java/com/yami/shop/service/UserService.java +++ b/yami-shop-service/src/main/java/com/yami/shop/service/UserService.java @@ -13,7 +13,6 @@ package com.yami.shop.service; import com.baomidou.mybatisplus.extension.service.IService; import com.yami.shop.bean.model.User; import com.yami.shop.bean.param.UserRegisterParam; -import com.yami.shop.bean.vo.UserVO; /** * @@ -23,7 +22,5 @@ public interface UserService extends IService { User getUserByUserId(String userId); - Boolean insertUser(UserRegisterParam userRegisterParam); - void validate(UserRegisterParam userRegisterParam, String checkRegisterSmsFlag); } diff --git a/yami-shop-service/src/main/java/com/yami/shop/service/impl/MyOrderServiceImpl.java b/yami-shop-service/src/main/java/com/yami/shop/service/impl/MyOrderServiceImpl.java index 965b676..e34f841 100644 --- a/yami-shop-service/src/main/java/com/yami/shop/service/impl/MyOrderServiceImpl.java +++ b/yami-shop-service/src/main/java/com/yami/shop/service/impl/MyOrderServiceImpl.java @@ -10,24 +10,16 @@ package com.yami.shop.service.impl; -import java.util.List; - import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.yami.shop.bean.app.dto.MyOrderItemDto; -import com.yami.shop.bean.app.dto.ProductDto; -import com.yami.shop.common.util.PageAdapter; -import org.apache.commons.collections.CollectionUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - import com.yami.shop.bean.app.dto.MyOrderDto; import com.yami.shop.bean.model.Order; +import com.yami.shop.common.util.PageAdapter; import com.yami.shop.dao.OrderMapper; import com.yami.shop.service.MyOrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; /** * @author lgh on 2018/09/15. @@ -38,9 +30,6 @@ public class MyOrderServiceImpl extends ServiceImpl implemen @Autowired private OrderMapper orderMapper; - private static final Logger log = LoggerFactory.getLogger(MyOrderServiceImpl.class); - - @Override public IPage pageMyOrderByUserIdAndStatus(Page page, String userId, Integer status) { page.setRecords(orderMapper.listMyOrderByUserIdAndStatus(new PageAdapter(page), userId, status)); diff --git a/yami-shop-service/src/main/java/com/yami/shop/service/impl/SmsLogServiceImpl.java b/yami-shop-service/src/main/java/com/yami/shop/service/impl/SmsLogServiceImpl.java index 28af4b0..c5a830e 100644 --- a/yami-shop-service/src/main/java/com/yami/shop/service/impl/SmsLogServiceImpl.java +++ b/yami-shop-service/src/main/java/com/yami/shop/service/impl/SmsLogServiceImpl.java @@ -11,7 +11,6 @@ package com.yami.shop.service.impl; import cn.hutool.core.collection.CollectionUtil; -import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.RandomUtil; import com.aliyuncs.DefaultAcsClient; @@ -26,17 +25,12 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yami.shop.bean.enums.SmsType; import com.yami.shop.bean.model.SmsLog; import com.yami.shop.common.bean.ALiDaYu; -import com.yami.shop.common.enums.YamiHttpStatus; import com.yami.shop.common.exception.YamiShopBindException; import com.yami.shop.common.util.Json; -import com.yami.shop.common.util.RedisUtil; import com.yami.shop.dao.SmsLogMapper; import com.yami.shop.service.SmsLogService; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @@ -125,47 +119,6 @@ public class SmsLogServiceImpl extends ServiceImpl impleme } - @Override - @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) - public boolean checkValidCode(String mobile, String code, SmsType smsType) { - long checkValidCodeNum = RedisUtil.incr(CHECK_VALID_CODE_NUM_PREFIX + mobile, 1); - if (checkValidCodeNum == 0) { - // 半小时后失效 - RedisUtil.expire(CHECK_VALID_CODE_NUM_PREFIX, 1800); - } - if (checkValidCodeNum >= TIMES_CHECK_VALID_CODE_NUM) { - throw new YamiShopBindException("验证码校验过频繁,请稍后再试"); - } - SmsLog sms = new SmsLog(); - sms.setUserPhone(mobile); - sms.setMobileCode(code); - sms.setStatus(1); - sms.setType(smsType.value()); - - SmsLog dbSms = smsLogMapper.selectOne(new LambdaQueryWrapper() - .eq(SmsLog::getUserPhone, mobile) - .eq(SmsLog::getMobileCode, code) - .eq(SmsLog::getStatus, 1) - .eq(SmsLog::getType, smsType.value())); - // 没有找到当前的验证码 - if (dbSms == null) { - RedisUtil.incr(CHECK_VALID_CODE_NUM_PREFIX + mobile, 1); - return false; - } - RedisUtil.del(CHECK_VALID_CODE_NUM_PREFIX + mobile); - // 标记为失效状态 - dbSms.setStatus(0); - smsLogMapper.updateById(dbSms); - // 验证码已过期 - DateTime offsetMinute = DateUtil.offsetMinute(dbSms.getRecDate(), 5); - if (offsetMinute.getTime() < System.currentTimeMillis()) { - RedisUtil.incr(CHECK_VALID_CODE_NUM_PREFIX + mobile, 1); - return false; - } - - return true; - } - private void sendSms(String mobile, String templateCode, Map params) throws ClientException { //可自助调整超时时间 diff --git a/yami-shop-service/src/main/java/com/yami/shop/service/impl/UserServiceImpl.java b/yami-shop-service/src/main/java/com/yami/shop/service/impl/UserServiceImpl.java index 3c0ee50..0a0cf5c 100644 --- a/yami-shop-service/src/main/java/com/yami/shop/service/impl/UserServiceImpl.java +++ b/yami-shop-service/src/main/java/com/yami/shop/service/impl/UserServiceImpl.java @@ -46,23 +46,6 @@ public class UserServiceImpl extends ServiceImpl implements Us return userMapper.selectById(userId); } - @Override - public Boolean insertUser(UserRegisterParam uParam) { - User mail = userMapper.getUserByUserMail(uParam.getUserMail()); - if (mail != null) { - throw new YamiShopBindException("账号已存在"); - } - Date now = new Date(); - User user = new User(); - user.setUserId(IdUtil.simpleUUID()); - user.setModifyTime(now); - user.setUserRegtime(now); - user.setStatus(1); - user.setNickName(uParam.getUserMail()); - user.setUserMail(uParam.getUserMail()); - user.setLoginPassword(uParam.getPassword()); - return userMapper.insert(user) == 1; - } /** * 看看有没有校验验证码成功的标识 * @param userRegisterParam diff --git a/yami-shop-service/src/main/resources/mapper/ProdPropMapper.xml b/yami-shop-service/src/main/resources/mapper/ProdPropMapper.xml index a797b85..6a250e9 100644 --- a/yami-shop-service/src/main/resources/mapper/ProdPropMapper.xml +++ b/yami-shop-service/src/main/resources/mapper/ProdPropMapper.xml @@ -38,7 +38,7 @@ and prop_name like concat('%',#{prodProp.propName},'%') - LIMIT #{adapter.begin} , #{adapter.size} + LIMIT #{com.yami.shop.security.common.adapter.begin} , #{com.yami.shop.security.common.adapter.size} ) pp left join tz_prod_prop_value ppv on pp.prop_id = ppv.prop_id diff --git a/yami-shop-service/src/main/resources/mapper/UserMapper.xml b/yami-shop-service/src/main/resources/mapper/UserMapper.xml index 0e5ac47..2b07e33 100644 --- a/yami-shop-service/src/main/resources/mapper/UserMapper.xml +++ b/yami-shop-service/src/main/resources/mapper/UserMapper.xml @@ -24,15 +24,12 @@ - - - - + diff --git a/yami-shop-sys/pom.xml b/yami-shop-sys/pom.xml index 2b89e62..3d2f242 100644 --- a/yami-shop-sys/pom.xml +++ b/yami-shop-sys/pom.xml @@ -7,14 +7,13 @@ com.yami.shop yami-shop 0.0.1-SNAPSHOT - ../pom.xml com.yami.shop - yami-shop-security + yami-shop-security-admin ${yami.shop.version} diff --git a/yami-shop-sys/src/main/java/com/yami/shop/sys/aspect/SysLogAspect.java b/yami-shop-sys/src/main/java/com/yami/shop/sys/aspect/SysLogAspect.java index 386b888..7dd0a49 100644 --- a/yami-shop-sys/src/main/java/com/yami/shop/sys/aspect/SysLogAspect.java +++ b/yami-shop-sys/src/main/java/com/yami/shop/sys/aspect/SysLogAspect.java @@ -10,32 +10,21 @@ package com.yami.shop.sys.aspect; -import java.lang.reflect.Method; -import java.util.Date; - -import javax.servlet.http.HttpServletRequest; - - +import cn.hutool.core.date.SystemClock; import com.yami.shop.common.util.IPHelper; -import com.yami.shop.security.util.SecurityUtils; +import com.yami.shop.common.util.Json; +import com.yami.shop.security.admin.util.SecurityUtils; +import com.yami.shop.sys.model.SysLog; +import com.yami.shop.sys.service.SysLogService; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Pointcut; -import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; -import com.yami.shop.sys.service.SysLogService; -import com.yami.shop.sys.model.SysLog; -import com.yami.shop.common.util.Json; - -import cn.hutool.core.date.SystemClock; -import cn.hutool.core.util.StrUtil; +import java.util.Date; /** * @author lgh diff --git a/yami-shop-sys/src/main/java/com/yami/shop/sys/controller/SysMenuController.java b/yami-shop-sys/src/main/java/com/yami/shop/sys/controller/SysMenuController.java index 4630132..18d60f7 100644 --- a/yami-shop-sys/src/main/java/com/yami/shop/sys/controller/SysMenuController.java +++ b/yami-shop-sys/src/main/java/com/yami/shop/sys/controller/SysMenuController.java @@ -10,39 +10,25 @@ package com.yami.shop.sys.controller; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import javax.validation.Valid; - import cn.hutool.core.map.MapUtil; -import com.yami.shop.security.util.SecurityUtils; - +import cn.hutool.core.util.StrUtil; +import com.yami.shop.common.annotation.SysLog; +import com.yami.shop.common.exception.YamiShopBindException; +import com.yami.shop.security.admin.util.SecurityUtils; import com.yami.shop.sys.constant.Constant; import com.yami.shop.sys.constant.MenuType; import com.yami.shop.sys.model.SysMenu; +import com.yami.shop.sys.service.SysMenuService; +import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; - -import com.yami.shop.sys.service.SysMenuService; -import com.yami.shop.common.annotation.SysLog; -import com.yami.shop.common.exception.YamiShopBindException; - -import cn.hutool.core.util.StrUtil; -import io.swagger.annotations.ApiOperation; +import javax.validation.Valid; +import java.util.List; +import java.util.Map; +import java.util.Objects; /** * 系统菜单 @@ -60,9 +46,8 @@ public class SysMenuController{ @ApiOperation(value="获取用户所拥有的菜单和权限", notes="通过登陆用户的userId获取用户所拥有的菜单和权限") public ResponseEntity> nav(){ List menuList = sysMenuService.listMenuByUserId(SecurityUtils.getSysUser().getUserId()); - Collection authorities = SecurityUtils.getSysUser().getAuthorities(); - return ResponseEntity.ok(MapUtil.builder().put("menuList", menuList).put("authorities", authorities).build()); + return ResponseEntity.ok(MapUtil.builder().put("menuList", menuList).put("authorities", SecurityUtils.getSysUser().getAuthorities()).build()); } /** diff --git a/yami-shop-sys/src/main/java/com/yami/shop/sys/controller/SysUserController.java b/yami-shop-sys/src/main/java/com/yami/shop/sys/controller/SysUserController.java index 780b433..6a3f99f 100644 --- a/yami-shop-sys/src/main/java/com/yami/shop/sys/controller/SysUserController.java +++ b/yami-shop-sys/src/main/java/com/yami/shop/sys/controller/SysUserController.java @@ -11,41 +11,32 @@ package com.yami.shop.sys.controller; -import java.util.List; -import java.util.Objects; - -import javax.validation.Valid; - +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.yami.shop.common.annotation.SysLog; +import com.yami.shop.common.exception.YamiShopBindException; import com.yami.shop.common.util.PageParam; +import com.yami.shop.security.admin.util.SecurityUtils; +import com.yami.shop.security.common.enums.SysTypeEnum; +import com.yami.shop.security.common.manager.PasswordManager; +import com.yami.shop.security.common.manager.TokenStore; import com.yami.shop.sys.constant.Constant; -import com.yami.shop.security.util.SecurityUtils; - - import com.yami.shop.sys.dto.UpdatePasswordDto; import com.yami.shop.sys.model.SysUser; +import com.yami.shop.sys.service.SysRoleService; +import com.yami.shop.sys.service.SysUserService; +import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import com.yami.shop.sys.service.SysRoleService; -import com.yami.shop.sys.service.SysUserService; -import com.yami.shop.common.annotation.SysLog; -import com.yami.shop.common.exception.YamiShopBindException; +import org.springframework.web.bind.annotation.*; -import cn.hutool.core.util.ArrayUtil; -import cn.hutool.core.util.StrUtil; -import io.swagger.annotations.ApiOperation; +import javax.validation.Valid; +import java.util.List; +import java.util.Objects; /** * 系统用户 @@ -58,21 +49,22 @@ public class SysUserController { private SysUserService sysUserService; @Autowired private SysRoleService sysRoleService; - @Autowired private PasswordEncoder passwordEncoder; + @Autowired + private PasswordManager passwordManager; + @Autowired + private TokenStore tokenStore; + /** * 所有用户列表 */ @GetMapping("/page") @PreAuthorize("@pms.hasPermission('sys:user:page')") public ResponseEntity> page(String username,PageParam page){ - IPage sysUserPage = sysUserService.page(page, new LambdaQueryWrapper() .eq(SysUser::getShopId, SecurityUtils.getSysUser().getShopId()) .like(StrUtil.isNotBlank(username), SysUser::getUsername, username)); - - return ResponseEntity.ok(sysUserPage); } @@ -99,13 +91,15 @@ public class SysUserController { throw new YamiShopBindException("禁止修改admin的账号密码"); } SysUser dbUser = sysUserService.getSysUserById(userId); - if (!passwordEncoder.matches(param.getPassword(), dbUser.getPassword())) { + String password = passwordManager.decryptPassword(param.getPassword()); + if (!passwordEncoder.matches(password, dbUser.getPassword())) { return ResponseEntity.badRequest().body("原密码不正确"); } //新密码 - String newPassword = passwordEncoder.encode(param.getNewPassword()); + String newPassword = passwordEncoder.encode(passwordManager.decryptPassword(param.getNewPassword())); // 更新密码 sysUserService.updatePasswordByUserId(userId, newPassword); + tokenStore.deleteAllToken(String.valueOf(SysTypeEnum.ADMIN.value()),String.valueOf(userId)); return ResponseEntity.ok().build(); } @@ -140,7 +134,7 @@ public class SysUserController { return ResponseEntity.badRequest().body("该用户已存在"); } user.setShopId(SecurityUtils.getSysUser().getShopId()); - user.setPassword(passwordEncoder.encode(user.getPassword())); + user.setPassword(passwordEncoder.encode(passwordManager.decryptPassword(user.getPassword()))); sysUserService.saveUserAndUserRole(user); return ResponseEntity.ok().build(); } @@ -152,7 +146,7 @@ public class SysUserController { @PutMapping @PreAuthorize("@pms.hasPermission('sys:user:update')") public ResponseEntity update(@Valid @RequestBody SysUser user){ - String password = user.getPassword(); + String password = passwordManager.decryptPassword(user.getPassword()); SysUser dbUser = sysUserService.getSysUserById(user.getUserId()); if (!Objects.equals(dbUser.getShopId(), SecurityUtils.getSysUser().getShopId())) { @@ -201,6 +195,4 @@ public class SysUserController { sysUserService.deleteBatch(userIds,SecurityUtils.getSysUser().getShopId()); return ResponseEntity.ok().build(); } - - } diff --git a/yami-shop-sys/src/main/java/com/yami/shop/sys/dao/SysUserMapper.java b/yami-shop-sys/src/main/java/com/yami/shop/sys/dao/SysUserMapper.java index e32351c..c1b3260 100644 --- a/yami-shop-sys/src/main/java/com/yami/shop/sys/dao/SysUserMapper.java +++ b/yami-shop-sys/src/main/java/com/yami/shop/sys/dao/SysUserMapper.java @@ -25,7 +25,7 @@ public interface SysUserMapper extends BaseMapper { * 查询用户的所有权限 * @param userId 用户ID */ - List queryAllPerms(Long userId); + List queryAllPerms(@Param("userId") Long userId); /** * 根据用户id 批量删除用户 @@ -38,6 +38,6 @@ public interface SysUserMapper extends BaseMapper { * @param username * @return */ - SysUser selectByUsername(String username); + SysUser selectByUsername(@Param("username") String username); } diff --git a/yami-shop-sys/src/main/java/com/yami/shop/sys/model/SysUser.java b/yami-shop-sys/src/main/java/com/yami/shop/sys/model/SysUser.java index 9abed9a..a8e24e7 100644 --- a/yami-shop-sys/src/main/java/com/yami/shop/sys/model/SysUser.java +++ b/yami-shop-sys/src/main/java/com/yami/shop/sys/model/SysUser.java @@ -14,7 +14,6 @@ package com.yami.shop.sys.model; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; diff --git a/yami-shop-sys/src/main/java/com/yami/shop/sys/service/SysUserService.java b/yami-shop-sys/src/main/java/com/yami/shop/sys/service/SysUserService.java index 3a21c0c..4c6ea5b 100644 --- a/yami-shop-sys/src/main/java/com/yami/shop/sys/service/SysUserService.java +++ b/yami-shop-sys/src/main/java/com/yami/shop/sys/service/SysUserService.java @@ -13,6 +13,8 @@ package com.yami.shop.sys.service; import com.baomidou.mybatisplus.extension.service.IService; import com.yami.shop.sys.model.SysUser; +import java.util.List; + /** * 系统用户 @@ -60,4 +62,10 @@ public interface SysUserService extends IService { */ SysUser getSysUserById(Long userId); + /** + * 查询用户的所有权限 + * @param userId 用户ID + */ + List queryAllPerms(Long userId); + } diff --git a/yami-shop-sys/src/main/java/com/yami/shop/sys/service/impl/SysUserServiceImpl.java b/yami-shop-sys/src/main/java/com/yami/shop/sys/service/impl/SysUserServiceImpl.java index 92dfb6c..e74cae7 100644 --- a/yami-shop-sys/src/main/java/com/yami/shop/sys/service/impl/SysUserServiceImpl.java +++ b/yami-shop-sys/src/main/java/com/yami/shop/sys/service/impl/SysUserServiceImpl.java @@ -18,12 +18,11 @@ import com.yami.shop.sys.dao.SysUserRoleMapper; import com.yami.shop.sys.model.SysUser; import com.yami.shop.sys.service.SysUserService; import lombok.AllArgsConstructor; -import org.springframework.cache.annotation.CacheEvict; -import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Date; +import java.util.List; /** @@ -88,4 +87,9 @@ public class SysUserServiceImpl extends ServiceImpl impl public SysUser getSysUserById(Long userId) { return sysUserMapper.selectById(userId); } + + @Override + public List queryAllPerms(Long userId) { + return sysUserMapper.queryAllPerms(userId); + } }