| | |
| | | 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") |
| | |
| | | @Autowired |
| | | private IUserDetailsService userDetailsService; |
| | | |
| | | @Resource |
| | | private AccountAuditClient accountAuditClient; |
| | | |
| | | |
| | | /** |
| | | * 获取认证token |
| | |
| | | */ |
| | | @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 |