我正在查看此链接并尝试向服务器发送请求
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html
public class Test {
public static void main(String[] args) throws ClientProtocolException, IOException {
DefaultHttpClient httpClient;
URL url = new URL("https://9.5.127.34:443");
httpClient = getSSLHttpClient(url);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope("https://9.5.127.34", AuthScope.ANY_PORT),
new UsernamePasswordCredentials("root", "passw0rd"));
httpClient.setCredentialsProvider(credsProvider);
HttpGet httpget = new HttpGet("https://9.5.127.34/powervc/openstack/volume/v1/115e4ad38aef463e8f99991baad1f809//volumes/3627400b-cd98-46c7-a7e2-ebce587a0b05/restricted_metadata");
HttpResponse response = httpClient.execute(httpget);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null) {
System.out.println(line);
}
}
但它给我的错误是
Authentication required
请告诉我我做错了什么。提前致谢
最佳答案
也许您应该尝试像这里解释的那样抢先发送身份验证参数:http://hc.apache.org/httpclient-legacy/authentication.html - 但我不确定这是否与您的版本有关。
Mat Mannion (@MatMannion) 描述了一种更常见的方法,应该适用于当前版本:Preemptive Basic authentication with Apache HttpClient 4
基本上,您只需要添加一个包含 key 的 HTTP header 字段:“authorization”和用户名和密码的 base64 编码字符串(组合在一起,然后进行 base64 编码)或@Jonathan 或@AdamBatkin 提供的方式在同一个线程中(上面链接)
@编辑:
在有一些空闲时间后,我将您的示例代码放入 Netbeans(是的,我想更熟悉 NB)并构建了一个简单的 jetty 服务器演示,它使用 SSL 和基本身份验证以及一个 Apache HttpClient 来调用一个简单的 hello world servlet 来展示客户端需要如何定义 SSL 和基本身份验证。进一步请注意,一些代码取自官方文档,并且 keystore 和信任库的设置如解释的那样 here .
请在下面找到该项目的完整代码(除了二进制的 keystore )(也许其他人也可能会觉得它有用)。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>at.rovo.test</groupId>
<artifactId>HttpClientExample</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>HttpClientExample</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Client -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3</version>
<type>jar</type>
</dependency>
<!-- Server -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.1.0.M0</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
<version>9.1.0.M0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.1.0.M0</version>
<type>jar</type>
</dependency>
</dependencies>
</project>
JettyServer.java
package at.rovo.test.httpclient;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.security.SecurityHandler;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.security.Constraint;
public class JettyServer
{
private String REALM;
public static void main( String[] args ) throws Exception
{
new JettyServer();
}
public JettyServer() throws Exception
{
Server server = new Server(8080);
server.addConnector(this.getSslChannelConnector(server));
server.setStopAtShutdown(true);
// create the context handler for the server
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.setClassLoader(Thread.currentThread().getContextClassLoader());
// attach the security handler to it that has basic authentication
context.setSecurityHandler(this.getSecurityHandler());
server.setHandler(context);
// define the processing servlet
context.addServlet(new ServletHolder(new ProcessingServlet()), "/process");
server.start();
server.join();
}
private Connector getSslChannelConnector(Server server)
{
try
{
String keyStore = this.getClass().getResource("/serverKey.jks").toURI().getPath();
SslConnectionFactory sslConnFactory = new SslConnectionFactory();
sslConnFactory.getSslContextFactory().setKeyStorePath(keyStore);
sslConnFactory.getSslContextFactory().setKeyStorePassword("keystorePW");
sslConnFactory.getSslContextFactory().setKeyManagerPassword("jettyPW");
HttpConfiguration config = new HttpConfiguration();
ConnectionFactory connFactory = new HttpConnectionFactory(config);
ServerConnector connector = new ServerConnector(server, sslConnFactory, connFactory);
connector.setPort(8443);
connector.setHost("localhost");
connector.setIdleTimeout(30000);
return connector;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
private SecurityHandler getSecurityHandler() throws Exception
{
// add authentication
Constraint constraint = new Constraint(Constraint.__BASIC_AUTH,"user");
constraint.setAuthenticate(true);
constraint.setRoles(new String[]{"user","admin"});
// map the security constraint to the root path.
ConstraintMapping cm = new ConstraintMapping();
cm.setConstraint(constraint);
cm.setPathSpec("/*");
// create the security handler, set the authentication to Basic
// and assign the realm.
ConstraintSecurityHandler csh = new ConstraintSecurityHandler();
csh.setAuthenticator(new BasicAuthenticator());
csh.setRealmName(REALM);
csh.addConstraintMapping(cm);
// set the login service
csh.setLoginService(getHashLoginService());
return csh;
}
private HashLoginService getHashLoginService() throws Exception
{
// load the authentication data from a simple property file
HashLoginService hls = new HashLoginService();
hls.setName(REALM);
hls.setConfig(this.getClass().getResource("/realm.properties").toURI().toString());
hls.setRefreshInterval(0);
return hls;
}
}
ProcessingServlet.java
package at.rovo.test.httpclient;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ProcessingServlet extends HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
response.setContentType("text/html");
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println("<h1>Hello World</h1>");
response.getWriter().println("session=" + request.getSession(true).getId());
}
}
领域.属性
admin: admin123, admin
root: passw0rd, user
客户端.java
package at.rovo.test.httpclient;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.security.KeyStore;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class Client
{
public static void main(String[] args) throws Exception
{
CloseableHttpClient httpClient;
// SSL setup
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream instream = new FileInputStream(new File(Client.class.getResource("/clientTrust.jks").toURI()));
try
{
trustStore.load(instream, "truststorePW".toCharArray());
}
finally
{
instream.close();
}
SSLContext sslcontext = SSLContexts.custom()
.loadTrustMaterial(trustStore)
.build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
HttpHost targetHost = new HttpHost("localhost", 8443, "https");
// Basic Auth setup
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(targetHost.getHostName(), targetHost.getPort()),
new UsernamePasswordCredentials("root", "passw0rd"));
httpClient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.setDefaultCredentialsProvider(credsProvider)
.build();
try
{
HttpGet httpget = new HttpGet("https://localhost:8443/process");
System.out.println("executing request: " + httpget.getRequestLine());
System.out.println("to target: " + targetHost);
CloseableHttpResponse response = httpClient.execute(httpget);
try
{
HttpEntity entity = response.getEntity();
System.out.println("--------------------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null)
{
System.out.println("Response content length: "+entity.getContentLength());
}
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line;
while ((line = rd.readLine()) != null)
{
System.out.println(line);
}
EntityUtils.consume(entity);
}
finally
{
response.close();
}
}
finally
{
httpClient.close();
}
}
}
请耐心等待,因为我几乎不检查错误,但这是一个快速且简单的示例,用于演示使用基本身份验证的 SSL 保护的 Apache HttpClient 的功能。
关于java - 使用 HTTP Commons Client 的基本身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19679320/