刘帅
2026-09-21 3f45e8fdfa31d7b764d60a7c0cb5dd11944ed418
cloud-server-auth/src/main/java/cn/mb/cloud/auth/controller/UserController.java
@@ -1,11 +1,18 @@
package cn.mb.cloud.auth.controller;
import cn.mb.cloud.auth.service.IUserDetailsService;
import cn.mb.cloud.auth.feignclient.AccountAuditClient;
import cn.mb.cloud.auth.warpper.GetTokenRequest;
import cn.mb.cloud.auth.warpper.RefreshTokenRequest;
import cn.mb.cloud.auth.warpper.TokenResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/oauth")
@@ -14,6 +21,9 @@
    @Autowired
    private IUserDetailsService userDetailsService;
    @Resource
    private AccountAuditClient accountAuditClient;
    /**
     * 获取认证token
@@ -21,15 +31,50 @@
     */
    @ResponseBody
    @PostMapping("/getToken")
    public TokenResponse getToken(@RequestBody GetTokenRequest request){
    public TokenResponse getToken(@RequestBody GetTokenRequest request, HttpServletRequest httpRequest){
        TokenResponse response = null;
        String error = null;
        try {
            return userDetailsService.getToken(request);
            response = userDetailsService.getToken(request);
            return response;
        }catch (Exception e){
            e.printStackTrace();
            error = e.getMessage();
        } finally {
            appendLoginAudit(request, httpRequest, response != null && response.getToken() != null, error);
        }
        return null;
    }
    private void appendLoginAudit(GetTokenRequest request, HttpServletRequest httpRequest, boolean success, String error) {
        try {
            Map<String, Object> audit = new HashMap<String, Object>();
            audit.put("sourceService", "mb-cloud-auth");
            audit.put("sourceType", "LOGIN");
            audit.put("operationType", "LOGIN");
            audit.put("riskLevel", "NORMAL");
            audit.put("operationName", "账号登录");
            audit.put("requestMethod", "POST");
            audit.put("requestUri", "/oauth/getToken");
            audit.put("requestParams", "username=" + (request == null ? null : request.getUsername()));
            // 登录账号是审计追溯字段,不做掩码;密码、token 等敏感字段仍然脱敏。
            audit.put("userAccount", request == null ? null : request.getUsername());
            audit.put("result", success ? "SUCCESS" : "FAIL");
            audit.put("errorMessage", error == null ? null : error.replaceAll("(?i)(password|token)\\s*[:=]\\s*[^,\\s&}]+", "$1=***"));
            audit.put("clientIp", clientIp(httpRequest));
            audit.put("createdAt", new Date());
            accountAuditClient.append(audit);
        } catch (Exception ignored) {
            // 审计链路不可用时绝不能影响认证主流程;客户端会输出 Feign 异常用于告警。
        }
    }
    private String clientIp(HttpServletRequest request) {
        if (request == null) return null;
        String forwarded = request.getHeader("X-Forwarded-For");
        return forwarded == null || forwarded.trim().isEmpty() ? request.getRemoteAddr() : forwarded.split(",")[0].trim();
    }
    /**
     * 刷新token
     * @param request