Commit c2ccfa3bd6c7acb8096c2e7dbdc0a08289804b71

Authored by YunaiV
1 parent 4890cf05

多模块重构 12:【新增】Spring Security 新增 AuthorizeRequestsCustomizer 抽象类, 自定义每个 Maven Module 的 URL 的安全配置

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