我正在查看此链接,我正在尝试向服务器发送请求
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
请告诉我我做错了什么。 Thanx in Advance
答案 0 :(得分:3)
也许您应该尝试先发送身份验证参数,如下所示:http://hc.apache.org/httpclient-legacy/authentication.html - 但我不确定这是否与您的版本有关。
Mat Mannion(@MatMannion)描述了一种更常见的方法,它应该适用于当前版本:Preemptive Basic authentication with Apache HttpClient 4基本上你只需要添加一个包含密钥的HTTP-header字段:“authorization”和用户名和密码的base64编码字符串(组合在一起然后用base64编码)或者@Jonathan或@AdamBatkin呈现它的方式在同一个帖子中(上面链接)
@edit:
在有了一些业余时间后,我把你的示例代码扔进Netbeans(是的,我想对NB更加熟悉)并构建一个简单的jetty服务器演示,它使用SSL和基本的auth和Apache HttpClient调用一个简单的hello world servlet来展示客户端如何定义SSL和基本身份验证。请进一步注意,部分代码来自官方文档,密钥库以及信任库的设置与解释here类似。
下面请找到项目的完整代码(二进制密钥库除外)(也许其他人也可能觉得它很有用)。
的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());
}
}
realm.properties
admin: admin123, admin
root: passw0rd, user
Client.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的功能。