From 417856b7beba498ae727b27ddfdd19bf783324d7 Mon Sep 17 00:00:00 2001
From: wangjianhong <546732225seven@gmail.com>
Date: Wed, 6 Aug 2025 15:54:19 +0800
Subject: [PATCH] no message
---
README.md | 15 ++
pom.xml | 10 +-
.../config/SecurityWebAutoConfigurer.java | 2 +-
.../filter/JwtRequestFilter.java | 130 +++++++++++-------
.../store/UserDetailsServiceStore.java | 10 +-
src/main/resources/application.yml | 2 +-
6 files changed, 108 insertions(+), 61 deletions(-)
create mode 100644 README.md
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..060cbfc
--- /dev/null
+++ b/README.md
@@ -0,0 +1,15 @@
+
+## Getting started
+
+##
+
+
+```
+
+mvn versions:display-dependency-updates
+
+mvn versions:update-properties
+
+mvn versions:set -DnewVersion=1.2.0.RELEASE
+```
+
diff --git a/pom.xml b/pom.xml
index 138b5f4..ac8a5d0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,12 +5,12 @@
org.springframework.boot
spring-boot-starter-parent
- 3.5.3
+ 4.0.0-M1
com.arrokoth
authorization-server-standalone
- 0.0.1-SNAPSHOT
+ 1.2.0.RELEASE
authorization-server-standalone
authorization-server-standalone
@@ -34,8 +34,8 @@
17
3.5.3
- 1.1.0.RELEASE
- 1.1.0.RELEASE
+ 1.2.0.RELEASE
+ 1.2.0.RELEASE
@@ -50,7 +50,7 @@
com.arrokoth.framework
basic-authorization-server
- 1.0.1-RELEASE
+ 1.2.0.RELEASE
diff --git a/src/main/java/com/arrokoth/standalone/authorization/config/SecurityWebAutoConfigurer.java b/src/main/java/com/arrokoth/standalone/authorization/config/SecurityWebAutoConfigurer.java
index 61de936..c40e95e 100644
--- a/src/main/java/com/arrokoth/standalone/authorization/config/SecurityWebAutoConfigurer.java
+++ b/src/main/java/com/arrokoth/standalone/authorization/config/SecurityWebAutoConfigurer.java
@@ -50,7 +50,7 @@ public class SecurityWebAutoConfigurer {
.logout(logout -> logout
.logoutUrl(SecurityWebProperties.AXIOS_LOGOUT_PROCESSING_URL)
- .logoutSuccessUrl(securityWebProperties.getLogoutSuccessUrl())
+// .logoutSuccessUrl(securityWebProperties.getLogoutSuccessUrl())
.invalidateHttpSession(true) // 注销时销毁 session
.deleteCookies("JSESSIONID", "Authorization")
.permitAll()
diff --git a/src/main/java/com/arrokoth/standalone/authorization/filter/JwtRequestFilter.java b/src/main/java/com/arrokoth/standalone/authorization/filter/JwtRequestFilter.java
index 06696bc..c9b25e2 100644
--- a/src/main/java/com/arrokoth/standalone/authorization/filter/JwtRequestFilter.java
+++ b/src/main/java/com/arrokoth/standalone/authorization/filter/JwtRequestFilter.java
@@ -12,6 +12,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
@@ -28,92 +29,113 @@ public class JwtRequestFilter extends OncePerRequestFilter {
private final RedisTokenService redisTokenService;
@Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
-
- logRequestDetails(request);
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
+ throws ServletException, IOException {
try {
+ // 1. 提取 JWT Token
String jwt = extractJwtFromRequest(request);
if (jwt == null) {
chain.doFilter(request, response);
return;
}
- String username = extractUsernameFromToken(jwt);
- if (username == null) {
- chain.doFilter(request, response);
+ // 2. 解析用户名
+ String username = JwtUtils.extractUsername(jwt);
+ if (username == null || username.isBlank()) {
+ log.warn("JWT token does not contain a valid username: {}", maskToken(jwt));
+ sendUnauthorizedResponse(response, "Invalid token");
return;
}
- if (isTokenBlacklisted(jwt, response)) {
+ // 3. 检查 Token 是否被拉黑(退出登录状态)
+ if (redisTokenService.isBlacklisted(jwt)) {
+ log.warn("Token is blacklisted: {}", maskToken(jwt));
+ sendUnauthorizedResponse(response, "Token is blacklisted");
return;
}
+ // 4. 若用户未认证,则进行认证
if (isUserNotAuthenticated(username)) {
- authenticateUser(jwt, username);
+ authenticateUser(jwt, username, request);
}
+ // 5. 继续过滤链
chain.doFilter(request, response);
} catch (Exception ex) {
- logger.warn("Error occurred during JWT filter processing", ex);
- response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
+ log.warn("JWT filter processing failed for request: {}", request.getRequestURI(), ex);
+ sendUnauthorizedResponse(response, "Unauthorized: " + ex.getMessage());
}
}
-
+ /**
+ * 从请求中提取 JWT Token
+ */
private String extractJwtFromRequest(HttpServletRequest request) {
-
- String jwt = null;
-
- // 1. 先从 Authorization Header 中提取
- String authorizationHeader = request.getHeader("Authorization");
- if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
- jwt = authorizationHeader.substring(7);
+ // 优先从 Authorization: Bearer
+ String bearerToken = request.getHeader("Authorization");
+ if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
+ return bearerToken.substring(7).trim();
}
- // 2. 如果 Header 中没有,则尝试从 URL 参数中获取(如 X-Token)
- if (jwt == null || jwt.isEmpty()) {
- jwt = request.getParameter("X-Token");
+ // 其次尝试从 X-Token 参数获取(URL 或表单)
+ String tokenParam = request.getParameter("X-Token");
+ if (tokenParam != null && !tokenParam.isBlank()) {
+ return tokenParam.trim();
}
- return jwt;
- }
-
- private String extractUsernameFromToken(String jwt) {
- try {
- return JwtUtils.extractUsername(jwt);
- } catch (Exception e) {
- throw new RuntimeException(e.getMessage());
- }
- }
-
- private boolean isTokenBlacklisted(String jwt, HttpServletResponse response) throws IOException {
- if (redisTokenService.isBlacklisted(jwt)) {
- response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token is blacklisted");
- return true;
- }
- return false;
+ return null;
}
+ /**
+ * 判断当前上下文是否已认证为指定用户
+ */
private boolean isUserNotAuthenticated(String username) {
- return SecurityContextHolder.getContext().getAuthentication() == null ||
- !SecurityContextHolder.getContext().getAuthentication().isAuthenticated() ||
- !SecurityContextHolder.getContext().getAuthentication().getName().equals(username);
+ var authentication = SecurityContextHolder.getContext().getAuthentication();
+ return authentication == null
+ || !authentication.isAuthenticated()
+ || !username.equals(authentication.getName());
}
- private void authenticateUser(String jwt, String username) {
- UserDetails userDetails = userDetailsService.loadUserByUsername(username);
+ /**
+ * 对用户进行身份认证并设置 SecurityContext
+ */
+ private void authenticateUser(String jwt, String username, HttpServletRequest request) {
+ UserDetails userDetails;
+ try {
+ userDetails = userDetailsService.loadUserByUsername(username);
+ } catch (Exception e) {
+ log.warn("User not found during JWT authentication: {}", username);
+ throw new RuntimeException("Invalid token or user does not exist");
+ }
- if (JwtUtils.validateToken(jwt, userDetails.getUsername())) {
- UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
- userDetails, null, userDetails.getAuthorities());
- SecurityContextHolder.getContext().setAuthentication(authentication);
- } else {
+ if (!JwtUtils.validateToken(jwt, userDetails.getUsername())) {
+ log.warn("JWT token validation failed for user: {}", username);
throw new RuntimeException("Token is expired or invalid");
}
+
+ UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
+ userDetails, null, userDetails.getAuthorities());
+ authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ log.debug("Authenticated user: {} via JWT", username);
}
+ /**
+ * 发送 401 响应
+ */
+ private void sendUnauthorizedResponse(HttpServletResponse response, String message) throws IOException {
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED, message);
+ }
+
+ /**
+ * 日志脱敏:隐藏长 Token 的中间部分
+ */
+ private String maskToken(String token) {
+ if (token == null || token.length() <= 10) return token;
+ return token.substring(0, 5) + "..." + token.substring(token.length() - 5);
+ }
/**
* 封装的打印请求详情方法
@@ -123,10 +145,10 @@ public class JwtRequestFilter extends OncePerRequestFilter {
String queryString = request.getQueryString();
// 打印基本信息
- if (log.isInfoEnabled()) {
- log.info("Request URL: {}", requestURL);
+ if (log.isDebugEnabled()) {
+ log.debug("Request URL: {}", requestURL);
if (queryString != null) {
- log.info("Query Parameters: {}", queryString);
+ log.debug("Query Parameters: {}", queryString);
}
}
@@ -135,8 +157,10 @@ public class JwtRequestFilter extends OncePerRequestFilter {
while (paramNames.hasMoreElements()) {
String paramName = paramNames.nextElement();
String[] paramValues = request.getParameterValues(paramName);
- for (String value : paramValues) {
- log.debug("Request Param: {} = {}", paramName, value);
+ if (log.isDebugEnabled()) {
+ for (String value : paramValues) {
+ log.debug("Request Param: {} = {}", paramName, value);
+ }
}
}
}
diff --git a/src/main/java/com/arrokoth/standalone/authorization/store/UserDetailsServiceStore.java b/src/main/java/com/arrokoth/standalone/authorization/store/UserDetailsServiceStore.java
index 7076773..46a180a 100644
--- a/src/main/java/com/arrokoth/standalone/authorization/store/UserDetailsServiceStore.java
+++ b/src/main/java/com/arrokoth/standalone/authorization/store/UserDetailsServiceStore.java
@@ -19,7 +19,15 @@ public class UserDetailsServiceStore {
.roles("admin", "normal")
.authorities("app", "web")
.build();
- return new InMemoryUserDetailsManager(user);
+
+
+
+ UserDetails user2 = User.withUsername("guest")
+ .password(passwordEncoder.encode("yyds@8848"))
+ .roles("normal")
+ .authorities("app")
+ .build();
+ return new InMemoryUserDetailsManager(user,user2);
}
}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 9805174..cc54724 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -69,7 +69,7 @@ mybatis:
mapper-locations: classpath*:com.arrokoth/**/mapper/xml/*.xml
configuration:
map-underscore-to-camel-case: true
- log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mybatis-plus:
type-aliases-package: com.arrokoth.**.domain
mapper-locations: classpath*:com.arrokoth/**/mapper/xml/*.xml