由于我曾经遇到过这个问题,也许这篇文章可以帮助其他人避免同样的痛苦。必须使用自定义cookie策略而不是通用的策略来支持多个目录。对于每个目录,您需要设置3个cookie(CloudFront-Key-Pair-Id、CloudFront-Policy和CloudFront-Signature)。对于每个目录,您需要使用相同名称但不同路径的3个cookie(对我来说,设置相同的cookie名称超过一次有点违反直觉,但我已经测试过它可以工作)。另一个困难的部分是您必须确保cloudfront域名与您的域名匹配,否则您无法传递cookie。在本地主机上,我使用host文件创建虚假的DNS查找进行测试(将127.0.0.1映射到myapp.com,而cloudfront必须使用类似cdn.myapp.com的某个域名)。
<dependencyManagement>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>2.16.60</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-bom</artifactId>
<version>1.12.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-cloudfront</artifactId>
</dependency>
@GetMapping("/cloudfront-cookies")
public String getCloudfrontCookies(HttpServletResponse resp) {
String path1 = "/protected/user1/";
String path2 = "/protected/user2/";
setCookies(resp, path1, distributionDomain, "https");
setCookies(resp, path2, distributionDomain, "https");
return "success";
}
protected void setCookies(HttpServletResponse resp, String path, String domain, String proto) {
Date start = new Date(System.currentTimeMillis());
Date expiration = new Date(System.currentTimeMillis()+expirationSeconds*1000);
InputStream is = this.getClass().getResourceAsStream(privateKeyFilePath);
try {
PrivateKey privateKey = RSA.privateKeyFromPKCS8(IOUtils.toByteArray(is));
String url = proto + "://" + domain + path + "*";
CookiesForCustomPolicy cp = CloudFrontCookieSigner.getCookiesForCustomPolicy(
url,
privateKey,
keyPairId,
expiration,
start,
null);
Entry<String,String> kpi = cp.getKeyPairId();
Entry<String,String> pol = cp.getPolicy();
Entry<String,String> sig = cp.getSignature();
resp.addCookie(getCookie(pol.getKey(),pol.getValue(),path,domain));
resp.addCookie(getCookie(sig.getKey(),sig.getValue(),path,domain));
resp.addCookie(getCookie(kpi.getKey(),kpi.getValue(),path,domain));
}catch(Exception e) {
e.printStackTrace();
}
finally {
try {is.close();} catch(IOException ignore) {}
}
}
protected Cookie getCookie(String key, String value, String path, String domain) {
Cookie c = new Cookie(key,value);
c.setPath(path);
return c;
}
一些属性是通过属性文件设置的,我从文件系统中获取证书。其余内容请遵循 AWS 签名 cookie 文档。
/user1
和/user2
。据我所知,策略中的路径只能是/user1
或/user2
其中之一。 - Anthony Kong