【问题标题】:facing SSLHandshakeException with OAuth authentication使用 OAuth 身份验证面对 SSLHandshakeException
【发布时间】:2016-05-26 13:08:06
【问题描述】:

我的代码:

    URL url=new URL(https url with client id and clientsecret);
    HttpURLConnection connect=(HttpURLConnection) url.openConnection();
    connect.setRequestMethod("POST");
    connect.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
    connect.setDoOutput(true);

通过这个我得到了

javax.net.ssl.SSLHandshakeException:无法验证 SSL 证书 对于网址:(我的网址)

如果尝试更改为HttpsURLConnection

    URL url=new URL(https url with client id and clientsecret);
    HttpsURLConnection connect=(HttpsURLConnection) url.openConnection();
    connect.setRequestMethod("POST");
    connect.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
    connect.setDoOutput(true);

我来了

java.lang.ClassCastException: com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection 无法转换为 javax.net.ssl.HttpsURLConnection

我正在与 GAE 合作。我需要解决这个问题才能获得访问令牌。 通过查看较早的问题,我没有得到正确的解决方案。

当我通过“curl”尝试通过终端时,我能够获得有效的访问令牌。

curl --data "parameters like client id and client secret and the auth_code" my https url

在此之后我能够获得令牌的有效响应

【问题讨论】:

  • 即使我尝试了在stackoverflow.com/questions/2893819/…找到的一些代码
  • 这种情况是仅发生在开发服务器上还是在部署的应用程序上也发生?
  • 我尚未在部署的应用程序中添加此代码。我只是在本地检查。

标签: java google-app-engine sslhandshakeexception


【解决方案1】:

我相信您需要加载密钥库。您应该保存证书并加载 .jks 以进行连接:

package com.tdi.api.brm.service;

import java.io.InputStream;
import java.security.KeyStore;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.protocol.HTTP;
import org.apache.log4j.Logger;

import com.tdi.api.brm.servlet.InitServlet;
import com.tdi.api.brm.util.TDI_Constants;
import com.tdi.api.brm.util.TDI_Utility;
import com.tdi.common.exceptions.TDI_CommonException;
import com.tdi.common.utility.TDI_CommonConstants;
import com.tdi.restService.model.tdiapis.ProccessAccountElements;

public class TDI_IGProcessAccountServiceImpl2 extends AbstractBaseService implements TDI_IGProcessAccountService{

static final Logger LOGGER = Logger.getLogger(TDI_IGProcessAccountServiceImpl2.class);

public TDI_IGProcessAccountServiceImpl2(){
    LOGGER.debug("TDI_IGProcessAccountServiceImpl: Contructor: Entered");

    LOGGER.debug("TDI_IGProcessAccountServiceImpl: Contructor: Leaving");
}

public ProccessAccountElements processAccount(String payload, String environment) throws Exception{
    LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Entered");

    ProccessAccountElements serviceResp = new ProccessAccountElements();
    String xmlFilePath;
    String xmlString;
    String httpResponsexml;
    String httpPostUri;
    StringEntity stringEntity;
    HttpClient httpClient = null;
    HttpPost httpPost;
    HttpResponse httpResponse;
    HttpEntity httpEntity;

    InputStream keyStoreInputStream;
    String keyStoreFilePath;
    String keyStorePassword;
    KeyStore keyStore;
    SSLSocketFactory socketFactory;
    Scheme scheme;

    try{

            xmlFilePath = TDI_Constants.XML_TEMPLATE_DIR.concat(TDI_Constants.FORWARD_SLASH).concat(TDI_Constants.TDI_PROCESS_ACCOUNT_XML);


            xmlString = TDI_Utility.readFromFile(xmlFilePath);

            stringEntity = new StringEntity(payload, HTTP.UTF_8);
            stringEntity.setContentType(TDI_Constants.TEXT_XML);

            httpPostUri = InitServlet.getPropertyValue(environment.concat(TDI_Constants.DELIMITER_UNDERSCORE).concat(TDI_Constants.IG_PROCESS_ACCOUNT_URL1));

            httpPost = new HttpPost(httpPostUri);
            httpPost.setHeader(TDI_Constants.CONTENT_TYPE, TDI_Constants.CONTENT_TYPE_VALUE);
            httpPost.setEntity(stringEntity);

            keyStorePassword = TDI_Constants.KEY_STORE_PASSWORD;
            keyStoreFilePath = TDI_Constants.BRM_SHARE.concat(TDI_Constants.FORWARD_SLASH).concat(environment).concat(TDI_Constants.DELIMITER_UNDERSCORE).concat(TDI_Constants.PROCESS_ACCOUNT_CERTIFICATE);

            keyStoreInputStream = TDI_Utility.getResourceAsInputStream(keyStoreFilePath);

            keyStore  = KeyStore.getInstance(KeyStore.getDefaultType());

            try {
                keyStore.load(keyStoreInputStream, keyStorePassword.toCharArray());
                LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Try: keyStore: Loaded");
            }finally{
                keyStoreInputStream.close();
                LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Try: keyStoreInputStream: Closed");
            }

            socketFactory = new SSLSocketFactory(keyStore);
            socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Try: HostnameVerifier: Set");

            scheme = new Scheme(TDI_Constants.HTTPS, socketFactory, TDI_Constants.PORT_443);
            LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Try: Scheme: Created");

            httpClient = new DefaultHttpClient();

            httpClient.getConnectionManager().getSchemeRegistry().register(scheme);
            LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Try: HttpClient: Registered");

            httpResponse = (BasicHttpResponse) httpClient.execute(httpPost);

            //Capture the TDI-Service un available exception
            if(httpResponse != null &&  httpResponse.getStatusLine().toString().contains(TDI_Constants.WEBSERVICE_UNAVAIALBLE)){
                LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: URL : " + httpPostUri);
                LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: httpResponse.getStatusLine() " + httpResponse.getStatusLine().toString());
                throw new TDI_CommonException(TDI_Constants.WEBSERVICE_ERROR_CODE_404,TDI_Constants.IG_SERVICE_ERROR_MESSAGE_404);
            }

            if(httpResponse != null) {
                httpEntity = httpResponse.getEntity();
                httpResponsexml = TDI_Utility.getInputStreamAsString(httpEntity.getContent());
                serviceResp = parseResponseXML (httpEntity, httpResponsexml);       

            }else{
                httpResponsexml = TDI_Constants.COMMON_XML_RESPONSE_ERROR_NO_RESPONSE;
                throw new TDI_CommonException(TDI_CommonConstants.ERROR_CODE_932, httpResponsexml);
            }
            LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Try: Final: HttpResponsexml=[" + httpResponsexml + "]");

        LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Try: Leaving");
    }catch(java.net.SocketException soe){
        LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Catch: Socket Exception Entered");
        LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Catch: Socket Exception: " + soe.getMessage());
        LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Catch: Socket Exception Leaving");
        throw new TDI_CommonException(TDI_Constants.WEBSERVICE_ERROR_CODE_404,TDI_Constants.IG_SERVICE_ERROR_MESSAGE_404);
    }catch(TDI_CommonException e){
        e.printStackTrace();
        LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Catch: TDI_CommonException: Entered");
        LOGGER.error("TDI_IGProcessAccountServiceImpl: processAccount: Catch: TDI_CommonException: " + e);
        LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Catch: TDI_CommonException: Leaving");
        serviceResp.setRespCode(TDI_Constants.WDR_WEBSERVICE_ERROR_CODE);
        serviceResp.setRespDesc(TDI_Constants.WDR_SERVICE_ERROR_MESSAGE);
        throw e;
    }catch(Exception e){
        LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Catch: Exception: Entered");
        LOGGER.error("TDI_IGProcessAccountServiceImpl: processAccount: Catch: Exception: " + e);
        LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Catch: Exception: Leaving");
        serviceResp.setRespCode(TDI_Constants.WDR_WEBSERVICE_ERROR_CODE);
        serviceResp.setRespDesc(TDI_Constants.WDR_SERVICE_ERROR_MESSAGE);
        throw e;
    }

    LOGGER.debug("TDI_IGProcessAccountServiceImpl: processAccount: Leaving");
    return serviceResp;
}

}

检查此示例中的方案。

【讨论】:

  • 你好 JRadcliffethanx 的链接,但我已经检查过了,我没有得到想要的解决方案。
  • 已更新,看看这是否有助于该计划。如果您可以使用 DefaultHttpClient,可能会丢失
【解决方案2】:

最初的问题是由于无法在您的域中验证 SSL 证书造成的。这可能是因为证书在某些方面不好,或者因为 Google 不知道信任链的根。您应该专注于调查您的 SSL 设置。

第二个问题是由于尝试将 javax.net.URL.openConnection()(在 App Engine 运行时将返回 com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection 的实例)的结果转换为 javax.net.ssl.HttpsURLConnection 而导致的,这是无法完成的。

【讨论】:

  • 嗨@Nick 我试图通过我的终端执行以下代码来获取证书,然后它也显示为 SSL 握手错误。 回声-n | openssl s_client -connect :443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ~/.crt
  • 您好 Nickthanx 的网址。它真的很有用。
猜你喜欢
  • 2015-06-20
  • 2015-02-02
  • 1970-01-01
  • 2011-11-25
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2018-07-10
  • 2011-09-17
相关资源
最近更新 更多