2012-03-12 56 views
0

我想使用Apache的示例代碼登錄到我的JBoss Web應用程序,但我不成功。 JBoss AS配置爲基於表單的身份驗證。有沒有人有一個想法,爲什麼它不工作?使用基於Apache的HttpClient的基於表單的JBoss身份驗證

public class ClientFormLogin { 

    public static void main(String[] args) throws Exception { 

     System.out.println("started with login..."); 

     DefaultHttpClient httpclient = new DefaultHttpClient(); 
     try { 
      HttpGet httpget = new HttpGet("url to requested website"); 


      HttpResponse response = httpclient.execute(httpget); 
      HttpEntity entity = response.getEntity(); 

      System.out.println("Login form get: " + response.getStatusLine()); 
      EntityUtils.consume(entity); 

      System.out.println("Initial set of cookies:"); 
      List<Cookie> cookies = httpclient.getCookieStore().getCookies(); 
      if (cookies.isEmpty()) { 
       System.out.println("None"); 
      } else { 
       for (int i = 0; i < cookies.size(); i++) { 
        System.out.println("- " + cookies.get(i).toString()); 
       } 
      } 

      HttpPost httpost = new HttpPost("url to the j_security_check page"); 

      List <NameValuePair> nvps = new ArrayList <NameValuePair>(); 
      nvps.add(new BasicNameValuePair("j_username", "my_username")); 
      nvps.add(new BasicNameValuePair("j_password", "my_password!")); 

      httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8)); 

      response = httpclient.execute(httpost); 
      entity = response.getEntity(); 

      System.out.println("Login form get: " + response.getStatusLine()); 
      EntityUtils.consume(entity); 

      System.out.println("Post logon cookies:"); 
      cookies = httpclient.getCookieStore().getCookies(); 
      if (cookies.isEmpty()) { 
       System.out.println("None"); 
      } else { 
       for (int i = 0; i < cookies.size(); i++) { 
        System.out.println("- " + cookies.get(i).toString()); 
       } 
      } 

     } finally { 
      // When HttpClient instance is no longer needed, 
      // shut down the connection manager to ensure 
      // immediate deallocation of all system resources 
      httpclient.getConnectionManager().shutdown(); 
     } 
    } 
} 

錯誤消息:

Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated 
    at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificates(Unknown Source) 
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128) 
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:397) 
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148) 
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:150) 
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121) 
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:575) 
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:425) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732) 
    at com.sicap.ssis.client.ClientFormLogin.main(ClientFormLogin.java:57) 

回答

-1

這是解決方案:

添加新類:

import java.io.IOException; 
import java.security.cert.X509Certificate; 

import javax.net.ssl.SSLContext; 
import javax.net.ssl.SSLException; 
import javax.net.ssl.SSLSession; 
import javax.net.ssl.SSLSocket; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.X509TrustManager; 

import org.apache.http.client.HttpClient; 
import org.apache.http.conn.ClientConnectionManager; 
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.conn.ssl.X509HostnameVerifier; 
import org.apache.http.impl.client.DefaultHttpClient; 

/* 
This code is public domain: you are free to use, link and/or modify it in any way you want, for all purposes including commercial applications. 
*/ 
public class WebClientDevWrapper { 

    @SuppressWarnings("deprecation") 
    public static HttpClient wrapClient(HttpClient base) { 
     try { 
      SSLContext ctx = SSLContext.getInstance("TLS"); 
      X509TrustManager tm = new X509TrustManager() { 

       public void checkClientTrusted(X509Certificate[] xcs, 
         String string) { 
       } 

       public void checkServerTrusted(X509Certificate[] xcs, 
         String string) { 
       } 

       public X509Certificate[] getAcceptedIssuers() { 
        return null; 
       } 
      }; 
      X509HostnameVerifier verifier = new X509HostnameVerifier() { 

       @Override 
       public void verify(String string, SSLSocket ssls) 
         throws IOException { 
       } 

       @Override 
       public void verify(String string, X509Certificate xc) 
         throws SSLException { 
       } 

       @Override 
       public void verify(String string, String[] strings, 
         String[] strings1) throws SSLException { 
       } 

       @Override 
       public boolean verify(String string, SSLSession ssls) { 
        return true; 
       } 
      }; 
      ctx.init(null, new TrustManager[] { tm }, null); 
      SSLSocketFactory ssf = new SSLSocketFactory(ctx); 
      ssf.setHostnameVerifier(verifier); 
      ClientConnectionManager ccm = base.getConnectionManager(); 
      SchemeRegistry sr = ccm.getSchemeRegistry(); 
      sr.register(new Scheme("https", ssf, 443)); 
      return new DefaultHttpClient(ccm, base.getParams()); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
      return null; 
     } 
    } 
} 

現在周圍添加HttpClient的包裝:

DefaultHttpClient httpclient = new DefaultHttpClient(); 
httpclient = (DefaultHttpClient) WebClientDevWrapper.wrapClient(httpclient); 

現在如何確定登錄是否成功?

boolean loginSuccess = false; 

    Header[] locationHeader = response.getHeaders("Location"); 
    if (locationHeader.length > 0) { 
      if (response.getStatusLine().toString().contains("302") && locationHeader[0].toString().endsWith(requestURL)) { 
       loginSuccess=true; 
      } 
    } 
    System.out.println("Login Success: " + loginSuccess); 

如果位置標題等於您請求的URL並且登錄表單獲取包含302,則登錄成功。如果您設置了錯誤的用戶名或密碼,則可以檢查該信息,否則登錄將失敗。

希望這會有所幫助。

相關問題