Как войти на сайт используя Java - PullRequest
6 голосов
/ 22 июня 2010

Я хочу получить доступ к некоторым страницам веб-сайта 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 ]

9 голосов
/ 22 июня 2010

Сначала - пожалуйста, не называйте свою 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) к вашему PostMethod и убедитесь, что вы отправляете на правильный URL-адрес.

1 голос
/ 23 июня 2010

Если на этом сайте используется аутентификация Siteminder, вы не сможете войти в систему именно так. Siteminder использует куки для идентификации аутентифицированных сеансов. Эти куки действительны только до тех пор, пока ваша сессия жива. Если вы не вошли в систему, то сервер перенаправит вас на страницу входа в Siteminder (следовательно, перенаправление). Поэтому вам нужно будет выполнить перенаправление, отправить свои учетные данные (имя пользователя / пароль), а затем снова выполнить перенаправление, отправив полученные файлы cookie.

Я записал сеансы для регрессионных тестов, используя The Grinder (http://grinder.sourceforge.net/),), и он смог автоматически зайти на защищенный сайт Siteminder! Так что это определенно возможно, но вам придется сделать немного больше, чем просто отправить HTTP-запрос ...

Лучшим решением была бы какая-то другая аутентификация, например аутентификация на основе сертификатов (но, конечно, она должна быть настроена и на стороне сервера, так что в этом случае это может быть не вариант). Почему бы не спросить BT, предоставляют ли они другие методы аутентификации?

EDIT: Я только что нашел это: http://www.codeproject.com/KB/IP/SiteminderHttpWebRequest.aspx Исходный код на VB, но статья отличная, и не должно быть никаких проблем с переводом кода VB на Java ...; -)

0 голосов
/ 08 июля 2014

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<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());
            }
        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...