mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-25 08:41:52 +08:00
多模块重构 12:【新增】Spring Security 新增 AuthorizeRequestsCustomizer 抽象类, 自定义每个 Maven Module 的 URL 的安全配置
This commit is contained in:
parent
4890cf05de
commit
c2ccfa3bd6
@ -4,7 +4,7 @@
|
|||||||
"token": "test1",
|
"token": "test1",
|
||||||
"adminTenentId": "1",
|
"adminTenentId": "1",
|
||||||
|
|
||||||
"userApi": "http://127.0.0.1:48080/app-api",
|
"appApi": "http://127.0.0.1:48080/app-api",
|
||||||
"appToken": "test1",
|
"appToken": "test1",
|
||||||
"appTenentId": "1"
|
"appTenentId": "1"
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
package cn.iocoder.yudao.framework.security.config;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.web.config.WebProperties;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.security.config.Customizer;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义的 URL 的安全配置
|
||||||
|
* 目的:每个 Maven Module 可以自定义规则!
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public abstract class AuthorizeRequestsCustomizer
|
||||||
|
implements Customizer<ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry>, Ordered {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private WebProperties webProperties;
|
||||||
|
|
||||||
|
protected String buildAdminApi(String url) {
|
||||||
|
return webProperties.getAdminApi().getPrefix() + url;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String buildAppApi(String url) {
|
||||||
|
return webProperties.getAppApi().getPrefix() + url;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -26,6 +26,8 @@ import org.springframework.security.web.util.matcher.RequestMatcher;
|
|||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义的 Spring Security 配置适配器实现
|
* 自定义的 Spring Security 配置适配器实现
|
||||||
@ -62,14 +64,22 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap
|
|||||||
@Resource
|
@Resource
|
||||||
private JWTAuthenticationTokenFilter authenticationTokenFilter;
|
private JWTAuthenticationTokenFilter authenticationTokenFilter;
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 自定义的权限映射 Bean
|
||||||
|
// *
|
||||||
|
// * @see #configure(HttpSecurity)
|
||||||
|
// */
|
||||||
|
// @Resource
|
||||||
|
// private Customizer<ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry>
|
||||||
|
// authorizeRequestsCustomizer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义的权限映射 Bean
|
* 自定义的权限映射 Bean 们
|
||||||
*
|
*
|
||||||
* @see #configure(HttpSecurity)
|
* @see #configure(HttpSecurity)
|
||||||
*/
|
*/
|
||||||
@Resource
|
@Resource
|
||||||
private Customizer<ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry>
|
private List<AuthorizeRequestsCustomizer> authorizeRequestsCustomizers;
|
||||||
authorizeRequestsCustomizer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 由于 Spring Security 创建 AuthenticationManager 对象时,没声明 @Bean 注解,导致无法被注入
|
* 由于 Spring Security 创建 AuthenticationManager 对象时,没声明 @Bean 注解,导致无法被注入
|
||||||
@ -126,44 +136,31 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap
|
|||||||
StrUtil.equalsAny(request.getRequestURI(), buildAdminApi("/system/logout"),
|
StrUtil.equalsAny(request.getRequestURI(), buildAdminApi("/system/logout"),
|
||||||
buildAppApi("/member/logout")));
|
buildAppApi("/member/logout")));
|
||||||
|
|
||||||
// 设置每个请求的权限 ①:全局共享规则
|
// 设置每个请求的权限
|
||||||
httpSecurity.authorizeRequests()
|
httpSecurity
|
||||||
// 登录的接口,可匿名访问
|
// ①:全局共享规则
|
||||||
.antMatchers(buildAdminApi("/system/login"), buildAdminApi("/member/login")).anonymous()
|
.authorizeRequests()
|
||||||
// 静态资源,可匿名访问
|
// 静态资源,可匿名访问
|
||||||
.antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll()
|
.antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll()
|
||||||
// 文件的获取接口,可匿名访问
|
// 设置 App API 无需认证
|
||||||
.antMatchers(buildAdminApi("/infra/file/get/**")).anonymous()
|
.antMatchers(buildAppApi("/**")).permitAll()
|
||||||
// Swagger 接口文档
|
// ②:每个项目的自定义规则
|
||||||
.antMatchers("/swagger-ui.html").anonymous()
|
.and().authorizeRequests(registry -> // 下面,循环设置自定义规则
|
||||||
.antMatchers("/swagger-resources/**").anonymous()
|
authorizeRequestsCustomizers.forEach(customizer -> customizer.customize(registry)))
|
||||||
.antMatchers("/webjars/**").anonymous()
|
// ③:兜底规则,必须认证
|
||||||
.antMatchers("/*/api-docs").anonymous()
|
.authorizeRequests()
|
||||||
// Spring Boot Actuator 的安全配置
|
.anyRequest().authenticated()
|
||||||
.antMatchers("/actuator").anonymous()
|
|
||||||
.antMatchers("/actuator/**").anonymous()
|
|
||||||
// Druid 监控 TODO 芋艿:等对接了 druid admin 后,在调整下。
|
|
||||||
.antMatchers("/druid/**").anonymous()
|
|
||||||
// oAuth2 auth2/login/gitee TODO 芋艿:貌似可以删除
|
|
||||||
.antMatchers(buildAdminApi("/auth2/login/**")).anonymous()
|
|
||||||
.antMatchers(buildAdminApi("/auth2/authorization/**")).anonymous()
|
|
||||||
.antMatchers("/api/callback/**").anonymous()
|
|
||||||
// 设置每个请求的权限 ②:每个项目的自定义规则 TODO 芋艿:改造成多个,方便每个模块自定义规则
|
|
||||||
.and().authorizeRequests(authorizeRequestsCustomizer)
|
|
||||||
// 设置每个请求的权限 ③:兜底规则,必须认证
|
|
||||||
.authorizeRequests().anyRequest().authenticated()
|
|
||||||
;
|
;
|
||||||
|
|
||||||
// 添加 JWT Filter
|
// 添加 JWT Filter
|
||||||
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
|
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildAdminApi(String url) {
|
private String buildAdminApi(String url) {
|
||||||
// TODO 芋艿:多模块
|
|
||||||
return webProperties.getAdminApi().getPrefix() + url;
|
return webProperties.getAdminApi().getPrefix() + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildAppApi(String url) {
|
private String buildAppApi(String url) {
|
||||||
// TODO 芋艿:多模块
|
|
||||||
return webProperties.getAppApi().getPrefix() + url;
|
return webProperties.getAppApi().getPrefix() + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +90,17 @@
|
|||||||
<groupId>cn.smallbun.screw</groupId>
|
<groupId>cn.smallbun.screw</groupId>
|
||||||
<artifactId>screw-core</artifactId> <!-- 实现数据库文档 -->
|
<artifactId>screw-core</artifactId> <!-- 实现数据库文档 -->
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 监控相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
|
<artifactId>yudao-spring-boot-starter-monitor</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.codecentric</groupId>
|
||||||
|
<artifactId>spring-boot-admin-starter-server</artifactId> <!-- 实现 Spring Boot Admin Server 服务端 -->
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.server.framework.monitor.config;
|
package cn.iocoder.yudao.module.infra.framework.monitor.config;
|
||||||
|
|
||||||
import de.codecentric.boot.admin.server.config.EnableAdminServer;
|
import de.codecentric.boot.admin.server.config.EnableAdminServer;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
@ -1,4 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* 使用 Spring Boot Admin 实现简单的监控平台
|
* 使用 Spring Boot Admin 实现简单的监控平台
|
||||||
*/
|
*/
|
||||||
package cn.iocoder.yudao.server.framework.monitor;
|
package cn.iocoder.yudao.module.infra.framework.monitor;
|
@ -0,0 +1,45 @@
|
|||||||
|
package cn.iocoder.yudao.module.infra.framework.security.config;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Infra 模块的 Security 配置
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class InfraSecurityConfiguration {
|
||||||
|
|
||||||
|
@Value("${spring.boot.admin.context-path:''}")
|
||||||
|
private String adminSeverContextPath;
|
||||||
|
|
||||||
|
@Bean("infraAuthorizeRequestsCustomizer")
|
||||||
|
public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
|
||||||
|
return new AuthorizeRequestsCustomizer() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
|
||||||
|
// Swagger 接口文档
|
||||||
|
registry.antMatchers("/swagger-ui.html").anonymous()
|
||||||
|
.antMatchers("/swagger-resources/**").anonymous()
|
||||||
|
.antMatchers("/webjars/**").anonymous()
|
||||||
|
.antMatchers("/*/api-docs").anonymous();
|
||||||
|
// Spring Boot Actuator 的安全配置
|
||||||
|
registry.antMatchers("/actuator").anonymous()
|
||||||
|
.antMatchers("/actuator/**").anonymous();
|
||||||
|
// Druid 监控
|
||||||
|
registry.antMatchers("/druid/**").anonymous();
|
||||||
|
// Spring Boot Admin Server 的安全配置
|
||||||
|
registry.antMatchers(adminSeverContextPath).anonymous()
|
||||||
|
.antMatchers(adminSeverContextPath + "/**").anonymous();
|
||||||
|
// 文件的获取接口,可匿名访问
|
||||||
|
registry.antMatchers(buildAdminApi("/infra/file/get/**"), buildAppApi("/infra/file/get/**")).anonymous();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* 占位
|
||||||
|
*/
|
||||||
|
package cn.iocoder.yudao.module.infra.framework.security.core;
|
@ -1,6 +0,0 @@
|
|||||||
/**
|
|
||||||
* 属于 yudao-module-member-impl 的封装
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
package cn.iocoder.yudao.module.member.framework;
|
|
@ -202,6 +202,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
|
|||||||
if (user != null) {
|
if (user != null) {
|
||||||
reqDTO.setUserId(user.getId());
|
reqDTO.setUserId(user.getId());
|
||||||
}
|
}
|
||||||
|
reqDTO.setUserType(getUserType().getValue());
|
||||||
reqDTO.setUsername(mobile);
|
reqDTO.setUsername(mobile);
|
||||||
reqDTO.setUserAgent(ServletUtils.getUserAgent());
|
reqDTO.setUserAgent(ServletUtils.getUserAgent());
|
||||||
reqDTO.setUserIp(getClientIP());
|
reqDTO.setUserIp(getClientIP());
|
||||||
|
@ -23,7 +23,6 @@ public class LoginLogCreateReqDTO {
|
|||||||
/**
|
/**
|
||||||
* 链路追踪编号
|
* 链路追踪编号
|
||||||
*/
|
*/
|
||||||
@NotEmpty(message = "链路追踪编号不能为空")
|
|
||||||
private String traceId;
|
private String traceId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.framework.security.config;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* System 模块的 Security 配置
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class SystemSecurityConfiguration {
|
||||||
|
|
||||||
|
@Bean("systemAuthorizeRequestsCustomizer")
|
||||||
|
public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
|
||||||
|
return new AuthorizeRequestsCustomizer() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
|
||||||
|
// 登录的接口,可匿名访问
|
||||||
|
registry.antMatchers(buildAdminApi("/system/login")).anonymous();
|
||||||
|
// 验证码的接口
|
||||||
|
registry.antMatchers(buildAdminApi("/system/captcha/**")).anonymous();
|
||||||
|
// 获得租户编号的接口
|
||||||
|
registry.antMatchers(buildAdminApi("/system/tenant/get-id-by-name")).anonymous();
|
||||||
|
// 短信回调 API
|
||||||
|
registry.antMatchers(buildAdminApi("/system/sms/callback/**")).anonymous();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* 占位
|
||||||
|
*/
|
||||||
|
package cn.iocoder.yudao.module.system.framework.security.core;
|
@ -164,7 +164,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
|||||||
if (user != null) {
|
if (user != null) {
|
||||||
reqDTO.setUserId(user.getId());
|
reqDTO.setUserId(user.getId());
|
||||||
}
|
}
|
||||||
reqDTO.setUserType(UserTypeEnum.ADMIN.getValue());
|
reqDTO.setUserType(getUserType().getValue());
|
||||||
reqDTO.setUsername(username);
|
reqDTO.setUsername(username);
|
||||||
reqDTO.setUserAgent(ServletUtils.getUserAgent());
|
reqDTO.setUserAgent(ServletUtils.getUserAgent());
|
||||||
reqDTO.setUserIp(ServletUtils.getClientIP());
|
reqDTO.setUserIp(ServletUtils.getClientIP());
|
||||||
|
@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.system.convert.logger.LoginLogConvert;
|
|||||||
import cn.iocoder.yudao.module.system.dal.dataobject.logger.LoginLogDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.logger.LoginLogDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.mysql.logger.LoginLogMapper;
|
import cn.iocoder.yudao.module.system.dal.mysql.logger.LoginLogMapper;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -16,6 +17,7 @@ import java.util.List;
|
|||||||
* 登录日志 Service 实现
|
* 登录日志 Service 实现
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@Validated
|
||||||
public class LoginLogServiceImpl implements LoginLogService {
|
public class LoginLogServiceImpl implements LoginLogService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -67,17 +67,6 @@
|
|||||||
<artifactId>yudao-spring-boot-starter-protection</artifactId>
|
<artifactId>yudao-spring-boot-starter-protection</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 监控相关 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
|
||||||
<artifactId>yudao-spring-boot-starter-monitor</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>de.codecentric</groupId>
|
|
||||||
<artifactId>spring-boot-admin-starter-server</artifactId> <!-- 实现 Spring Boot Admin Server 服务端 -->
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* 占位
|
||||||
|
*/
|
||||||
|
package cn.iocoder.yudao.module.shop.controller.admin;
|
@ -1,13 +1,13 @@
|
|||||||
package cn.iocoder.yudao.userserver.modules.shop.controller;
|
package cn.iocoder.yudao.module.shop.controller.app;
|
||||||
|
|
||||||
import cn.iocoder.yudao.coreservice.modules.pay.service.notify.vo.PayNotifyOrderReqVO;
|
|
||||||
import cn.iocoder.yudao.coreservice.modules.pay.service.notify.vo.PayRefundOrderReqVO;
|
|
||||||
import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayOrderCoreService;
|
|
||||||
import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderCreateReqDTO;
|
|
||||||
import cn.iocoder.yudao.coreservice.modules.pay.util.PaySeqUtils;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||||
import cn.iocoder.yudao.userserver.modules.shop.controller.vo.ShopOrderCreateRespVO;
|
import cn.iocoder.yudao.module.pay.service.notify.vo.PayNotifyOrderReqVO;
|
||||||
|
import cn.iocoder.yudao.module.pay.service.notify.vo.PayRefundOrderReqVO;
|
||||||
|
import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
|
||||||
|
import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderCreateReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.pay.util.PaySeqUtils;
|
||||||
|
import cn.iocoder.yudao.module.shop.controller.app.vo.AppShopOrderCreateRespVO;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -24,20 +24,20 @@ import java.time.Duration;
|
|||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
|
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
|
||||||
|
|
||||||
@Api(tags = "商城订单")
|
@Api(tags = "用户 APP - 商城订单")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/shop/order")
|
@RequestMapping("/shop/order")
|
||||||
@Validated
|
@Validated
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ShopOrderController {
|
public class AppShopOrderController {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private PayOrderCoreService payOrderCoreService;
|
private PayOrderService payOrderService;
|
||||||
|
|
||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
@ApiOperation("创建商城订单")
|
@ApiOperation("创建商城订单")
|
||||||
// @PreAuthenticated // TODO 暂时不加登陆验证,前端暂时没做好
|
// @PreAuthenticated // TODO 暂时不加登陆验证,前端暂时没做好
|
||||||
public CommonResult<ShopOrderCreateRespVO> create() {
|
public CommonResult<AppShopOrderCreateRespVO> create() {
|
||||||
// 假装创建商城订单
|
// 假装创建商城订单
|
||||||
Long shopOrderId = System.currentTimeMillis();
|
Long shopOrderId = System.currentTimeMillis();
|
||||||
|
|
||||||
@ -50,10 +50,10 @@ public class ShopOrderController {
|
|||||||
reqDTO.setBody("内容:" + shopOrderId);
|
reqDTO.setBody("内容:" + shopOrderId);
|
||||||
reqDTO.setAmount(200); // 单位:分
|
reqDTO.setAmount(200); // 单位:分
|
||||||
reqDTO.setExpireTime(DateUtils.addTime(Duration.ofDays(1)));
|
reqDTO.setExpireTime(DateUtils.addTime(Duration.ofDays(1)));
|
||||||
Long payOrderId = payOrderCoreService.createPayOrder(reqDTO);
|
Long payOrderId = payOrderService.createPayOrder(reqDTO);
|
||||||
|
|
||||||
// 拼接返回
|
// 拼接返回
|
||||||
return success(ShopOrderCreateRespVO.builder().id(shopOrderId)
|
return success(AppShopOrderCreateRespVO.builder().id(shopOrderId)
|
||||||
.payOrderId(payOrderId).build());
|
.payOrderId(payOrderId).build());
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.userserver.modules.shop.controller.vo;
|
package cn.iocoder.yudao.module.shop.controller.app.vo;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
@ -6,11 +6,11 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@ApiModel("商城订单创建 Response VO")
|
@ApiModel("用户 APP - 商城订单创建 Response VO")
|
||||||
@Data
|
@Data
|
||||||
@Builder
|
@Builder
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class ShopOrderCreateRespVO {
|
public class AppShopOrderCreateRespVO {
|
||||||
|
|
||||||
@ApiModelProperty(value = "商城订单编号", required = true, example = "1024")
|
@ApiModelProperty(value = "商城订单编号", required = true, example = "1024")
|
||||||
private Long id;
|
private Long id;
|
@ -5,4 +5,5 @@
|
|||||||
*
|
*
|
||||||
* 缩写:shop
|
* 缩写:shop
|
||||||
*/
|
*/
|
||||||
package cn.iocoder.yudao.userserver.modules.shop;
|
// TODO 芋艿:后续会迁移到 yudao-module-mall-trade 下
|
||||||
|
package cn.iocoder.yudao.module.shop;
|
@ -1,50 +0,0 @@
|
|||||||
package cn.iocoder.yudao.server.framework.security;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.web.config.WebProperties;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.security.config.Customizer;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class SecurityConfiguration {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private WebProperties webProperties;
|
|
||||||
|
|
||||||
@Value("${spring.boot.admin.context-path:''}")
|
|
||||||
private String adminSeverContextPath;
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Customizer<ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry> authorizeRequestsCustomizer() {
|
|
||||||
return registry -> {
|
|
||||||
// 验证码的接口
|
|
||||||
registry.antMatchers(buildAdminApi("/system/captcha/**")).anonymous();
|
|
||||||
// 获得租户编号的接口
|
|
||||||
registry.antMatchers(buildAdminApi("/system/tenant/get-id-by-name")).anonymous();
|
|
||||||
// Spring Boot Admin Server 的安全配置
|
|
||||||
registry.antMatchers(adminSeverContextPath).anonymous()
|
|
||||||
.antMatchers(adminSeverContextPath + "/**").anonymous();
|
|
||||||
// 短信回调 API
|
|
||||||
registry.antMatchers(buildAdminApi("/system/sms/callback/**")).anonymous();
|
|
||||||
|
|
||||||
// 设置 App API 无需认证
|
|
||||||
registry.antMatchers(buildAppApi("/**")).permitAll();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private String buildAdminApi(String url) {
|
|
||||||
// TODO 芋艿:多模块
|
|
||||||
return webProperties.getAdminApi().getPrefix() + url;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String buildAppApi(String url) {
|
|
||||||
// TODO 芋艿:多模块
|
|
||||||
return webProperties.getAppApi().getPrefix() + url;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -20,6 +20,10 @@ spring:
|
|||||||
write-durations-as-timestamps: true # 设置 Duration 的格式,使用时间戳
|
write-durations-as-timestamps: true # 设置 Duration 的格式,使用时间戳
|
||||||
fail-on-empty-beans: false # 允许序列化无属性的 Bean
|
fail-on-empty-beans: false # 允许序列化无属性的 Bean
|
||||||
|
|
||||||
|
# 静态资源
|
||||||
|
mvc:
|
||||||
|
static-path-pattern: /static/**
|
||||||
|
|
||||||
# 工作流 Activiti 配置
|
# 工作流 Activiti 配置
|
||||||
activiti:
|
activiti:
|
||||||
# 1. false: 默认值,activiti启动时,对比数据库表中保存的版本,如果不匹配。将抛出异常
|
# 1. false: 默认值,activiti启动时,对比数据库表中保存的版本,如果不匹配。将抛出异常
|
||||||
|
@ -24,11 +24,11 @@
|
|||||||
<script>
|
<script>
|
||||||
let shopOrderId = undefined;
|
let shopOrderId = undefined;
|
||||||
let payOrderId = undefined;
|
let payOrderId = undefined;
|
||||||
let server = 'http://127.0.0.1:28080';
|
let server = 'http://127.0.0.1:48080';
|
||||||
$(function() {
|
$(function() {
|
||||||
// 自动发起商城订单编号
|
// 自动发起商城订单编号
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: server + "/api/shop/order/create",
|
url: server + "/app-api/shop/order/create",
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
success: function( result ) {
|
success: function( result ) {
|
||||||
if (result.code !== 0) {
|
if (result.code !== 0) {
|
||||||
@ -46,7 +46,7 @@
|
|||||||
$( "#alipay_wap").on( "click", function() {
|
$( "#alipay_wap").on( "click", function() {
|
||||||
// 提交支付
|
// 提交支付
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: server + "/api/pay/order/submit",
|
url: server + "/app-api/pay/order/submit",
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
contentType: "application/json",
|
contentType: "application/json",
|
@ -17,13 +17,13 @@
|
|||||||
|
|
||||||
let shopOrderId = undefined;
|
let shopOrderId = undefined;
|
||||||
let payOrderId = undefined;
|
let payOrderId = undefined;
|
||||||
let server = 'http://127.0.0.1:28080';
|
let server = 'http://127.0.0.1:48080';
|
||||||
//let server = 'http://niubi.natapp1.cc';
|
//let server = 'http://niubi.natapp1.cc';
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
// 自动发起商城订单编号
|
// 自动发起商城订单编号
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: server + "/api/shop/order/create",
|
url: server + "/app-api/shop/order/create",
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
success: function( result ) {
|
success: function( result ) {
|
||||||
if (result.code !== 0) {
|
if (result.code !== 0) {
|
||||||
@ -41,7 +41,7 @@
|
|||||||
$( "#alipay_wap").on( "click", function() {
|
$( "#alipay_wap").on( "click", function() {
|
||||||
// 提交支付
|
// 提交支付
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: server + "/api/pay/order/submit",
|
url: server + "/app-api/pay/order/submit",
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
contentType: "application/json",
|
contentType: "application/json",
|
@ -16,7 +16,7 @@
|
|||||||
<script>
|
<script>
|
||||||
let shopOrderId = undefined;
|
let shopOrderId = undefined;
|
||||||
let payOrderId = undefined;
|
let payOrderId = undefined;
|
||||||
// let server = 'http://127.0.0.1:28080';
|
// let server = 'http://127.0.0.1:48080';
|
||||||
let server = 'http://niubi.natapp1.cc';
|
let server = 'http://niubi.natapp1.cc';
|
||||||
// TODO openid
|
// TODO openid
|
||||||
let openid = "ockUAwIZ-0OeMZl9ogcZ4ILrGba0";
|
let openid = "ockUAwIZ-0OeMZl9ogcZ4ILrGba0";
|
||||||
@ -24,7 +24,7 @@
|
|||||||
// 获得 JsapiTicket
|
// 获得 JsapiTicket
|
||||||
// 参考 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 文档
|
// 参考 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 文档
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: server + "/api/wx/mp/create-jsapi-signature?url=" + document.location.href,
|
url: server + "/app-api/wx/mp/create-jsapi-signature?url=" + document.location.href,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
success: function( result ) {
|
success: function( result ) {
|
||||||
if (result.code !== 0) {
|
if (result.code !== 0) {
|
||||||
@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
// 自动发起商城订单编号
|
// 自动发起商城订单编号
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: server + "/api/shop/order/create",
|
url: server + "/app-api/shop/order/create",
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
success: function( result ) {
|
success: function( result ) {
|
||||||
if (result.code !== 0) {
|
if (result.code !== 0) {
|
||||||
@ -78,7 +78,7 @@
|
|||||||
// 参考 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6 文档
|
// 参考 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6 文档
|
||||||
// 参考 https://segmentfault.com/a/1190000020704650 文档
|
// 参考 https://segmentfault.com/a/1190000020704650 文档
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: server + "/api/pay/order/submit",
|
url: server + "/app-api/pay/order/submit",
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
contentType: "application/json",
|
contentType: "application/json",
|
@ -14,14 +14,14 @@
|
|||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
// let server = 'http://127.0.0.1:28080';
|
// let server = 'http://127.0.0.1:28080';
|
||||||
let server = 'http://192.168.1.2:28080';
|
let server = 'http://192.168.1.2:48080';
|
||||||
|
|
||||||
|
|
||||||
// 微信公众号
|
// 微信公众号
|
||||||
$( "#wx_pub").on( "click", function() {
|
$( "#wx_pub").on( "click", function() {
|
||||||
// 获得授权链接
|
// 获得授权链接
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: server + "/api/social-auth-redirect?type=31&redirectUri=" +
|
url: server + "/app-api/social-auth-redirect?type=31&redirectUri=" +
|
||||||
encodeURIComponent(server + '/static/social-login2.html'), //重定向地址
|
encodeURIComponent(server + '/static/social-login2.html'), //重定向地址
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
success: function( result ) {
|
success: function( result ) {
|
@ -17,8 +17,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
// let server = 'http://127.0.0.1:28080';
|
// let server = 'http://127.0.0.1:48080';
|
||||||
let server = 'http://192.168.1.2:28080';
|
let server = 'http://192.168.1.2:48080';
|
||||||
|
|
||||||
let type = 31; //登录类型 微信公众号
|
let type = 31; //登录类型 微信公众号
|
||||||
|
|
||||||
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
// 调用授权登录接口
|
// 调用授权登录接口
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: server + "/api/social-login2",
|
url: server + "/app-api/social-login2",
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: JSON.stringify(data),
|
data: JSON.stringify(data),
|
||||||
contentType: "application/json;charset=utf-8",
|
contentType: "application/json;charset=utf-8",
|
||||||
@ -60,7 +60,7 @@
|
|||||||
'scene': 1 // 手机号登陆 类型
|
'scene': 1 // 手机号登陆 类型
|
||||||
}
|
}
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: server + "/api/send-sms-code",
|
url: server + "/app-api/send-sms-code",
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: JSON.stringify(data),
|
data: JSON.stringify(data),
|
||||||
contentType: "application/json;charset=utf-8",
|
contentType: "application/json;charset=utf-8",
|
@ -20,9 +20,7 @@ spring:
|
|||||||
write-durations-as-timestamps: true # 设置 Duration 的格式,使用时间戳
|
write-durations-as-timestamps: true # 设置 Duration 的格式,使用时间戳
|
||||||
fail-on-empty-beans: false # 允许序列化无属性的 Bean
|
fail-on-empty-beans: false # 允许序列化无属性的 Bean
|
||||||
|
|
||||||
# 静态资源
|
|
||||||
mvc:
|
|
||||||
static-path-pattern: /static/**
|
|
||||||
|
|
||||||
# MyBatis Plus 的配置项
|
# MyBatis Plus 的配置项
|
||||||
mybatis-plus:
|
mybatis-plus:
|
||||||
|
2
更新日志.md
2
更新日志.md
@ -26,6 +26,7 @@ TODO 待统计
|
|||||||
|
|
||||||
*【重构】大模块按照多 Maven Module 的方式拆分,提升可维护性,为后续重构 onemall 提供基础
|
*【重构】大模块按照多 Maven Module 的方式拆分,提升可维护性,为后续重构 onemall 提供基础
|
||||||
*【新增】Spring Security 支持读取多种用户类型,从不同的数据库表,从而实现单项目提供管理后台、用户 APP 的不同 RESTful API 接口
|
*【新增】Spring Security 支持读取多种用户类型,从不同的数据库表,从而实现单项目提供管理后台、用户 APP 的不同 RESTful API 接口
|
||||||
|
*【新增】Spring Security 新增 AuthorizeRequestsCustomizer 抽象类, 自定义每个 Maven Module 的 URL 的安全配置
|
||||||
*【新增】代码生成器支持多 Maven Module 的方式生成代码,支持管理后台、用户 APP 两种场景的 RESTful API 的生成,支持 H2 SQL 脚本的生成
|
*【新增】代码生成器支持多 Maven Module 的方式生成代码,支持管理后台、用户 APP 两种场景的 RESTful API 的生成,支持 H2 SQL 脚本的生成
|
||||||
*【重构】将数据库文档调整到 tool 模块,更加明确
|
*【重构】将数据库文档调整到 tool 模块,更加明确
|
||||||
*【优化】代码生成器的前端展示效果,例如说 Java 包路径合并
|
*【优化】代码生成器的前端展示效果,例如说 Java 包路径合并
|
||||||
@ -73,6 +74,7 @@ TODO 待统计
|
|||||||
|
|
||||||
* 【修复】biz-data-permission 组件的缓存机制,导致部分 SQL 未进行数据过滤
|
* 【修复】biz-data-permission 组件的缓存机制,导致部分 SQL 未进行数据过滤
|
||||||
* 【修复】codegen 生成代码时,delete 接口补充 dataTypeClass 属性,避免 Swagger 打印 WARN 日志
|
* 【修复】codegen 生成代码时,delete 接口补充 dataTypeClass 属性,避免 Swagger 打印 WARN 日志
|
||||||
|
* 【修复】Swagger 文档由于写错 `@ApiImplicitParam` 注解的 name 和 dataTypeClass 属性,导致文档生成失败
|
||||||
|
|
||||||
### 🔨 Dependency Upgrades
|
### 🔨 Dependency Upgrades
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user