代码之家  ›  专栏  ›  技术社区  ›  RandomQuestion

如何使用Java登录网站

  •  6
  • RandomQuestion  · 技术社区  · 16 年前

    我想访问一些网站页面 https://myoffice.bt.com 这需要使用Java进行用户身份验证。我们必须先登录才能访问页面。我的手腕按密码。

    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进行基于表单的身份验证吗?

    谢谢。

    3 回复  |  直到 12 年前
        1
  •  9
  •   Lauri Lehtinen    16 年前

    首先-请不要说出你的名字 PostMethod 变量 get .

    第二,试试这个:

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

    如果您碰巧处于“另一方”,并且想要防止您的用户遭受痛苦,请使用响应代码 303 (See Other) 重定向时 POST 请求给 GET 而不是普通的 302 301 (每) RFC )常规浏览器往往很好,违反规则,不要求我们确认这些重定向,但许多移动浏览器仍然可以。

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

    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
    

    尝试添加一些或全部这些(至少 USER PASSWORD 对你 后方法 ,并确保提交到正确的URL。

        2
  •  1
  •   egbokul    16 年前

    如果该网站使用SiteMinder身份验证,您将无法像这样登录。SiteMinder使用cookie来标识经过验证的会话。这些cookie只有在会话处于活动状态时才有效。 如果您没有登录,那么服务器会将您重定向到SiteMinder登录页面(因此重定向)。 因此,您需要做的是遵循重定向,发送您的凭证(用户名/密码),然后再次遵循重定向,发送收到的cookie。

    我用研磨机记录了回归测试的会话。( http://grinder.sourceforge.net/ ,它能够自动登录到SiteMinder保护的网站!所以这是绝对有可能的,但是你需要做的不仅仅是发送一个HTTP请求…

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

    编辑: 我刚找到这个: http://www.codeproject.com/KB/IP/SiteminderHttpWebRequest.aspx 源代码在VB中,但是文章很好,把VB代码翻译成Java应该没问题。;-)

        3
  •  0
  •   craftsmannadeem    12 年前

    Java版本:与SITEMWELD保护的资源协同工作,用公钥HTTPclipse 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<Cookie> 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());
                }
            }
        }
    
    }