如何使用Jsoup进行JIRA登录?

问题描述:

我一直在尝试使用Jsoup API登录到JIRA,但由于某种原因它不工作。如何使用Jsoup进行JIRA登录?

我试图找出用户名和密码标签,但仍然没有好处。

有人能帮我弄清楚我做错了什么吗?

public class test 
{ 
public static void main(String[] args) throws IOException{ 
    final String USER_AGENT = "\"Mozilla/5.0 (Windows NT\" +\n" + 
    "   \" 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36\""; 
    String loginFormUrl = "https://jira.aciworldwide.com/login.jsp"; 
    String loginActionUrl = "https://jira.aciworldwide.com/login.jsp"; 
    String username = "[email protected]"; 
    String password = "XXXXXX"; 

    HashMap<String, String> cookies = new HashMap<>(); 
    HashMap<String, String> formData = new HashMap<>(); 

    Connection.Response loginForm = Jsoup.connect(loginFormUrl).method(Connection.Method.GET).userAgent(USER_AGENT).execute(); 
    Document loginDoc = loginForm.parse(); // this is the document that contains response html 

    cookies.putAll(loginForm.cookies()); // save the cookies, this will be passed on to next request 

    formData.put("login", "Log In"); 
    formData.put("os_username", username); 
    formData.put("os_password", password); 

    Connection.Response homePage = Jsoup.connect(loginActionUrl) 
     .cookies(cookies) 
     .data(formData) 
     .method(Connection.Method.POST) 
     .userAgent(USER_AGENT) 
     .execute(); 

    System.out.println(homePage.parse().html()); 


    } 
} 

如果不是JSoup,是否还有其他可用的API?

任何帮助将不胜感激!

+0

你可以添加一些堆栈跟踪或输出,“但仍然没有好”相关: getFullName只是搜索的服务器响应的全名(全成登录全名后会出现在响应)的方法?你得到了什么结果/错误? – exoddus

+1

为什么不使用jira的rest api? – slowy

+0

我被要求只使用JAVA。 –

你是在正确的方向,但有时“伪造”一些webapps的登录过程可能是相当棘手或难以成功,因为你缺少设置一个特定的标题,cookie或一些特殊的参数...

如果你看看Jira的documentation,你会发现很多例子。除了将用户名和密码作为表单发送外,您最好还是使用REST POST来获取有效的Cookie。

如在文档表示:

  • (1)客户端为用户创建新的会话,经由JIRA REST API。
  • (2)JIRA返回一个会话对象,其中包含会话信息,包括会话cookie。客户端存储这个会话对象。 (3)客户现在可以在标题中为所有对JIRA REST API的后续请求设置cookie。

我已经创建了用于测试的简单类,我已经确保正在与吉拉(不知道有什么版本,但可能是最后一个)。

import org.jsoup.Connection.Method; 
import org.jsoup.Connection.Response; 
import org.jsoup.Jsoup; 
import org.jsoup.nodes.Document; 
import org.jsoup.nodes.Element; 

import java.io.IOException; 
import java.util.Map; 
import java.util.Optional; 

public class JiraLogin { 

private final static String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"; 
private final static String JIRA_REST_LOGIN = "https://youdomain.com/rest/auth/1/session"; 

private final static String HOME_URL = "https://youdomain.com/"; 
private final static String USERNAME = "your_username"; 
private final static String PASSWORD = "your_password"; 

public static void main(String[] args) throws IOException { 
    JiraLogin app = new JiraLogin(); 
    app.doLogin(); 
} 

public void doLogin() throws IOException { 
    // (1) 
    Response postResult = doLoginPost(); 
    System.out.println("POST credentials result: " + postResult.body()); 
    // (2) 
    Map<String, String> cookies = postResult.cookies(); 

    Document loggedDocument = Jsoup.connect(HOME_URL) 
      .cookies(cookies) // (3) 
      .method(Method.GET) 
      .userAgent(USER_AGENT) 
      .validateTLSCertificates(false) 
      .get(); 

    System.out.println("FullName: " + getFullName(loggedDocument)); 
} 

private Response doLoginPost() throws IOException { 
    return Jsoup.connect(JIRA_REST_LOGIN) 
      .validateTLSCertificates(false) 
      .method(Method.POST) 
      // if use regular USER_AGENT gets a 403 error 
      // http://*.com/questions/10120849/jsoup-connect-throws-403-error-while-apache-httpclient-is-able-to-fetch-the-cont 
      .userAgent("Mozilla") 
      .ignoreContentType(true) 
      .requestBody("{ \"username\": \"" + USERNAME +"\", \"password\": \"" + PASSWORD +"\" }") 
      .header("Content-Type", "application/json") 
      .execute(); 
} 

private String getFullName(Document document) { 
    Optional<Element> fullNameOpt = document.getElementsByTag("meta") 
      .stream() 
      .filter(e -> e.hasAttr("name") && "ajs-remote-user-fullname".equals(e.attr("name"))).findFirst(); 

    return fullNameOpt.isPresent() ? fullNameOpt.get().attr("content") : "Not found"; 
} 

}