刘帅
2026-09-21 673b4f9d4dce17a2e1c116b2b12646a9fdd74829
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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")
public class UserController {
 
    @Autowired
    private IUserDetailsService userDetailsService;
 
    @Resource
    private AccountAuditClient accountAuditClient;
 
 
    /**
     * 获取认证token
     * @param request
     */
    @ResponseBody
    @PostMapping("/getToken")
    public TokenResponse getToken(@RequestBody GetTokenRequest request, HttpServletRequest httpRequest){
        TokenResponse response = null;
        String error = null;
        try {
            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
     * @return
     */
    @ResponseBody
    @PostMapping("/refreshToken")
    public TokenResponse refreshToken(@RequestBody RefreshTokenRequest request){
        try {
            return userDetailsService.refreshToken(request);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}