【发布时间】:2015-12-28 07:30:37
【问题描述】:
标题说...向 Restlet 2.3 添加适当的 CORS 支持的正确/推荐方法是什么,实现 ChallengeAuthenticator 以允许飞行前选项在没有授权标头的情况下访问标头信息?
本来我以为可以在资源接口上加@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 飞行前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 大致相同,只是它在createInboundRoot() 方法中附加到Router .但是我不明白它应该如何与ChallengeAuthenticator一起工作。
附录:
- 我在代码中找到了this,提示应该处理飞行前的问题。
【问题讨论】:
标签: java ajax rest cors restlet