如何使用Java登录网站

我想访问网站https://myoffice.bt.com的某些页面,这需要使用java进行用户身份validation。 我们必须先登录才能访问页面。 我有以下代码的wriiten。

package root; import java.io.IOException; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.params.HttpMethodParams; public class Url { public static void main(String[] args) throws IOException { HttpClient client = new HttpClient(); client.getParams().setParameter( HttpMethodParams.USER_AGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2" ); client.getState().setCredentials( new AuthScope("https://myoffice.bt.com", 443, AuthScope.ANY_REALM), new UsernamePasswordCredentials("username", "password") ); PostMethod get = new PostMethod("https://myoffice.bt.com/youraccount/default.aspx"); get.setDoAuthentication( true ); System.out.println(get.getFollowRedirects()); //get.setFollowRedirects(true); try { // execute the GET int status = client.executeMethod( get ); // print the status and response System.out.println(status + "\n" + get.getResponseBodyAsString()); } finally { // release any connection resources used by the method get.releaseConnection(); } } } 

但它给出了以下错误。

 > Jun 22, 2010 12:14:40 PM org.apache.commons.httpclient.HttpMethodDirector isRedirectNeeded INFO: Redirect requested but followRedirects is disabled 302 

如果我取消注释get.setFollowingRedirects行,则会出现另一个错误。

 Exception in thread "main" java.lang.IllegalArgumentException: Entity enclosing requests cannot be redirected without user intervention at org.apache.commons.httpclient.methods.EntityEnclosingMethod.setFollowRedirects(Unknown Source) at root.Url.main(Url.java:30) 

有人能帮我一下吗? 我们可以使用HttpClient进行基于表单的身份validation吗?

谢谢。

首先 – 请不要命名你的PostMethod变量get

其次,试试这个:

 PostMethod post = new PostMethod("yourUrl") { @Override public boolean getFollowRedirects() { return true; } }; 

如果您碰巧遇到“另一方”并希望阻止您的用户受到影响, 303 (See Other)在将POST请求重定向到GET时使用响应代码303 (See Other) ,而不是使用公共302301 (根据RFC ) 。 常规浏览器往往很好,违反规则而不是要求我们确认这些重定向,但很多移动浏览器仍然可以。

关于基于表单的身份validation的问题 – 您只需要找出要使用的参数名称(例如,查看“通常”登录的网站的来源),然后使用适当的值填充它们:

 post.addParameter("username", username); post.addParameter("password", password); 

我在myoffice.bt.com上使用了登录表单,JavaScript中有一些内容。

表格提交至https://myoffice.bt.com/siteminderagent/forms/login.fcc

提交的表单元素如下( name=value ,某些值为空):

 Segment=btb.hub SubSegment= searchType=0 searchPlatform=BEA lob=btb.hub queryText= searchText= ctl00$masterWebpartManager$gwpCustomLogin1$CustomLogin1$UserName=your@email.com ctl00$masterWebpartManager$gwpCustomLogin1$CustomLogin1$PWD=yourpwd ctl00$masterWebpartManager$gwpCustomLogin1$CustomLogin1$RememberMe=on USER=your@email.com PASSWORD=yourpwd SMENC=ISO-8859-1 SMLOCALE=US-EN userFirstLoginUrl=https://myoffice.bt.com/ManageBusinessApplications/SecretQA.aspx PrivateLoginSuccessUrl=https://myoffice.bt.com/sm/privatecreatesession.aspx?siteArea=btb.mya PublicLoginSuccessUrl=https://myoffice.bt.com/sm/createsession.aspx?siteArea=btb.mya target=https://myoffice.bt.com/sm/privatecreatesession.aspx?siteArea=btb.mya&TARGET=https%3a%2f%2fmyoffice.bt.com%2fdefault.aspx (hidden) submitStatus= smauthreason= smagentname= postpreservationdata= AnonUserName=anon@myoffice.bt.com authMode=SITEMINDER smUrl=https://myoffice.bt.com/siteminderagent/forms/login.fcc notSMUrl=https://myoffice.bt.com/default.aspx smIdentifier=1 

尝试将部分或全部(至少USERPASSWORD )添加到PostMethod ,并确保提交到正确的URL。

如果该网站使用Siteminder身份validation,您将无法像这样登录。 Siteminder使用cookie来识别经过身份validation的会话。 这些cookie仅在您的会话处于活动状态时才有效。 如果您尚未登录,则服务器会将您重定向到Siteminder登录页面(因此重定向)。 因此,您需要做的是按照重定向,发送您的凭据(用户名/密码),然后再次按照重定向,发送收到的cookie。

我使用The Grinder( http://grinder.sourceforge.net/ )记录了回归测试的会话,并且能够自动登录到Siteminder受保护的网站! 所以这绝对是可能的,但你必须做的不仅仅是发送一个HTTP请求……

最好的解决方案是某种其他身份validation,例如基于证书的身份validation(当然,这也必须在服务器端配置,因此在这种情况下这可能不是一个选项)。 为什么不问BT是否提供其他身份validation方法?

编辑:我刚刚发现这个: http : //www.codeproject.com/KB/IP/SiteminderHttpWebRequest.aspx源代码在VB中,但文章很好,将VB代码翻译成应该没问题Java …… 😉

Java版本:适用于siteminder受保护的资源,使用公共httpClient 4.3.3进行测试

 import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.List; import javax.net.ssl.SSLContext; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.methods.RequestBuilder; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.LaxRedirectStrategy; import org.apache.http.util.EntityUtils; public class AccessSiteminderProtectedResource { private static final String PASSWORD = "pwd"; private static final String USER_NAME = "userId"; private static final String SITEMINDER_PROTECTED_RESOURCE = "protectedResource"; private static final String SITEMINDER_LOGIN_URL = "siteMinderLoginUrl?TARGET=-SM-" + SITEMINDER_PROTECTED_RESOURCE; public static void main(String[] args) throws Exception { BasicCookieStore cookieStore = new BasicCookieStore(); SSLContext sslcontext = buildSSLContext(); SSLConnectionSocketFactory sslsf = buildSSLConnectionSocketFactory(sslcontext); CloseableHttpClient httpclient = buildHttpClient(cookieStore, sslsf); try { String nextLocation = executeLogin(cookieStore, httpclient); accessApp(httpclient, nextLocation); } finally { httpclient.close(); } } private static SSLContext buildSSLContext() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException { SSLContext sslcontext = SSLContexts.custom() .setSecureRandom(new SecureRandom()) .loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(); return sslcontext; } private static SSLConnectionSocketFactory buildSSLConnectionSocketFactory( SSLContext sslcontext) { SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); return sslsf; } private static CloseableHttpClient buildHttpClient( BasicCookieStore cookieStore, SSLConnectionSocketFactory sslsf) { CloseableHttpClient httpclient = HttpClients.custom() .setSSLSocketFactory(sslsf).setDefaultCookieStore(cookieStore) .setRedirectStrategy(new LaxRedirectStrategy()) .build(); return httpclient; } private static String executeLogin(BasicCookieStore cookieStore, CloseableHttpClient httpclient) throws URISyntaxException, IOException, ClientProtocolException { HttpUriRequest loginPost = RequestBuilder .post() .setUri(new URI(SITEMINDER_LOGIN_URL)) .addParameter("USER", USER_NAME) .addParameter("PASSWORD", PASSWORD).build(); System.out.println("executing request" + loginPost.getRequestLine() + "\n"); CloseableHttpResponse loginResponse = httpclient.execute(loginPost); String nexLocation; try { HttpEntity loginResponseEntity = loginResponse.getEntity(); System.out.println("Login form post Status: " + loginResponse.getStatusLine()); EntityUtils.consume(loginResponseEntity); System.out.println(); System.out.println("Post logon cookies:"); System.out.println(); displayCookies(cookieStore); System.out.println(); System.out.println(); System.out.println("Login Post Headers----------------------------------------"); displayHeaders(loginResponse); System.out.println(); System.out.println(); nexLocation = SITEMINDER_PROTECTED_RESOURCE; } finally { loginResponse.close(); } return nexLocation; } private static void accessApp(CloseableHttpClient httpclient, String nextLocation) throws IOException, ClientProtocolException { HttpGet appGet = new HttpGet(nextLocation); System.out.println("executing request" + appGet.getRequestLine()); CloseableHttpResponse response = httpclient.execute(appGet); try { HttpEntity entity = response.getEntity(); System.out.println("\n\n\n\n---------------------------------------- \n"); System.out.println("App Get Status: " + response.getStatusLine()); System.out.println(EntityUtils.toString(entity)); EntityUtils.consume(entity); } finally { response.close(); } } private static void displayHeaders(CloseableHttpResponse loginResponse) { for (Header header : loginResponse.getAllHeaders()) { System.out.println(header); } } private static void displayCookies(BasicCookieStore cookieStore) { List cookies = cookieStore.getCookies(); if (cookies.isEmpty()) { System.out.println("None"); } else { for (int i = 0; i < cookies.size(); i++) { System.out.println("- " + cookies.get(i).toString()); } } } } 
Interesting Posts