2014-11-22 66 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); 
相關問題