|
17 | 17 | package com.ctrip.framework.apollo.configservice.filter;
|
18 | 18 |
|
19 | 19 | import com.ctrip.framework.apollo.biz.config.BizConfig;
|
| 20 | +import com.ctrip.framework.apollo.common.utils.WebUtils; |
20 | 21 | import com.ctrip.framework.apollo.configservice.util.AccessKeyUtil;
|
21 | 22 | import com.ctrip.framework.apollo.core.signature.Signature;
|
22 | 23 | import com.ctrip.framework.apollo.core.utils.StringUtils;
|
| 24 | +import com.ctrip.framework.apollo.tracer.Tracer; |
23 | 25 | import com.google.common.net.HttpHeaders;
|
24 | 26 | import java.io.IOException;
|
25 | 27 | import java.util.List;
|
@@ -70,29 +72,60 @@ public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain
|
70 | 72 |
|
71 | 73 | List<String> availableSecrets = accessKeyUtil.findAvailableSecret(appId);
|
72 | 74 | if (!CollectionUtils.isEmpty(availableSecrets)) {
|
73 |
| - String timestamp = request.getHeader(Signature.HTTP_HEADER_TIMESTAMP); |
74 |
| - String authorization = request.getHeader(HttpHeaders.AUTHORIZATION); |
75 |
| - |
76 |
| - // check timestamp, valid within 1 minute |
77 |
| - if (!checkTimestamp(timestamp)) { |
78 |
| - logger.warn("Invalid timestamp. appId={},timestamp={}", appId, timestamp); |
79 |
| - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "RequestTimeTooSkewed"); |
| 75 | + if (!doCheck(request, response, appId, availableSecrets, false)) { |
80 | 76 | return;
|
81 | 77 | }
|
82 |
| - |
83 |
| - // check signature |
84 |
| - String uri = request.getRequestURI(); |
85 |
| - String query = request.getQueryString(); |
86 |
| - if (!checkAuthorization(authorization, availableSecrets, timestamp, uri, query)) { |
87 |
| - logger.warn("Invalid authorization. appId={},authorization={}", appId, authorization); |
88 |
| - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); |
89 |
| - return; |
| 78 | + } else { |
| 79 | + // pre-check for observable secrets |
| 80 | + List<String> observableSecrets = accessKeyUtil.findObservableSecrets(appId); |
| 81 | + if (!CollectionUtils.isEmpty(observableSecrets)) { |
| 82 | + doCheck(request, response, appId, observableSecrets, true); |
90 | 83 | }
|
91 | 84 | }
|
92 | 85 |
|
93 | 86 | chain.doFilter(request, response);
|
94 | 87 | }
|
95 | 88 |
|
| 89 | + /** |
| 90 | + * Performs authentication checks(timestamp and signature) for the request. |
| 91 | + * |
| 92 | + * @param preCheck Boolean flag indicating whether this is a pre-check |
| 93 | + * @return true if authentication checks is successful, false otherwise |
| 94 | + */ |
| 95 | + private boolean doCheck(HttpServletRequest req, HttpServletResponse resp, |
| 96 | + String appId, List<String> secrets, boolean preCheck) throws IOException { |
| 97 | + |
| 98 | + String timestamp = req.getHeader(Signature.HTTP_HEADER_TIMESTAMP); |
| 99 | + String authorization = req.getHeader(HttpHeaders.AUTHORIZATION); |
| 100 | + String ip = WebUtils.tryToGetClientIp(req); |
| 101 | + |
| 102 | + // check timestamp, valid within 1 minute |
| 103 | + if (!checkTimestamp(timestamp)) { |
| 104 | + if (preCheck) { |
| 105 | + preCheckInvalidLogging(String.format("Invalid timestamp in pre-check. " |
| 106 | + + "appId=%s,clientIp=%s,timestamp=%s", appId, ip, timestamp)); |
| 107 | + } else { |
| 108 | + logger.warn("Invalid timestamp. appId={},clientIp={},timestamp={}", appId, ip, timestamp); |
| 109 | + resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "RequestTimeTooSkewed"); |
| 110 | + return false; |
| 111 | + } |
| 112 | + } |
| 113 | + |
| 114 | + // check signature |
| 115 | + if (!checkAuthorization(authorization, secrets, timestamp, req.getRequestURI(), req.getQueryString())) { |
| 116 | + if (preCheck) { |
| 117 | + preCheckInvalidLogging(String.format("Invalid authorization in pre-check. " |
| 118 | + + "appId=%s,clientIp=%s,authorization=%s", appId, ip, authorization)); |
| 119 | + } else { |
| 120 | + logger.warn("Invalid authorization. appId={},clientIp={},authorization={}", appId, ip, authorization); |
| 121 | + resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); |
| 122 | + return false; |
| 123 | + } |
| 124 | + } |
| 125 | + |
| 126 | + return true; |
| 127 | + } |
| 128 | + |
96 | 129 | @Override
|
97 | 130 | public void destroy() {
|
98 | 131 | //nothing
|
@@ -130,4 +163,9 @@ private boolean checkAuthorization(String authorization, List<String> availableS
|
130 | 163 | }
|
131 | 164 | return false;
|
132 | 165 | }
|
| 166 | + |
| 167 | + protected void preCheckInvalidLogging(String message) { |
| 168 | + logger.warn(message); |
| 169 | + Tracer.logEvent("Apollo.AccessKey.PreCheck", message); |
| 170 | + } |
133 | 171 | }
|
0 commit comments