|
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