From a7fccc356f08bd4160d4c596c45710edecefd8c6 Mon Sep 17 00:00:00 2001 From: xgblack Date: Fri, 23 Feb 2024 09:58:44 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=F0=9F=93=9Adocs(README):=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 85dd7b1..8cf90c5 100644 --- a/README.md +++ b/README.md @@ -2,33 +2,39 @@

+

+

+ + + +

-#### planning -https://flowus.cn/xgblack/share/043ae88d-9444-4aa0-bf90-dcf0806e82f7 +## Planning +**CoolCode开发计划:== [开发计划](https://flowus.cn/xgblack/share/043ae88d-9444-4aa0-bf90-dcf0806e82f7) ==** -#### 介绍 +## 介绍 快速开发脚手架 -#### 软件架构 +## 软件架构 软件架构说明 -#### 安装教程 +## 安装教程 todo... -#### 使用说明 +## 使用说明 todo... -#### 参与贡献 +## 参与贡献 todo... -#### 特技 +## 特技 todo... -- Gitee From 5f0777baad56c3ca7774755e24b95a9190a00b75 Mon Sep 17 00:00:00 2001 From: xgblack Date: Fri, 23 Feb 2024 10:00:02 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=F0=9F=93=9Adocs(README):=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8cf90c5..d8aa18c 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ +

-

-- Gitee From e237b99f9a431ffc40f89a591dc8aed5101fddd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E5=85=89?= Date: Fri, 23 Feb 2024 10:42:58 +0800 Subject: [PATCH 3/8] Create main.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 墨菲安全代码安全扫描 --- .github/workflows/main.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..01f2201 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,32 @@ +name: "MurphySec代码扫描" +on: + push: + branches: + - develop +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout_Actions + uses: actions/checkout@v3 + - name: Install MurphySec code scan cli + run: | + wget -q https://s.murphysec.com/release/install.sh -O - | /bin/bash + - name: Code scan + run: murphysec scan . --token ${{ secrets.MURPHYSEC_TOKEN }} --json >scan_results.json + - name: Format data + run: | + wget https://s.murphysec.com/github_actions_format.py + python3 github_actions_format.py + - name: Check if file exists + run: | + if [ -f "results.sarif" ]; then + echo "file_exists=true" >> $GITHUB_ENV + else + echo "file_exists=false" >> $GITHUB_ENV + fi + - name: Upload SARIF file + if: env.file_exists == 'true' + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: results.sarif -- Gitee From d8df07618b897d1b41895f9cfe70e94f28d3256f Mon Sep 17 00:00:00 2001 From: xgblack Date: Fri, 23 Feb 2024 11:26:05 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=F0=9F=93=9Adocs(README):=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d8aa18c..50eb21e 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,15 @@

- - - - + + + +

- - +码匠君 + +

## Planning -- Gitee From f53b5aaa39542fdab3e62bb7dc30907a400e335d Mon Sep 17 00:00:00 2001 From: xgblack Date: Fri, 23 Feb 2024 11:39:15 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=F0=9F=93=9Adocs(README):=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 50eb21e..bf1f76a 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ +

码匠君 -- Gitee From a00e475d0fc955917982e1b60a4b9db0a780b025 Mon Sep 17 00:00:00 2001 From: xgblack Date: Fri, 23 Feb 2024 15:54:57 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E2=AC=86=EF=B8=8F(pom):=20=E5=8D=87?= =?UTF-8?q?=E7=BA=A7=20springboot=203.2.2->3.2.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- cool-dependencies/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index bf1f76a..1badf61 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

- +

diff --git a/cool-dependencies/pom.xml b/cool-dependencies/pom.xml index 13adae1..f392710 100644 --- a/cool-dependencies/pom.xml +++ b/cool-dependencies/pom.xml @@ -18,7 +18,7 @@ 1.0.0 - 3.2.2 + 3.2.3 8.3.0 1.2.21 diff --git a/pom.xml b/pom.xml index e5ad517..4d3dbae 100644 --- a/pom.xml +++ b/pom.xml @@ -51,10 +51,10 @@ ${java.version} UTF-8 - 3.2.2 + 3.2.3 3.2.5 3.12.1 - 0.10.0 + 0.10.1 1.18.30 -- Gitee From c8372fc46c629fae21d49f343bb8a40bba5104cb Mon Sep 17 00:00:00 2001 From: xgblack Date: Fri, 23 Feb 2024 15:57:17 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E2=9C=A8feat(jdbc):=20=E6=9B=B4=E6=8D=A2?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E8=BF=9E=E6=8E=A5=E6=B1=A0=E4=B8=BA?= =?UTF-8?q?spring=E5=86=85=E7=BD=AE=E7=9A=84Hikari=EF=BC=8C=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E4=BD=BF=E7=94=A8Druid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cool-dependencies/pom.xml | 7 --- .../pom.xml | 6 +- .../CoolDataSourceAutoConfiguration.java | 27 +-------- .../core/filter/DruidAdRemoveFilter.java | 38 ------------ .../support/handler/CoolLoginPreFilter.java | 1 + .../module/system/web/StudentController.java | 5 +- .../src/main/resources/application.yaml | 58 +++++-------------- 7 files changed, 24 insertions(+), 118 deletions(-) delete mode 100644 cool-framework/cool-spring-boot-starter-mybatis-flex/src/main/java/com/xgblack/cool/framework/datasource/core/filter/DruidAdRemoveFilter.java diff --git a/cool-dependencies/pom.xml b/cool-dependencies/pom.xml index f392710..f1b2a29 100644 --- a/cool-dependencies/pom.xml +++ b/cool-dependencies/pom.xml @@ -21,7 +21,6 @@ 3.2.3 8.3.0 - 1.2.21 1.7.9 3.0.3 33.0.0-jre @@ -148,12 +147,6 @@ mysql-connector-j ${mysql.version} - - - com.alibaba - druid-spring-boot-starter - ${druid-spring-boot.version} - org.mybatis mybatis-spring diff --git a/cool-framework/cool-spring-boot-starter-mybatis-flex/pom.xml b/cool-framework/cool-spring-boot-starter-mybatis-flex/pom.xml index 957efa4..08108b7 100644 --- a/cool-framework/cool-spring-boot-starter-mybatis-flex/pom.xml +++ b/cool-framework/cool-spring-boot-starter-mybatis-flex/pom.xml @@ -36,10 +36,10 @@ mybatis-flex-spring-boot3-starter - + - com.alibaba - druid-spring-boot-starter + com.zaxxer + HikariCP diff --git a/cool-framework/cool-spring-boot-starter-mybatis-flex/src/main/java/com/xgblack/cool/framework/datasource/config/CoolDataSourceAutoConfiguration.java b/cool-framework/cool-spring-boot-starter-mybatis-flex/src/main/java/com/xgblack/cool/framework/datasource/config/CoolDataSourceAutoConfiguration.java index 5ddfb53..1b0b3b4 100644 --- a/cool-framework/cool-spring-boot-starter-mybatis-flex/src/main/java/com/xgblack/cool/framework/datasource/config/CoolDataSourceAutoConfiguration.java +++ b/cool-framework/cool-spring-boot-starter-mybatis-flex/src/main/java/com/xgblack/cool/framework/datasource/config/CoolDataSourceAutoConfiguration.java @@ -1,41 +1,18 @@ package com.xgblack.cool.framework.datasource.config; -import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties; -import com.xgblack.cool.framework.datasource.core.filter.DruidAdRemoveFilter; import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.annotation.Bean; import org.springframework.transaction.annotation.EnableTransactionManagement; /** * 数据库配置类 * - * @author xg black + * @author xg black */ @AutoConfiguration @EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理 -@EnableConfigurationProperties(DruidStatProperties.class) public class CoolDataSourceAutoConfiguration { - /** - * 创建 DruidAdRemoveFilter 过滤器,过滤 common.js 的广告 - */ - @Bean - @ConditionalOnProperty(name = "spring.datasource.druid.web-stat-filter.enabled", havingValue = "true") - public FilterRegistrationBean druidAdRemoveFilterFilter(DruidStatProperties properties) { - // 获取 druid web 监控页面的参数 - DruidStatProperties.StatViewServlet config = properties.getStatViewServlet(); - // 提取 common.js 的配置路径 - String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*"; - String commonJsPattern = pattern.replaceAll("\\*", "js/common.js"); - // 创建 DruidAdRemoveFilter Bean - FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); - registrationBean.setFilter(new DruidAdRemoveFilter()); - registrationBean.addUrlPatterns(commonJsPattern); - return registrationBean; - } + } diff --git a/cool-framework/cool-spring-boot-starter-mybatis-flex/src/main/java/com/xgblack/cool/framework/datasource/core/filter/DruidAdRemoveFilter.java b/cool-framework/cool-spring-boot-starter-mybatis-flex/src/main/java/com/xgblack/cool/framework/datasource/core/filter/DruidAdRemoveFilter.java deleted file mode 100644 index f8206cb..0000000 --- a/cool-framework/cool-spring-boot-starter-mybatis-flex/src/main/java/com/xgblack/cool/framework/datasource/core/filter/DruidAdRemoveFilter.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.xgblack.cool.framework.datasource.core.filter; - -import com.alibaba.druid.util.Utils; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.springframework.web.filter.OncePerRequestFilter; - -import java.io.IOException; - -/** - * Druid 底部广告过滤器 - * - * @author 芋道源码 - */ -public class DruidAdRemoveFilter extends OncePerRequestFilter { - - /** - * common.js 的路径 - */ - private static final String COMMON_JS_ILE_PATH = "support/http/resources/js/common.js"; - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) - throws ServletException, IOException { - chain.doFilter(request, response); - // 重置缓冲区,响应头不会被重置 - response.resetBuffer(); - // 获取 common.js - String text = Utils.readFromResource(COMMON_JS_ILE_PATH); - // 正则替换 banner, 除去底部的广告信息 - text = text.replaceAll("
", ""); - text = text.replaceAll("powered.*?shrek.wang", ""); - response.getWriter().write(text); - } - -} diff --git a/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/support/handler/CoolLoginPreFilter.java b/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/support/handler/CoolLoginPreFilter.java index 71733da..ee029d9 100644 --- a/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/support/handler/CoolLoginPreFilter.java +++ b/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/support/handler/CoolLoginPreFilter.java @@ -51,6 +51,7 @@ public class CoolLoginPreFilter extends OncePerRequestFilter { } // 客户端配置跳过验证码 TODO: 验证码相关逻辑 + log.info("验证码相关逻辑"); /*boolean isIgnoreClient = ignoreClients.contains(WebUtils.getClientId()); if (isIgnoreClient) { filterChain.doFilter(request, response); diff --git a/cool-module-system/cool-module-system-adapter/src/main/java/com/xgblack/cool/module/system/web/StudentController.java b/cool-module-system/cool-module-system-adapter/src/main/java/com/xgblack/cool/module/system/web/StudentController.java index 14e4ec6..6e922c8 100644 --- a/cool-module-system/cool-module-system-adapter/src/main/java/com/xgblack/cool/module/system/web/StudentController.java +++ b/cool-module-system/cool-module-system-adapter/src/main/java/com/xgblack/cool/module/system/web/StudentController.java @@ -9,7 +9,6 @@ import com.xgblack.cool.module.system.dto.student.StudentPageQry; import com.xgblack.cool.module.system.dto.student.clientobject.StudentCO; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -50,7 +49,7 @@ public class StudentController { * 详情 * @return */ - @PreAuthorize("hasAuthority('SCOPE_Message')") + //@PreAuthorize("hasAuthority('SCOPE_Message')") @GetMapping("{id}") public StudentCO detail(@PathVariable Long id) { return studentService.getDetail(id); @@ -61,7 +60,7 @@ public class StudentController { * @param qry * @return */ - @PreAuthorize("hasAuthority('SCOPE_profile')") + //@PreAuthorize("hasAuthority('SCOPE_profile')") @GetMapping public PageResult page(StudentPageQry qry) { return studentService.getPage(qry); diff --git a/cool-server/src/main/resources/application.yaml b/cool-server/src/main/resources/application.yaml index bf70874..ce1ccf4 100644 --- a/cool-server/src/main/resources/application.yaml +++ b/cool-server/src/main/resources/application.yaml @@ -55,51 +55,25 @@ spring: max-request-size: 200MB # 设置总上传的文件大小 datasource: driver-class-name: com.mysql.cj.jdbc.Driver - type: com.alibaba.druid.pool.DruidDataSource +# type: com.zaxxer.hikari.HikariDataSource url: ${mysql.url:jdbc:mysql://localhost:3306/cool_code_server?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull} username: ${mysql.username:root} password: ${mysql.password:admin} - druid: - #初始化大小 - initialSize: 10 - #最小值 - minIdle: 8 - #最大值 - maxActive: 80 - #最大等待时间,配置获取连接等待超时,时间单位都是毫秒ms - maxWait: 6000 - #配置间隔多久才进行一次检测,检测需要关闭的空闲连接 - timeBetweenEvictionRunsMillis: 30000 - #配置一个连接在池中最小生存的时间 - minEvictableIdleTimeMillis: 300000 - validationQuery: SELECT 1 FROM DUAL - testWhileIdle: true - testOnBorrow: false - testOnReturn: false - poolPreparedStatements: true - # 配置监控统计拦截的filters,去掉后监控界面sql无法统计, - #'wall'用于防火墙,SpringBoot中没有log4j,我改成了log4j2 - filters: stat,wall,log4j2 - #最大PSCache连接 - maxPoolPreparedStatementPerConnectionSize: 20 - useGlobalDataSourceStat: true - # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 - connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500 - # 配置StatFilter - web-stat-filter: - #默认为false,设置为true启动 - enabled: true - url-pattern: "/*" - exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*" - #配置StatViewServlet - stat-view-servlet: - url-pattern: "/druid/*" - login-username: admin - login-password: admin123 - #是否可以重置 - reset-enable: true - #启用 - enabled: true + hikari: + # 最大连接池数量 + maximum-pool-size: 20 + # 最小空闲线程数量 + minimum-idle: 10 + # 配置获取连接等待超时的时间 + connection-timeout: 30000 + # 校验超时时间 + validation-timeout: 5000 + # 空闲连接存活最大时间,默认10分钟 + idle-timeout: 600000 + # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟 + max-lifetime: 1800000 + # 多久检查一次连接的活性 + keep-alive-time: 30000 jackson: date-format: yyyy-MM-dd HH:mm:ss locale: zh_CN -- Gitee From ed876c4fb6e712bf19c1cdf6c3c5dbf81b50b360 Mon Sep 17 00:00:00 2001 From: xgblack Date: Sat, 24 Feb 2024 22:59:46 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E2=9C=A8feat(auth):=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=20=E8=AE=A4=E8=AF=81=E6=8E=88=E6=9D=83=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E5=8F=82=E6=95=B0=E6=96=B9=E5=BC=8F=E4=B8=BA?= =?UTF-8?q?form-data?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 官方认为参数传递是不安全的,所以spring-boot自3.2.1版本起,需要使用form-data方式传参,参考https://github.com/spring-projects/spring-authorization-server/issues/1451 --- .../endpoint/CoolTokenEndpoint.java | 4 ++-- ...sourceOwnerBaseAuthenticationConverter.java | 8 ++++---- .../MobileGrantAuthenticationConverter.java | 6 +++--- .../PasswordGrantAuthenticationConverter.java | 8 ++++---- .../component/CoolBearerTokenExtractor.java | 3 +-- ...Utils.java => CoolOAuth2EndpointUtils.java} | 18 +++++++++++++----- 6 files changed, 27 insertions(+), 20 deletions(-) rename cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/utils/{OAuth2EndpointUtils.java => CoolOAuth2EndpointUtils.java} (81%) diff --git a/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/endpoint/CoolTokenEndpoint.java b/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/endpoint/CoolTokenEndpoint.java index 48422bc..c477ebf 100644 --- a/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/endpoint/CoolTokenEndpoint.java +++ b/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/endpoint/CoolTokenEndpoint.java @@ -3,7 +3,7 @@ package com.xgblack.cool.framework.security.core.authentication.endpoint; import com.xgblack.cool.framework.common.constants.CacheConstants; import com.xgblack.cool.framework.security.annotation.Inner; import com.xgblack.cool.framework.security.core.authentication.support.handler.CoolAuthenticationFailureEventHandler; -import com.xgblack.cool.framework.security.core.utils.OAuth2EndpointUtils; +import com.xgblack.cool.framework.security.core.utils.CoolOAuth2EndpointUtils; import com.xgblack.cool.framework.security.core.utils.OAuth2ErrorCodesExpand; import com.xgblack.cool.framework.security.service.RemoteClientDetailsService; import jakarta.servlet.http.HttpServletRequest; @@ -128,7 +128,7 @@ public class CoolTokenEndpoint { } Map claims = authorization.getAccessToken().getClaims(); - OAuth2AccessTokenResponse sendAccessTokenResponse = OAuth2EndpointUtils.sendAccessTokenResponse(authorization, claims); + OAuth2AccessTokenResponse sendAccessTokenResponse = CoolOAuth2EndpointUtils.sendAccessTokenResponse(authorization, claims); this.accessTokenHttpResponseConverter.write(sendAccessTokenResponse, MediaType.APPLICATION_JSON, httpResponse); } diff --git a/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/support/base/OAuth2ResourceOwnerBaseAuthenticationConverter.java b/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/support/base/OAuth2ResourceOwnerBaseAuthenticationConverter.java index 20d02b4..7dbf225 100644 --- a/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/support/base/OAuth2ResourceOwnerBaseAuthenticationConverter.java +++ b/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/support/base/OAuth2ResourceOwnerBaseAuthenticationConverter.java @@ -1,6 +1,6 @@ package com.xgblack.cool.framework.security.core.authentication.support.base; -import com.xgblack.cool.framework.security.core.utils.OAuth2EndpointUtils; +import com.xgblack.cool.framework.security.core.utils.CoolOAuth2EndpointUtils; import jakarta.servlet.http.HttpServletRequest; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; @@ -56,11 +56,11 @@ public abstract class OAuth2ResourceOwnerBaseAuthenticationConverter parameters = OAuth2EndpointUtils.getParameters(request); + MultiValueMap parameters = CoolOAuth2EndpointUtils.getParameters(request); // scope (OPTIONAL) String scope = parameters.getFirst(OAuth2ParameterNames.SCOPE); if (StringUtils.hasText(scope) && parameters.get(OAuth2ParameterNames.SCOPE).size() != 1) { - OAuth2EndpointUtils.throwError(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.SCOPE, OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI); + CoolOAuth2EndpointUtils.throwError(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.SCOPE, CoolOAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI); } Set requestedScopes = null; @@ -74,7 +74,7 @@ public abstract class OAuth2ResourceOwnerBaseAuthenticationConverter parameters = OAuth2EndpointUtils.getParameters(request); + MultiValueMap parameters = CoolOAuth2EndpointUtils.getParameters(request); // PHONE (REQUIRED) String phone = parameters.getFirst(SecurityConstants.SMS_PARAMETER_NAME); if (!StringUtils.hasText(phone) || parameters.get(SecurityConstants.SMS_PARAMETER_NAME).size() != 1) { - OAuth2EndpointUtils.throwError(OAuth2ErrorCodes.INVALID_REQUEST, SecurityConstants.SMS_PARAMETER_NAME, OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI); + CoolOAuth2EndpointUtils.throwError(OAuth2ErrorCodes.INVALID_REQUEST, SecurityConstants.SMS_PARAMETER_NAME, CoolOAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI); } } diff --git a/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/support/password/PasswordGrantAuthenticationConverter.java b/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/support/password/PasswordGrantAuthenticationConverter.java index 600b385..dbcef8d 100644 --- a/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/support/password/PasswordGrantAuthenticationConverter.java +++ b/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/authentication/support/password/PasswordGrantAuthenticationConverter.java @@ -1,7 +1,7 @@ package com.xgblack.cool.framework.security.core.authentication.support.password; import com.xgblack.cool.framework.security.core.authentication.support.base.OAuth2ResourceOwnerBaseAuthenticationConverter; -import com.xgblack.cool.framework.security.core.utils.OAuth2EndpointUtils; +import com.xgblack.cool.framework.security.core.utils.CoolOAuth2EndpointUtils; import jakarta.servlet.http.HttpServletRequest; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.core.AuthorizationGrantType; @@ -43,17 +43,17 @@ public class PasswordGrantAuthenticationConverter extends OAuth2ResourceOwnerBas */ @Override public void checkParams(HttpServletRequest request) { - MultiValueMap parameters = OAuth2EndpointUtils.getParameters(request); + MultiValueMap parameters = CoolOAuth2EndpointUtils.getParameters(request); // username (REQUIRED) String username = parameters.getFirst(OAuth2ParameterNames.USERNAME); if (!StringUtils.hasText(username) || parameters.get(OAuth2ParameterNames.USERNAME).size() != 1) { - OAuth2EndpointUtils.throwError(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.USERNAME, OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI); + CoolOAuth2EndpointUtils.throwError(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.USERNAME, CoolOAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI); } // password (REQUIRED) String password = parameters.getFirst(OAuth2ParameterNames.PASSWORD); if (!StringUtils.hasText(password) || parameters.get(OAuth2ParameterNames.PASSWORD).size() != 1) { - OAuth2EndpointUtils.throwError(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.PASSWORD, OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI); + CoolOAuth2EndpointUtils.throwError(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.PASSWORD, CoolOAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI); } } diff --git a/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/component/CoolBearerTokenExtractor.java b/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/component/CoolBearerTokenExtractor.java index a1d47a1..02e4814 100644 --- a/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/component/CoolBearerTokenExtractor.java +++ b/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/component/CoolBearerTokenExtractor.java @@ -21,8 +21,7 @@ import java.util.regex.Pattern; public class CoolBearerTokenExtractor implements BearerTokenResolver { - private static final Pattern authorizationPattern = Pattern.compile("^Bearer (?[a-zA-Z0-9-:._~+/]+=*)$", - Pattern.CASE_INSENSITIVE); + private static final Pattern authorizationPattern = Pattern.compile("^Bearer (?[a-zA-Z0-9-:._~+/]+=*)$", Pattern.CASE_INSENSITIVE); private boolean allowFormEncodedBodyParameter = false; diff --git a/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/utils/OAuth2EndpointUtils.java b/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/utils/CoolOAuth2EndpointUtils.java similarity index 81% rename from cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/utils/OAuth2EndpointUtils.java rename to cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/utils/CoolOAuth2EndpointUtils.java index ce0a7c7..2cc195c 100644 --- a/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/utils/OAuth2EndpointUtils.java +++ b/cool-framework/cool-spring-boot-starter-security/src/main/java/com/xgblack/cool/framework/security/core/utils/CoolOAuth2EndpointUtils.java @@ -1,8 +1,8 @@ package com.xgblack.cool.framework.security.core.utils; -import org.dromara.hutool.core.map.MapUtil; import jakarta.servlet.http.HttpServletRequest; import lombok.experimental.UtilityClass; +import org.dromara.hutool.core.map.MapUtil; import org.springframework.security.oauth2.core.*; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; @@ -10,6 +10,7 @@ import org.springframework.security.oauth2.core.endpoint.PkceParameterNames; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; import java.io.IOException; import java.time.temporal.ChronoUnit; @@ -21,21 +22,28 @@ import java.util.Map; */ @UtilityClass -public class OAuth2EndpointUtils { +public class CoolOAuth2EndpointUtils { public final String ACCESS_TOKEN_REQUEST_ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2"; /** * 解析Http请求参数 + *

认证方式同spring官方方式修改,认证方式改为form-data,不再支持query parameter, + * 自spring-boot3.2.1版本起修改,参见{@link org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2EndpointUtils#getFormParameters(HttpServletRequest)}

+ * * @param request * @return */ public MultiValueMap getParameters(HttpServletRequest request) { Map parameterMap = request.getParameterMap(); - MultiValueMap parameters = new LinkedMultiValueMap<>(parameterMap.size()); + MultiValueMap parameters = new LinkedMultiValueMap<>(); parameterMap.forEach((key, values) -> { - for (String value : values) { - parameters.add(key, value); + String queryString = StringUtils.hasText(request.getQueryString()) ? request.getQueryString() : ""; + // If not query parameter then it's a form parameter + if (!queryString.contains(key) && values.length > 0) { + for (String value : values) { + parameters.add(key, value); + } } }); return parameters; -- Gitee