2014-10-09 2 views
1

Я пытаюсь использовать Bonita Web API. I Мой код ниже. Как вы можете видеть, я вызываю loginservice перед вызовом любой другой службы API. Он регистрируется в OK 200. Но когда я делаю последующий вызов, чтобы получить список процессов, я получаю ошибку 401. Вы получаете JSESSIONID от первого вызова, и вы можете передать его на последующие вызовы для аутентификации.Bonita Web API - 401 Несанкционированная ошибка

var baseAddress = new Uri(<base address>); 
var cookieContainer = new CookieContainer(); 
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer }) 
using (var client = new HttpClient(handler) { BaseAddress = baseAddress }) 
    { 
      HttpResponseMessage result = client.PostAsync("/bonita/loginservice", new StringContent("login=<username>,password=<password>,redirect=false")).Result; 
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
      HttpResponseMessage result2 = client.GetAsync("/bonita/API/bpm/process").Result; 
      result2.EnsureSuccessStatusCode(); 
    } 

ответ

2

Это работает для .Net 2.0 C#, но есть интересные вещи для проверки.

WebClient wc = new WebClient(); 
wc.Proxy = WebRequest.GetSystemWebProxy(); 
//wc.Headers[HttpRequestHeader.AcceptEncoding] = "gzip, deflate"; 
string strLogin = wc.DownloadString("http://localhost:8080/bonita/loginservice?username=walter.bates&password=bpm&redirect=false"); 

wc.Headers[HttpRequestHeader.Cookie] = wc.ResponseHeaders[HttpResponseHeader.SetCookie].ToString(); 
string strCookie = wc.ResponseHeaders[HttpResponseHeader.SetCookie].ToString(); 

string strProcesses = wc.DownloadString("http://localhost:8080/bonita/API/bpm/process?p=0"); 

Прежде всего, вы должны знать, как определить, что выполняется операция прошла успешно (логин, getProcesses и все) При попытке войти в систему, вы всегда получите заголовок (например "JSESSIONID=50E509D37AC28E2D725CBD45A8112FA7; Path=/bonita; HttpOnly") и OK 200, даже если ваша попытка входа в Bonita не увенчалась успехом.

Для успешной регистрации на предыдущем примере

1) Вы должны пройти обязательную форму данные: имя пользователя, пароль и перенаправлять Вы также должны быть уверены, чтобы передать перенаправлять в нижнем регистре. "False" не будет работать, "false" будет работать. Поэтому для .Net предположим, что у вас есть перенаправление property-> Boolean. Вы должны сделать это в нижнем регистре с redirect.ToString().ToLower(), потому что в любом случае значение будет "False", и вы этого не хотите.

Предположим, вы пытаетесь войти только с именем пользователя и паролем без переадресации. в результате вы получите как OK 200, так и заголовок, но вы также получите ответ, который является неправильным (ответ должен быть пустым), поэтому при следующем запросе (например, getProcesses) вы получите (401) Unauthorized. Угадайте результаты, которые вы получите, если пройдете redirect=False вместо redirect=false. Точно так же.

2) Вы должны получить: strLogin="" // the body of the response must be empty strCookie="JSESSIONID=4F67F134840A2C72DBB968D53772FB22; Path=/bonita; HttpOnly"

Для успешного getProcesses на предыдущем примере вы передаете заголовок, который вы получили от входа

wc.Headers[HttpRequestHeader.Cookie] = wc.ResponseHeaders[HttpResponseHeader.SetCookie].ToString(); 

, а затем вы называете этот процесс и получить строку в формате JSON формат, например

"[{\"id\":\"6996906669894804403\",\"icon\":\"\",\"displayDescription\":\"\",\"deploymentDate\":\"2014-11-19 17:57:40.893\",\"description\":\"\",\"activationState\":\"ENABLED\",\"name\":\"Travel request\",\"deployedBy\":\"22\",\"displayName\":\"Travel request\",\"actorinitiatorid\":\"4\",\"last_update_date\":\"2014-11-19 17:57:41.753\",\"configurationState\":\"RESOLVED\",\"version\":\"1.0\"}]" 

(или [], что означает пустой JSON)

Если cookie не передан правильно, вы снова получите ошибку 401.

решение для .Net 4.5.1

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.IO; 
using System.Linq; 
using System.Net; 
using System.Net.Http; 
using System.Net.Http.Headers; 
using System.Text; 
using System.Threading.Tasks; 
using System.Web; 


namespace BonitaRestApi 
{ 
    class BonitaApi 
    { 
     private CookieCollection collection; 
     string strCookietoPass; 
     string sessionID; 

     static void Main(string[] args) 
     { 
      BonitaApi obj = new BonitaApi(); 
      Task login = new Task(obj.Login); 
      login.Start(); 
      login.Wait(); 
      Console.ReadLine(); 

      Task GetProcesses = new Task(obj.GetProcesses); 
      GetProcesses.Start(); 
      GetProcesses.Wait(); 
      Console.ReadLine(); 

      Task logout = new Task(obj.Logout); 
      logout.Start(); 
      logout.Wait(); 
      Console.ReadLine(); 

     } 

     public async void Login() 
     { 
      const string url = "http://localhost:8080/bonita/"; 

      var cookies = new CookieContainer(); 
      var handler = new HttpClientHandler(); 
      handler.CookieContainer = cookies; 

      using (var client = new HttpClient(handler)) 
      { 
       var uri = new Uri(url); 
       client.BaseAddress = uri; 
       //client.DefaultRequestHeaders.Accept.Clear(); 
       //client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

       var content = new FormUrlEncodedContent(new[] 
       { 
        new KeyValuePair<string, string>("username", "helen.kelly"), 
        new KeyValuePair<string, string>("password", "bpm"), 
        new KeyValuePair<string, string>("redirect", "false"), 
        new KeyValuePair<string, string>("redirectUrl", ""), 
       }); 

       HttpResponseMessage response = await client.PostAsync("loginservice", content); 

       if (response.IsSuccessStatusCode) 
       { 
        var responseBodyAsText = await response.Content.ReadAsStringAsync(); 

        if (!String.IsNullOrEmpty(responseBodyAsText)) 
        { 
         Console.WriteLine("Unsuccessful Login.Bonita bundle may not have been started, or the URL is invalid."); 
         return; 
        } 

        collection= cookies.GetCookies(uri); 
        strCookietoPass = response.Headers.GetValues("Set-Cookie").FirstOrDefault(); 

        sessionID = collection["JSESSIONID"].ToString(); 

        Console.WriteLine(string.Format("Successful Login Retrieved session ID {0}", sessionID)); 
         // Do useful work 
       } 
       else 
       { 
        Console.WriteLine("Login Error" + (int)response.StatusCode + "," + response.ReasonPhrase); 
       } 

      } 
     } 

     public async void Logout() 
     { 
      const string url = "http://localhost:8080/bonita/"; 

      var cookies = new CookieContainer(); 
      var handler = new HttpClientHandler(); 
      handler.CookieContainer = cookies; 

      using (var client = new HttpClient(handler)) 
      { 
       var uri = new Uri(url); 
       client.BaseAddress = uri; 

       var content = new FormUrlEncodedContent(new[] 
       { 
        new KeyValuePair<string, string>("redirect", "false") 
       }); 

       HttpResponseMessage response = await client.PostAsync("logoutservice", content); 

       if (response.IsSuccessStatusCode) 
       { 
        var responseBodyText = await response.Content.ReadAsStringAsync(); 

        if (!String.IsNullOrEmpty(responseBodyText)) 
        { 
         Console.WriteLine("Unsuccessful Logout.Bonita bundle may not have been started, or the URL is invalid."); 
         return; 
        } 

        Console.WriteLine("Successfully Logged out."); 
       } 
       else 
       { 
        Console.WriteLine("Logout Error" + (int)response.StatusCode + "," + response.ReasonPhrase); 
       } 

      } 
     } 

     public async void GetProcesses() 
     { 

      var handler = new HttpClientHandler(); 

      Cookie ok = new Cookie("Set-Cookie:",strCookietoPass); 

      handler.CookieContainer.Add(collection); 

      using (var client = new HttpClient(handler)) 
      { 

       var builder = new UriBuilder("http://localhost/bonita/API/bpm/process"); 
       builder.Port = 8080; 

       var query = HttpUtility.ParseQueryString(builder.Query); 
       query["p"] = "0"; 
       query["c"] = "10"; 
       builder.Query = query.ToString(); 

       Uri uri= new Uri(builder.ToString()); 
       client.BaseAddress = uri; 

       HttpResponseMessage response = await client.GetAsync(uri.ToString()); 

       if (response.IsSuccessStatusCode) 
       { 
        var responseBodyText = await response.Content.ReadAsStringAsync(); 

        if (String.IsNullOrEmpty(responseBodyText)) 
        { 
         Console.WriteLine("Unsuccessful GetProcesses.Bonita bundle may not have been started, or the URL is invalid."); 
         return; 
        } 

        Console.WriteLine("Successfully GetProcesses:" + responseBodyText); 

       } 
       else 
       { 
        Console.WriteLine("GetProcesses Error" + (int)response.StatusCode + "," + response.ReasonPhrase); 
       } 

      } 
     } 
    } 
} 
1

У меня была такая же проблема (401 ошибок) для каждого отдельного запроса, не GET.

я, наконец, получил через это, глядя в документации CSRF: http://documentation.bonitasoft.com/7.4?page=csrf-security

(см «Есть ли влияние на вызовы REST API?раздел ")

После входа в систему успешным, вы должны поместить специальный заголовок в запросе:.

key: X-Bonita-API-Token 

value: the one you got after your login (check the relevant cookie) 
+0

Weird почему такая важная деталь, не упоминается нигде в начальной странице использования API док Спасибо за это Помогите! – buer

Смежные вопросы