简体   繁体   English

如何从其他来源访问网址? 即使存在Access-Control-Allow- *标头,预检请求也将返回401

[英]How to access url from another origin? Preflight request returns 401 even if Access-Control-Allow-* headers is present

I run simple Jersey REST endpoint in embedded jetty with basic authentication and try to access it via ajax call from other web-application. 我使用基本身份验证在嵌入式码头中运行简单的Jersey REST端点,并尝试通过其他Web应用程序通过ajax调用来访问它。 But I get 401 Unauthorized on preflight request even if Access-Control-Allow-* headers is present. 但是,即使存在Access-Control-Allow- *标头,我也会在预检请求中得到401未经授权

Server code: 服务器代码:

public final class RESTServerStarter {
private static final int WEB_SERVER_PORT = 8888;

public static void main(String[] args) throws Exception {
    final ServletHolder sh = new ServletHolder(ServletContainer.class);
    sh.setInitParameter(ServletContainer.RESOURCE_CONFIG_CLASS, PackagesResourceConfig.class.getCanonicalName());
    sh.setInitParameter(PackagesResourceConfig.PROPERTY_PACKAGES, HelloRESTService.class.getPackage().getName());

    final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
    context.setSecurityHandler(basicAuth("admin", "adminpwd", "Private!"));
    context.setContextPath("/rest");
    context.addServlet(sh, "/*");
    context.addFilter(MyFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));

    final Server server = new Server();

    final ServerConnector connector = new ServerConnector(server);
    connector.setHost("172.18.133.20");
    connector.setPort(WEB_SERVER_PORT);
    server.addConnector(connector);

    server.setHandler(context);

    try {
        server.start();
        server.join();
    } finally {
        server.destroy();
    }

}

private static final SecurityHandler basicAuth(String username, String password, String realm) {

    HashLoginService hashLoginService = new HashLoginService();
    hashLoginService.putUser(username, Credential.getCredential(password), new String[]{"user"});
    hashLoginService.setName(realm);

    Constraint constraint = new Constraint();
    constraint.setName(Constraint.__BASIC_AUTH);
    constraint.setRoles(new String[]{"user"});
    constraint.setAuthenticate(true);

    ConstraintMapping cm = new ConstraintMapping();
    cm.setConstraint(constraint);
    cm.setPathSpec("/*");

    ConstraintSecurityHandler csh = new ConstraintSecurityHandler();
    csh.setAuthenticator(new BasicAuthenticator());
    csh.setRealmName("myrealm");
    csh.addConstraintMapping(cm);
    csh.setLoginService(hashLoginService);

    return csh;

}

public static final class MyFilter implements Filter {
    public void init(FilterConfig filterConfig) {
        //nothing to init
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        final HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.addHeader("Access-Control-Allow-Origin", "http://172.18.133.20:" + RESTClientStarter.WEB_SERVER_PORT);
        httpResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE, PUT");
        httpResponse.addHeader("Access-Control-Allow-Credentials", "true");
        httpResponse.addHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
        chain.doFilter(request, response);
    }

    public void destroy() {
        //nothing to destroy
    }
}

@Path("/test")
public static class HelloRESTService {

    @GET
    @Path("hello")
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
}

} }

Client code: 客户代码:

$(function(){
    $.ajax({
        url : "http://172.18.133.20:8888/rest/test/hello",
        type : "GET",
        timeout : 120000,
        async : true,
        xhrFields: {
            withCredentials: true
        },
        crossDomain: true,
        headers: {
            "Authorization": "Basic " + btoa("admin:adminpwd")
        },
        error: function(xhr, status, error) {
            $("#container").text(error);
        },
        success: function(xhr) {
            $("#container").text(xhr);
        }
    });
});

Client code run on http://172.18.133.20:9999 客户端代码在http://172.18.133.20:9999上运行

Here is the full sources: 以下是全部资料:

https://bitbucket.org/dmitry_apanasevich/cors/src https://bitbucket.org/dmitry_apanasevich/cors/src

Could you please tell me what's wrong? 你能告诉我怎么了吗?

Thanks for advance! 感谢前进!

I have solved the problen excluding OPTIONS request from SecurityMapping. 我已经解决了从SecurityMapping排除OPTIONS请求的问题。 Just adding one line: 只需添加一行:

...
ConstraintMapping cm = new ConstraintMapping();
cm.setMethod("GET"); //new line
cm.setConstraint(constraint);
cm.setPathSpec("/*");
...

I think you use httpResponse.addHeader("Access-Control-Allow-Origin", " http://172.18.133.20 :" + RESTClientStarter.WEB_SERVER_PORT); 我认为您使用httpResponse.addHeader(“ Access-Control-Allow-Origin”,“ http://172.18.133.20 :” + RESTClientStarter.WEB_SERVER_PORT); and WEB_SERVER_PORT of your rest app is 9999 so httpResponse allow http://172.18.133.20:9999 . 其余应用程序的WEB_SERVER_PORT是9999,因此httpResponse允许http://172.18.133.20:9999 But you call it at port 8888 this is not allow. 但是您不允许在端口8888上调用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何处理“对预检请求的响应未通过没有访问控制允许来源 header 存在于请求的资源上”来自 angular - How to handle “Response to preflight request doesn't pass No Access-control-Allow-Origin header is present on requested resource ” from angular in BE 对预检请求的响应未通过访问控制检查:不存在“Access-Control-Allow-Origin”标头 - Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present 在飞行前响应中,Access-Control-Allow-Headers不允许在Request标头字段中使用cors enable Access-Control-Allow-Origin - cors enable in Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response 如何修复对预检请求的响应未通过访问控制检查:否'Access-Control-Allow-Origin'? - How to fix Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin'? 对预检请求的响应未通过访问控制检查:不存在“Access-Control-Allow-Origin”标头。 服务器错误 - Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present . Server error 预检响应中的 Access-Control-Allow-Headers 不允许请求 header 字段 ack 即使服务器已经允许它 - Request header field ack is not allowed by Access-Control-Allow-Headers in preflight response even the server already allowing it Angular 7 如何将 Access-Control-Allow-Origin 标头添加到预检发布请求? - Angular 7 How to add Access-Control-Allow-Origin header to preflight post request? 预检请求未通过访问控制检查:否 'Access-Control-Allow-Origin' - preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' 请求中不存在“ Access-Control-Allow-Origin”标头 - No 'Access-Control-Allow-Origin' header present in request 存在“ Access-Control-Allow-Origin”标头 - 'Access-Control-Allow-Origin' header is present
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM