Commit c2ccfa3bd6c7acb8096c2e7dbdc0a08289804b71
1 parent
4890cf05
多模块重构 12:【新增】Spring Security 新增 AuthorizeRequestsCustomizer 抽象类, 自定义每个 Maven Module 的 URL 的安全配置
Showing
33 changed files
with
212 additions
and
137 deletions
http-client.env.json
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 | 26 | |
| 27 | 27 | import javax.annotation.Resource; |
| 28 | 28 | import javax.servlet.http.HttpServletRequest; |
| 29 | +import java.util.List; | |
| 30 | +import java.util.function.Consumer; | |
| 29 | 31 | |
| 30 | 32 | /** |
| 31 | 33 | * 自定义的 Spring Security 配置适配器实现 |
| ... | ... | @@ -62,14 +64,22 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap |
| 62 | 64 | @Resource |
| 63 | 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 | 79 | * @see #configure(HttpSecurity) |
| 69 | 80 | */ |
| 70 | 81 | @Resource |
| 71 | - private Customizer<ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry> | |
| 72 | - authorizeRequestsCustomizer; | |
| 82 | + private List<AuthorizeRequestsCustomizer> authorizeRequestsCustomizers; | |
| 73 | 83 | |
| 74 | 84 | /** |
| 75 | 85 | * 由于 Spring Security 创建 AuthenticationManager 对象时,没声明 @Bean 注解,导致无法被注入 |
| ... | ... | @@ -126,44 +136,31 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap |
| 126 | 136 | StrUtil.equalsAny(request.getRequestURI(), buildAdminApi("/system/logout"), |
| 127 | 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 | 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 | 155 | // 添加 JWT Filter |
| 157 | 156 | httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); |
| 158 | 157 | } |
| 159 | 158 | |
| 160 | 159 | private String buildAdminApi(String url) { |
| 161 | - // TODO 芋艿:多模块 | |
| 162 | 160 | return webProperties.getAdminApi().getPrefix() + url; |
| 163 | 161 | } |
| 164 | 162 | |
| 165 | 163 | private String buildAppApi(String url) { |
| 166 | - // TODO 芋艿:多模块 | |
| 167 | 164 | return webProperties.getAppApi().getPrefix() + url; |
| 168 | 165 | } |
| 169 | 166 | ... | ... |
yudao-module-infra/yudao-module-infra-impl/pom.xml
| ... | ... | @@ -90,6 +90,17 @@ |
| 90 | 90 | <groupId>cn.smallbun.screw</groupId> |
| 91 | 91 | <artifactId>screw-core</artifactId> <!-- 实现数据库文档 --> |
| 92 | 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 | 104 | </dependencies> |
| 94 | 105 | |
| 95 | 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
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
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
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/package-info.java deleted
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 | 202 | if (user != null) { |
| 203 | 203 | reqDTO.setUserId(user.getId()); |
| 204 | 204 | } |
| 205 | + reqDTO.setUserType(getUserType().getValue()); | |
| 205 | 206 | reqDTO.setUsername(mobile); |
| 206 | 207 | reqDTO.setUserAgent(ServletUtils.getUserAgent()); |
| 207 | 208 | reqDTO.setUserIp(getClientIP()); | ... | ... |
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/LoginLogCreateReqDTO.java
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
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 | 164 | if (user != null) { |
| 165 | 165 | reqDTO.setUserId(user.getId()); |
| 166 | 166 | } |
| 167 | - reqDTO.setUserType(UserTypeEnum.ADMIN.getValue()); | |
| 167 | + reqDTO.setUserType(getUserType().getValue()); | |
| 168 | 168 | reqDTO.setUsername(username); |
| 169 | 169 | reqDTO.setUserAgent(ServletUtils.getUserAgent()); |
| 170 | 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 | 8 | import cn.iocoder.yudao.module.system.dal.dataobject.logger.LoginLogDO; |
| 9 | 9 | import cn.iocoder.yudao.module.system.dal.mysql.logger.LoginLogMapper; |
| 10 | 10 | import org.springframework.stereotype.Service; |
| 11 | +import org.springframework.validation.annotation.Validated; | |
| 11 | 12 | |
| 12 | 13 | import javax.annotation.Resource; |
| 13 | 14 | import java.util.List; |
| ... | ... | @@ -16,6 +17,7 @@ import java.util.List; |
| 16 | 17 | * 登录日志 Service 实现 |
| 17 | 18 | */ |
| 18 | 19 | @Service |
| 20 | +@Validated | |
| 19 | 21 | public class LoginLogServiceImpl implements LoginLogService { |
| 20 | 22 | |
| 21 | 23 | @Resource | ... | ... |
yudao-server/pom.xml
| ... | ... | @@ -67,17 +67,6 @@ |
| 67 | 67 | <artifactId>yudao-spring-boot-starter-protection</artifactId> |
| 68 | 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 | 70 | </dependencies> |
| 82 | 71 | |
| 83 | 72 | <build> | ... | ... |
yudao-server/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/package-info.java
0 → 100644
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 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 9 | 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 | 11 | import io.swagger.annotations.Api; |
| 12 | 12 | import io.swagger.annotations.ApiOperation; |
| 13 | 13 | import lombok.extern.slf4j.Slf4j; |
| ... | ... | @@ -24,20 +24,20 @@ import java.time.Duration; |
| 24 | 24 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 25 | 25 | import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; |
| 26 | 26 | |
| 27 | -@Api(tags = "商城订单") | |
| 27 | +@Api(tags = "用户 APP - 商城订单") | |
| 28 | 28 | @RestController |
| 29 | 29 | @RequestMapping("/shop/order") |
| 30 | 30 | @Validated |
| 31 | 31 | @Slf4j |
| 32 | -public class ShopOrderController { | |
| 32 | +public class AppShopOrderController { | |
| 33 | 33 | |
| 34 | 34 | @Resource |
| 35 | - private PayOrderCoreService payOrderCoreService; | |
| 35 | + private PayOrderService payOrderService; | |
| 36 | 36 | |
| 37 | 37 | @PostMapping("/create") |
| 38 | 38 | @ApiOperation("创建商城订单") |
| 39 | 39 | // @PreAuthenticated // TODO 暂时不加登陆验证,前端暂时没做好 |
| 40 | - public CommonResult<ShopOrderCreateRespVO> create() { | |
| 40 | + public CommonResult<AppShopOrderCreateRespVO> create() { | |
| 41 | 41 | // 假装创建商城订单 |
| 42 | 42 | Long shopOrderId = System.currentTimeMillis(); |
| 43 | 43 | |
| ... | ... | @@ -50,10 +50,10 @@ public class ShopOrderController { |
| 50 | 50 | reqDTO.setBody("内容:" + shopOrderId); |
| 51 | 51 | reqDTO.setAmount(200); // 单位:分 |
| 52 | 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 | 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 | 3 | import io.swagger.annotations.ApiModel; |
| 4 | 4 | import io.swagger.annotations.ApiModelProperty; |
| ... | ... | @@ -6,11 +6,11 @@ import lombok.AllArgsConstructor; |
| 6 | 6 | import lombok.Builder; |
| 7 | 7 | import lombok.Data; |
| 8 | 8 | |
| 9 | -@ApiModel("商城订单创建 Response VO") | |
| 9 | +@ApiModel("用户 APP - 商城订单创建 Response VO") | |
| 10 | 10 | @Data |
| 11 | 11 | @Builder |
| 12 | 12 | @AllArgsConstructor |
| 13 | -public class ShopOrderCreateRespVO { | |
| 13 | +public class AppShopOrderCreateRespVO { | |
| 14 | 14 | |
| 15 | 15 | @ApiModelProperty(value = "商城订单编号", required = true, example = "1024") |
| 16 | 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
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 | 20 | write-durations-as-timestamps: true # 设置 Duration 的格式,使用时间戳 |
| 21 | 21 | fail-on-empty-beans: false # 允许序列化无属性的 Bean |
| 22 | 22 | |
| 23 | + # 静态资源 | |
| 24 | + mvc: | |
| 25 | + static-path-pattern: /static/** | |
| 26 | + | |
| 23 | 27 | # 工作流 Activiti 配置 |
| 24 | 28 | activiti: |
| 25 | 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 | 24 | <script> |
| 25 | 25 | let shopOrderId = undefined; |
| 26 | 26 | let payOrderId = undefined; |
| 27 | - let server = 'http://127.0.0.1:28080'; | |
| 27 | + let server = 'http://127.0.0.1:48080'; | |
| 28 | 28 | $(function() { |
| 29 | 29 | // 自动发起商城订单编号 |
| 30 | 30 | $.ajax({ |
| 31 | - url: server + "/api/shop/order/create", | |
| 31 | + url: server + "/app-api/shop/order/create", | |
| 32 | 32 | method: 'POST', |
| 33 | 33 | success: function( result ) { |
| 34 | 34 | if (result.code !== 0) { |
| ... | ... | @@ -46,7 +46,7 @@ |
| 46 | 46 | $( "#alipay_wap").on( "click", function() { |
| 47 | 47 | // 提交支付 |
| 48 | 48 | $.ajax({ |
| 49 | - url: server + "/api/pay/order/submit", | |
| 49 | + url: server + "/app-api/pay/order/submit", | |
| 50 | 50 | method: 'POST', |
| 51 | 51 | dataType: "json", |
| 52 | 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 | 17 | |
| 18 | 18 | let shopOrderId = undefined; |
| 19 | 19 | let payOrderId = undefined; |
| 20 | - let server = 'http://127.0.0.1:28080'; | |
| 20 | + let server = 'http://127.0.0.1:48080'; | |
| 21 | 21 | //let server = 'http://niubi.natapp1.cc'; |
| 22 | 22 | |
| 23 | 23 | $(function() { |
| 24 | 24 | // 自动发起商城订单编号 |
| 25 | 25 | $.ajax({ |
| 26 | - url: server + "/api/shop/order/create", | |
| 26 | + url: server + "/app-api/shop/order/create", | |
| 27 | 27 | method: 'POST', |
| 28 | 28 | success: function( result ) { |
| 29 | 29 | if (result.code !== 0) { |
| ... | ... | @@ -41,7 +41,7 @@ |
| 41 | 41 | $( "#alipay_wap").on( "click", function() { |
| 42 | 42 | // 提交支付 |
| 43 | 43 | $.ajax({ |
| 44 | - url: server + "/api/pay/order/submit", | |
| 44 | + url: server + "/app-api/pay/order/submit", | |
| 45 | 45 | method: 'POST', |
| 46 | 46 | dataType: "json", |
| 47 | 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 | 16 | <script> |
| 17 | 17 | let shopOrderId = undefined; |
| 18 | 18 | let payOrderId = undefined; |
| 19 | - // let server = 'http://127.0.0.1:28080'; | |
| 19 | + // let server = 'http://127.0.0.1:48080'; | |
| 20 | 20 | let server = 'http://niubi.natapp1.cc'; |
| 21 | 21 | // TODO openid |
| 22 | 22 | let openid = "ockUAwIZ-0OeMZl9ogcZ4ILrGba0"; |
| ... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | // 获得 JsapiTicket |
| 25 | 25 | // 参考 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 文档 |
| 26 | 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 | 28 | method: 'POST', |
| 29 | 29 | success: function( result ) { |
| 30 | 30 | if (result.code !== 0) { |
| ... | ... | @@ -42,7 +42,7 @@ |
| 42 | 42 | |
| 43 | 43 | // 自动发起商城订单编号 |
| 44 | 44 | $.ajax({ |
| 45 | - url: server + "/api/shop/order/create", | |
| 45 | + url: server + "/app-api/shop/order/create", | |
| 46 | 46 | method: 'POST', |
| 47 | 47 | success: function( result ) { |
| 48 | 48 | if (result.code !== 0) { |
| ... | ... | @@ -78,7 +78,7 @@ |
| 78 | 78 | // 参考 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6 文档 |
| 79 | 79 | // 参考 https://segmentfault.com/a/1190000020704650 文档 |
| 80 | 80 | $.ajax({ |
| 81 | - url: server + "/api/pay/order/submit", | |
| 81 | + url: server + "/app-api/pay/order/submit", | |
| 82 | 82 | method: 'POST', |
| 83 | 83 | dataType: "json", |
| 84 | 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 | </body> |
| 15 | 15 | <script> |
| 16 | 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 | 21 | $( "#wx_pub").on( "click", function() { |
| 22 | 22 | // 获得授权链接 |
| 23 | 23 | $.ajax({ |
| 24 | - url: server + "/api/social-auth-redirect?type=31&redirectUri=" + | |
| 24 | + url: server + "/app-api/social-auth-redirect?type=31&redirectUri=" + | |
| 25 | 25 | encodeURIComponent(server + '/static/social-login2.html'), //重定向地址 |
| 26 | 26 | method: 'GET', |
| 27 | 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 | 17 | </div> |
| 18 | 18 | </body> |
| 19 | 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 | 23 | let type = 31; //登录类型 微信公众号 |
| 24 | 24 | |
| ... | ... | @@ -38,7 +38,7 @@ |
| 38 | 38 | |
| 39 | 39 | // 调用授权登录接口 |
| 40 | 40 | $.ajax({ |
| 41 | - url: server + "/api/social-login2", | |
| 41 | + url: server + "/app-api/social-login2", | |
| 42 | 42 | method: 'POST', |
| 43 | 43 | data: JSON.stringify(data), |
| 44 | 44 | contentType: "application/json;charset=utf-8", |
| ... | ... | @@ -60,7 +60,7 @@ |
| 60 | 60 | 'scene': 1 // 手机号登陆 类型 |
| 61 | 61 | } |
| 62 | 62 | $.ajax({ |
| 63 | - url: server + "/api/send-sms-code", | |
| 63 | + url: server + "/app-api/send-sms-code", | |
| 64 | 64 | method: 'POST', |
| 65 | 65 | data: JSON.stringify(data), |
| 66 | 66 | contentType: "application/json;charset=utf-8", | ... | ... |
yudao-user-server/src/main/resources/application.yaml
更新日志.md
| ... | ... | @@ -26,6 +26,7 @@ TODO 待统计 |
| 26 | 26 | |
| 27 | 27 | *【重构】大模块按照多 Maven Module 的方式拆分,提升可维护性,为后续重构 onemall 提供基础 |
| 28 | 28 | *【新增】Spring Security 支持读取多种用户类型,从不同的数据库表,从而实现单项目提供管理后台、用户 APP 的不同 RESTful API 接口 |
| 29 | +*【新增】Spring Security 新增 AuthorizeRequestsCustomizer 抽象类, 自定义每个 Maven Module 的 URL 的安全配置 | |
| 29 | 30 | *【新增】代码生成器支持多 Maven Module 的方式生成代码,支持管理后台、用户 APP 两种场景的 RESTful API 的生成,支持 H2 SQL 脚本的生成 |
| 30 | 31 | *【重构】将数据库文档调整到 tool 模块,更加明确 |
| 31 | 32 | *【优化】代码生成器的前端展示效果,例如说 Java 包路径合并 |
| ... | ... | @@ -73,6 +74,7 @@ TODO 待统计 |
| 73 | 74 | |
| 74 | 75 | * 【修复】biz-data-permission 组件的缓存机制,导致部分 SQL 未进行数据过滤 |
| 75 | 76 | * 【修复】codegen 生成代码时,delete 接口补充 dataTypeClass 属性,避免 Swagger 打印 WARN 日志 |
| 77 | +* 【修复】Swagger 文档由于写错 `@ApiImplicitParam` 注解的 name 和 dataTypeClass 属性,导致文档生成失败 | |
| 76 | 78 | |
| 77 | 79 | ### 🔨 Dependency Upgrades |
| 78 | 80 | ... | ... |