修改用户名
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user