2014-11-22 98 views
0

我正在构建一个需要oauth 2身份验证的应用程序。端点检索的access_tokenhttps://10.0.2.2:8443/oauth/token(10.0.2.2是环回才能到本地主机的主机上)无法检索Android客户端中的身份验证令牌

当我通过我的浏览器的请求它工作得很好,但是当我做它通过Java代码,我收到了一个错误的请求,但没有得到足够的信息来解决问题。

Post request with PostMan

我使用不安全的HttpClient(是的,我知道,这是非常不安全的)

public class UnsafeHttpsClient { 

    public static HttpClient getNewHttpClient() { 
     try { 
      KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
      trustStore.load(null, null); 

      MySSLSocketFactory sf = new MySSLSocketFactory(trustStore); 
      sf.setHostnameVerifier(sf.ALLOW_ALL_HOSTNAME_VERIFIER); 

      HttpParams params = new BasicHttpParams(); 
      HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
      HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); 

      SchemeRegistry registry = new SchemeRegistry(); 
      registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 8080)); 
      registry.register(new Scheme("https", sf, 8443)); 

      ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); 

      return new DefaultHttpClient(ccm, params); 
     } catch (Exception e) { 
      return new DefaultHttpClient(); 
     } 
    } 

} 

我也使用这个类。该代码从这个职位是采取这样: 参考:Trusting all certificates using HttpClient over HTTPS

public class MySSLSocketFactory extends SSLSocketFactory { 
    SSLContext sslContext = SSLContext.getInstance("TLS"); 

    public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { 
     super(truststore); 

     TrustManager tm = new X509TrustManager() { 
      public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
      } 

      public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
      } 

      public X509Certificate[] getAcceptedIssuers() { 
       return null; 
      } 
     }; 

     sslContext.init(null, new TrustManager[] { tm }, null); 
    } 

    @Override 
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { 
     return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); 
    } 

    @Override 
    public Socket createSocket() throws IOException { 
     return sslContext.getSocketFactory().createSocket(); 
    } 
} 

最后,我用这两个类来构建我的要求:

public class TaskAuthenticate extends AsyncTask<String, Integer, JSONArray> { 

    private Context ctx; 
    public IApiAccessResponse delegate=null; 
    private HttpClient mHttpclient = UnsafeHttpsClient.getNewHttpClient(); 
    private HttpPost mHttppost; 
    private String client_string = "mobile:"; 
    public TaskAuthenticate (Context ctx) { 
     this.ctx = ctx; 
    } 


    protected JSONArray doInBackground(String... params) { 
     String strTokenUrl = ctx.getResources().getString(R.string.oauth2_endpoint); 

     mHttppost = new HttpPost(); 
     try { 
      mHttppost.setURI(new URI(strTokenUrl)); 
     } 
     catch (URISyntaxException e1) { 
      e1.printStackTrace(); 
     } 
     List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(4); 
     nameValuePairs.add(new BasicNameValuePair("username", params[0])); 
     nameValuePairs.add(new BasicNameValuePair("password", params[1])); 
     nameValuePairs.add(new BasicNameValuePair("grant_type", "password")); 
     nameValuePairs.add(new BasicNameValuePair("client_id", "mobile")); 
//  nameValuePairs.add(new BasicNameValuePair("client_secret",)); 
     try { 
      String header = "Basic " + Base64.encodeToString(client_string.getBytes("UTF-8"), Base64.DEFAULT); 
      mHttppost.setHeader("Authorization", header); 
      mHttppost.setHeader("Content-Type", 
        "application/x-www-form-urlencoded;charset=UTF-8"); 
      mHttppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8")); 
     } 
     catch (UnsupportedEncodingException e) { 
      e.printStackTrace(); 
     } 

     HttpResponse response; 
     try { 
      response = mHttpclient.execute(mHttppost); 
     } catch (ClientProtocolException e) { 
      e.printStackTrace(); 
      response = null; 
     } catch (IOException e) { 
      e.printStackTrace(); 
      response = null; 
     } 

     JSONArray result = null; 
     try { 
      result = new JSONArray(EntityUtils.toString(response.getEntity())); 
     } catch (ParseException e) { 
      e.printStackTrace(); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return result; 
    } 
} 

当我执行,我得到一个400 - Bad request响应。另外,如果我试图抓住响应体用下面的代码

HttpEntity respEntity = response.getEntity(); 
    if(respEntity!=null) { 
     String res = EntityUtils.toString(respEntity); 
    } 

身体回来为空字符串 到目前为止,我无法在我的浏览器以重新让我有种毫无头绪的问题是什么可能。 有什么我从根本上做错了?任何提示调试这将不胜感激

如果服务器代码是必需的,我会发布它,但我认为问题是在应用程序,因为我可以在浏览器中执行请求。

回答

0

我想通了什么是问题。当你为你的请求添加一个头时出现,行尾字符只会导致POST请求的问题。解决方法是更改​​位掩码以确保行尾字符不存在。我换成这一行:

String header = "Basic " + Base64.encodeToString(client_string.getBytes("UTF-8"), Base64.DEFAULT); 

由:

String header = "Basic " + Base64.encodeToString(client_string.getBytes("UTF-8"), Base64.URL_SAFE|Base64.NO_WRAP);