我的web-api服务由IIS 8.5托管,需要客户端证书并且正在响应403:禁止访问我的客户端。
如果不需要客户证书,则可以使用。
它们都使用相同的SSL证书,该证书是使用Portecle生成的,这是在IIS服务器证书个人和Web托管商店中。
日志中没有任何用处,所以这是我的代码: 主要活动:
package com.james.restfultest;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
//Consume Service
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import android.util.Log;
import android.widget.Toast;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import java.security.KeyStore;
import org.apache.http.conn.ssl.SSLSocketFactory;
import java.io.InputStream;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.protocol.HTTP;
public class Main extends Activity {
EditText edtInput;
Button btnGo;
TextView txvOutput;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setEventHandlers();
// check if you are connected or not
if (isConnected()) {
edtInput.setBackgroundColor(0xFF00CC00);
} else {
edtInput.setBackgroundColor(0xFF333333);
}
}
@Override
protected void onStart() {
super.onStart();
//new HttpRequestTask().execute();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void setEventHandlers() {
edtInput = (EditText) findViewById(R.id.edtInput);
btnGo = (Button) findViewById(R.id.btnGo);
txvOutput = (TextView) findViewById(R.id.txvOutput);
btnGo.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
callRestService(edtInput.getText().toString());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public boolean isConnected() {
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Activity.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected())
return true;
else
return false;
}
private void callRestService(String sParam) throws Exception {
MyAsyncTask myAsync = new MyAsyncTask();
myAsync.RefreshRefPoints(this, this);
myAsync.execute("hello", "boys");
}
}
class MyAsyncTask extends AsyncTask<String, Integer, String>{
public Context myContext;
public Activity myActivity;
public void RefreshRefPoints(Context ctx, Activity act){
// Now set context
this.myContext = ctx;
this.myActivity = act;
}
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
String s=postData(params);
return s;
}
protected void onPostExecute(String result){
//pb.setVisibility(View.GONE);
Toast.makeText(myContext, result, Toast.LENGTH_LONG).show();
}
protected void onProgressUpdate(Integer... progress){
//pb.setProgress(progress[0]);
}
public String postData(String valueIWantToSend[]) {
// Create a new HttpClient and Post Header
DefaultHttpClient httpclient = new MyHttpsClient(myContext);
HttpPost httppost = new HttpPost("https://86.168.253.152:40300/WebApiRest/api/courses");
String origresponseText="";
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("param1",valueIWantToSend[0]));
//nameValuePairs.add(new BasicNameValuePair("param2", valueIWantToSend[1]));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
/* execute */
HttpResponse response = httpclient.execute(httppost);
HttpEntity rp = response.getEntity();
origresponseText=readContent(response);
}
catch (ClientProtocolException e) {
throw new AssertionError(e);
}
catch (IOException e) {
throw new AssertionError(e);
}
String responseText = origresponseText.substring(7, origresponseText.length());
return responseText;
}
String readContent(HttpResponse response)
{
String text = "";
InputStream in =null;
try {
in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
text = sb.toString();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
in.close();
} catch (Exception ex) {
}
}
return text;
}
}
和MyHttpsClient类:
package com.james.restfultest;
import java.io.InputStream;
import java.security.KeyStore;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.SingleClientConnManager;
import android.content.Context;
public class MyHttpsClient extends DefaultHttpClient {
final Context context;
public MyHttpsClient(Context context) {
this.context = context;
}
@Override
protected ClientConnectionManager createClientConnectionManager() {
SchemeRegistry registry = new SchemeRegistry();
//JSP 070814 uncomment below line to enable http communication
//registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
// Register for port 443 our SSLSocketFactory with our keystore
// to the ConnectionManager
//registry.register(new Scheme("https", newSslSocketFactory(), 443));
registry.register(new Scheme("https", newSslSocketFactory(), 40300));
return new SingleClientConnManager(getParams(), registry);
}
private SSLSocketFactory newSslSocketFactory() {
try {
// Get an instance of the Bouncy Castle KeyStore format
KeyStore trusted = KeyStore.getInstance("BKS");
// Get the raw resource, which contains the keystore with
// your trusted certificates (root and any intermediate certs)
InputStream in = context.getResources().openRawResource(R.raw.servercertificate);
try {
// Initialize the keystore with the provided trusted certificates
// Also provide the password of the keystore
trusted.load(in, "myPassword".toCharArray());
} finally {
in.close();
}
// Pass the keystore to the SSLSocketFactory. The factory is responsible
// for the verification of the server certificate.
SSLSocketFactory sf = new SSLSocketFactory(trusted);
// Hostname verification from certificate
// http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
return sf;
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
我的问题是问题是: 答:客户端没有发送它的证书或B:证书没有CA根/无论如何它都不受信任。