1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.gbif.ws.client;
15
16 import org.gbif.ws.WebApplicationException;
17 import org.gbif.ws.security.Md5EncodeService;
18 import org.gbif.ws.security.PrivateKeyNotFoundException;
19 import org.gbif.ws.security.RequestDataToSign;
20 import org.gbif.ws.security.SigningService;
21
22 import java.util.Collection;
23 import java.util.Map;
24
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27 import org.springframework.http.HttpHeaders;
28 import org.springframework.http.HttpStatus;
29
30 import feign.RequestInterceptor;
31 import feign.RequestTemplate;
32
33 import static org.gbif.ws.client.ClientUtils.isPostOrPutRequest;
34 import static org.gbif.ws.client.ClientUtils.isRequestBodyNotEmpty;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class GbifAuthRequestInterceptor implements RequestInterceptor {
52
53 private static final Logger LOG = LoggerFactory.getLogger(GbifAuthRequestInterceptor.class);
54
55 private SigningService signingService;
56 private Md5EncodeService md5EncodeService;
57 private String username;
58 private String appKey;
59 private String secretKey;
60
61 public GbifAuthRequestInterceptor(
62 String username,
63 String appKey,
64 String secretKey,
65 SigningService signingService,
66 Md5EncodeService md5EncodeService) {
67 this.signingService = signingService;
68 this.md5EncodeService = md5EncodeService;
69 this.username = username;
70 this.appKey = appKey;
71 this.secretKey = secretKey;
72 }
73
74 @Override
75 public void apply(RequestTemplate template) {
76 RequestDataToSigntDataToSign">RequestDataToSign requestDataToSign = new RequestDataToSign();
77 requestDataToSign.setMethod(template.method());
78 requestDataToSign.setUrl(removeQueryParameters(template.url()));
79 requestDataToSign.setUser(username);
80
81 if (isPostOrPutRequest(template) && isRequestBodyNotEmpty(template)) {
82 Map<String, Collection<String>> headers = template.headers();
83
84 Collection<String> contentTypeHeaders = headers.get(HttpHeaders.CONTENT_TYPE);
85
86 String contentType =
87 (contentTypeHeaders != null && !contentTypeHeaders.isEmpty())
88 ? contentTypeHeaders.iterator().next()
89 : "application/json";
90 requestDataToSign.setContentType(contentType);
91
92 String contentMd5 = md5EncodeService.encode(template.body());
93 requestDataToSign.setContentTypeMd5(contentMd5);
94
95 template.header("Content-MD5", contentMd5);
96 }
97
98 LOG.debug("Client data to sign: {}", requestDataToSign.stringToSign());
99
100 try {
101 String signature = signingService.buildSignature(requestDataToSign, secretKey);
102
103 template.header("x-gbif-user", username);
104 template.header("Authorization", "GBIF " + appKey + ":" + signature);
105 } catch (PrivateKeyNotFoundException e) {
106 LOG.debug("Private key was not found for the application {}", appKey);
107 throw new WebApplicationException(
108 "Private key was not found for the application " + appKey, HttpStatus.UNAUTHORIZED);
109 }
110 }
111
112
113
114
115 private String removeQueryParameters(String url) {
116 return url.split("\\?")[0];
117 }
118 }