修改用户名

This commit is contained in:
wangjianhong
2025-07-24 10:46:10 +08:00
parent 8382cbe0c3
commit c29abb1b83
5 changed files with 141 additions and 32 deletions

View File

@@ -0,0 +1,35 @@
package com.arrokoth.standalone.authorization.controller;
import com.arrokoth.basic.properties.SecurityWebProperties;
import com.arrokoth.basic.request.LoginRequest;
import com.arrokoth.basic.response.Token;
import com.arrokoth.basic.service.AuthorizationService;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping
@RestController
@RequiredArgsConstructor
public class LoginController {
private final AuthorizationService authorizationService;
private final AuthenticationManager authenticationManager;
@Operation(summary = "登录", description = "获取登录Token信息")
@PostMapping(SecurityWebProperties.AXIOS_LOGIN_PROCESSING_URL)
public Token homeLogin(@Valid @RequestBody LoginRequest loginRequest) {
UsernamePasswordAuthenticationToken passwordAuthenticationToken = new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword());
Authentication authenticate = authenticationManager.authenticate(passwordAuthenticationToken);
SecurityContextHolder.getContext().setAuthentication(authenticate);
return authorizationService.login(loginRequest);
}
}

View File

@@ -7,6 +7,7 @@ import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
@@ -15,8 +16,9 @@ import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.Enumeration;
@Slf4j
@Component
@RequiredArgsConstructor
public class JwtRequestFilter extends OncePerRequestFilter {
@@ -26,47 +28,119 @@ public class JwtRequestFilter extends OncePerRequestFilter {
private final RedisTokenService redisTokenService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization");
logRequestDetails(request);
try {
String jwt = extractJwtFromRequest(request);
if (jwt == null) {
chain.doFilter(request, response);
return;
}
String username = extractUsernameFromToken(jwt);
if (username == null) {
chain.doFilter(request, response);
return;
}
if (isTokenBlacklisted(jwt, response)) {
return;
}
if (isUserNotAuthenticated(username)) {
authenticateUser(jwt, username);
}
chain.doFilter(request, response);
} catch (Exception ex) {
logger.warn("Error occurred during JWT filter processing", ex);
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
private String extractJwtFromRequest(HttpServletRequest request) {
String jwt = null;
String username = null;
// 1. 先从 Authorization Header 中提取
String authorizationHeader = request.getHeader("Authorization");
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
jwt = authorizationHeader.substring(7);
try {
username = JwtUtils.extractUsername(jwt);
} catch (Exception e) {
logger.warn("Failed to extract username from token");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid token");
return;
}
}
// 2. 如果 Header 中没有,则尝试从 URL 参数中获取(如 X-Token
if (jwt == null || jwt.isEmpty()) {
jwt = request.getParameter("X-Token");
}
return jwt;
}
private String extractUsernameFromToken(String jwt) {
try {
return JwtUtils.extractUsername(jwt);
} catch (Exception e) {
logger.warn("Failed to extract username from token", e);
throw new RuntimeException("Failed to extract username from token");
}
}
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;
}
private boolean isUserNotAuthenticated(String username) {
return SecurityContextHolder.getContext().getAuthentication() == null ||
!SecurityContextHolder.getContext().getAuthentication().isAuthenticated() ||
!SecurityContextHolder.getContext().getAuthentication().getName().equals(username);
}
private void authenticateUser(String jwt, String username) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (JwtUtils.validateToken(jwt, userDetails.getUsername())) {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
} else {
// 没有 token继续链可能是登录接口等不需要认证的路径
chain.doFilter(request, response);
return;
throw new RuntimeException("Token is expired or invalid");
}
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
if (redisTokenService.isBlacklisted(jwt)) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token is blacklisted");
return;
}
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (JwtUtils.validateToken(jwt, userDetails.getUsername())) {
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
} else {
// token 无效或已过期
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token is expired or invalid");
return;
/**
* 封装的打印请求详情方法
*/
private void logRequestDetails(HttpServletRequest request) {
String requestURL = request.getRequestURL().toString();
String queryString = request.getQueryString();
// 打印基本信息
if (log.isInfoEnabled()) {
log.info("Request URL: {}", requestURL);
if (queryString != null) {
log.info("Query Parameters: {}", queryString);
}
}
chain.doFilter(request, response);
// 打印参数GET/POST 通用)
Enumeration<String> paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) {
String paramName = paramNames.nextElement();
String[] paramValues = request.getParameterValues(paramName);
for (String value : paramValues) {
log.debug("Request Param: {} = {}", paramName, value);
}
}
}
}

View File

@@ -15,7 +15,7 @@ public class UserDetailsServiceStore {
@Bean
public UserDetailsService users(PasswordEncoder passwordEncoder) {
UserDetails user = User.withUsername("admin")
.password(passwordEncoder.encode("password"))
.password(passwordEncoder.encode("123456"))
.roles("admin", "normal")
.authorities("app", "web")
.build();

View File

@@ -62,7 +62,7 @@ logging:
root: INFO
com.arrokoth: DEBUG
org.springdoc: INFO
org.springframework: INFO
org.springframework: DEBUG
#mybatis:
# type-aliases-package: com.arrokoth.**.domain

View File

@@ -257,7 +257,7 @@
<div class="form-group">
<label for="password-input">密码</label>
<input id="password-input" name="password" placeholder="请输入密码" type="password"
value="password">
value="123456">
</div>
<div class="form-group" style="display: none">
<label for="pass-captcha-input">验证码</label>