我的Android应用程序应该与用C#.Net
编写的ASP.net web api进行通信。从手机发送的数据包含不应向公众公开的数据。所以我正在尝试使用https
协议。在我的服务器端,我要求所有请求都是HTTPS
,如下所示:
RequireRegisteredImei
public class RequireRegisteredImeiAttribute : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
var request = actionContext.ControllerContext.Request;
if (request.RequestUri.Scheme == Uri.UriSchemeHttps)
{
//OKAY
}
else
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
}
}
}
在控制器中:
[RequireRegisteredImei]
public string Post()
{
}
我通过从手机发送一个简单的http request
来调试此代码,而且这段代码效果很好,它会拒绝我。
所以,我开始研究如何从我的Android手机上通过https
发送请求。我想出了类似的东西:
public static DefaultHttpClient getSecureHttpClient() {
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
schemeRegistry.register(new Scheme("http", SSLSocketFactory.getSocketFactory(), 80));
BasicHttpParams params = new BasicHttpParams();
SingleClientConnManager mgr = new SingleClientConnManager(params, schemeRegistry);
return new DefaultHttpClient(mgr, params);
}
我这样使用这种方法:
HttpClient httpClient = CustomHttpClient.getSecureHttpClient();
这只会产生IOException: No peer certificate
我已经阅读了几个关于此问题的主题:
Problems with https (No peer certificate) in android
Android SSL - No Peer Certificate
'No peer certificate' error in Android 2.3 but NOT in 4
但是必须有一种更简单的方法来从Android HTTPS
发布数据?
答案 0 :(得分:1)
如果您拥有所有Android版本中未包含的自定义证书或CA颁发的证书,则可以将证书包含在您的应用中并直接使用。
为此,您必须将服务器证书(当然没有密钥)导入BKS密钥存储区,然后可以将其用作自定义信任存储区。
描述如何操作的非常好的教程是 Using a Custom Certificate Trust Store on Android 。
与EasyTrustManager或DummyTrustManager等标准解决方案不同,您可以找到Stackoverflow,此解决方案不会禁用SSL身份验证,因此不像其他解决方案那样不安全。
答案 1 :(得分:1)
您还可以将HttpClient
配置为接受以下所有证书:
SSLSocketFactory sslSocketFactory=SSLSocketFactory.getSocketFactory();
HostnameVerifier hostnameVerifier=org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
sslSocketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(
new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(
new Scheme("https", sslSocketFactory, 443));
如果您认为这可能是您的解决方案。