gpt4 book ai didi

java - 如何从另一个来源访问 url?即使存在 Access-Control-Allow-* header ,预检请求也会返回 401

转载 作者:行者123 更新时间:2023-12-01 09:31:48 24 4
gpt4 key购买 nike

我在嵌入式 jetty 中运行简单的 Jersey REST 端点,并进行基本身份验证,并尝试通过其他 Web 应用程序的 ajax 调用来访问它。但即使存在 Access-Control-Allow-* header ,我也会在预检请求中收到 401 Unauthorized

服务器代码:

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";
}
}

}

客户端代码:

$(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);
}
});
});

客户端代码运行于 http://172.18.133.20:9999

以下是完整来源:

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

你能告诉我出了什么问题吗?

感谢您的提前!

最佳答案

我已经解决了从 SecurityMapping 排除 OPTIONS 请求的问题。只需添加一行:

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

关于java - 如何从另一个来源访问 url?即使存在 Access-Control-Allow-* header ,预检请求也会返回 401,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39342604/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com