标题说明了......向Restlet 2.3添加适当的CORS支持的正确/推荐方法是什么,它实现ChallengeAuthenticator
以允许Pre-flight选项访问没有Authorization标头的标头信息?
最初我以为我可以将@Options
注释添加到资源界面:
@Options
void getCorsSupport();
然后用这样的东西实现它:
@Override
public void getCorsSupport() {
Series<Header> headers = getResponse().getHeaders();
headers.set("Access-Control-Expose-Headers", "Authorization, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-OAuth-Scopes, X-Accepted-OAuth-Scopes");
Set<String> head = new HashSet<>();
head.add("Authorization");
head.add("Content-Type");
head.add("X-Requested-With");
getResponse().setAccessControlAllowHeaders(head);
Set<Method> methods = new HashSet<>();
methods.add(Method.ALL);
getResponse().setAccessControlAllowMethods(methods);
getResponse().setAccessControlAllowCredentials(true);
Series<Header> reqHeaders = getRequest().getHeaders();
String requestOrigin = reqHeaders.getFirstValue("Origin", false, "*");
getResponse().setAccessControlAllowOrigin(requestOrigin);
}
我期望发生的事情是ajax pre-flight Options
请求将被免除ChallengeAuthenticator
并且将返回上述标题。可悲的是,情况并非如此,ajax飞行前Options
请求与其他所有内容一样受ChallengeAuthenticator
的约束。这意味着请求失败,因为它尚未被授予其所需的Access-Control-Allow-Origin
标头。
然后我做了一些研究,发现似乎可以在应用程序中注册CorsService
。
public class WebApi extends Application {
public WebApi() {
getServices().add(createCorsService());
}
...
private CorsService createCorsService() {
CorsService corsService = new CorsService();
corsService.setAllowedOrigins(new HashSet(Arrays.asList("*")));
corsService.setAllowedCredentials(true);
corsService.setAllowedCredentials(true);
corsService.setAllowingAllRequestedHeaders(true);
Set<String> allowHeaders = new HashSet<>();
allowHeaders.add("Authorization");
allowHeaders.add("Content-Type");
allowHeaders.add("X-Requested-With");
corsService.setAllowedHeaders(allowHeaders);
Set<String> exposeHeaders = new HashSet<>();
exposeHeaders.add("Authorization");
exposeHeaders.add("Link");
exposeHeaders.add("X-RateLimit-Limit");
exposeHeaders.add("X-RateLimit-Remaining");
exposeHeaders.add("X-OAuth-Scopes");
exposeHeaders.add("X-Accepted-OAuth-Scopes");
corsService.setExposedHeaders(exposeHeaders);
return corsService;
}
}
我认为这可能是一种干净的方法,可以避免为每项服务使用@Options
方法。但是,我必须做错事,因为这似乎什么都不做。
进一步研究我发现还有一个CorsFilter
这样的东西似乎与CorsService
的实例化方式大致相同,除了它附加到Router
在createInboundRoot()
方法中。但是,我不明白如何与ChallengeAuthenticator
一起实施。
附录:
答案 0 :(得分:2)
您需要设置CorsService的另一个属性,称为“skipResourceForCorsOptions”。例如:
CorsService corsService = new CorsService();
corsService.setAllowingAllRequestedHeaders(true);
corsService.setAllowedOrigins(new HashSet(Arrays.asList("*")));
corsService.setAllowedCredentials(true);
corsService.setSkippingResourceForCorsOptions(true);
将在用户指南中添加更详细的页面,地址为:http://restlet.com/technical-resources/restlet-framework/guide/2.3/core/services/cors。