Search code examples
c#web-servicesxamarin.formsrestful-authenticationaxelor

Unauthorized status from mobile Xamarin Forms application with Axelor Rest web-services


I want to connect to the Axelor server with a Xamarin forms application, I use this method to test the rest services connectivity :

                Login login = new()
                {
                    UserName = Constants.Login,
                    Password = Constants.Password
                };

                // Build authentication string
                byte[] bytes = Encoding.UTF8.GetBytes($"{login.UserName}:{login.Password}");
                string authorizationString = Convert.ToBase64String(bytes);

                // Add headers to the HTTP client
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authorizationString);

                // Build HTTP message and send, strRoot = login.jsp
                string url = $"{Constants.RestBaseUrl}/{strRoot}";
                HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post, url);
                var sessionResponse = await httpClient.SendAsync(message);

                /* sessionResponse.IsSuccessStatusCode = true, and sessionResponse.Headers =
                 {
                     Set-Cookie: JSESSIONID=E5EA31C3A5CBDF0A1C4B05ED2230679E; Path=/Gradle___com_axelor___axelor_erp_6_3_0_war; HttpOnly
                     Date: Mon, 14 Nov 2022 19:40:04 GMT
                 }
                 */
                sessionResponse.Headers.ToList().ForEach(x =>
                httpClient.DefaultRequestHeaders.Add(x.Key, x.Value.FirstOrDefault()));


                var rt = $"{Constants.RestBaseUrl}/ws/rest/com.axelor.apps.poultryfarming.db.Hatchery";
                var response = await httpClient.GetAsync(rt);

                var returnValue = await response.Content.ReadAsStringAsync();
                /* returnValue : 
                 <!doctype html><html lang="en"><head><title>HTTP Status 401 – Unauthorized</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 401 – Unauthorized</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The request has not been applied because it lacks valid authentication credentials for the target resource.</p><hr class="line" /><h3>Apache Tomcat/8.5.73</h3></body></html>
                 */
                var stat = response.StatusCode; // return: Unauthorized
                var cc = response.IsSuccessStatusCode;

                return returnValue;
            }
            catch (Exception e)
            {                
                throw;
            }

but i always get the Unauthorized status !

Can you help me please

When I test with navigator I have correct response like this :


Solution

  • It works well with RestSharp.RestRequest!

    Call Axelor rest services with RestClient example : https://github.com/dalmed/Maui-Axelor-Mobile.git

    This is my solution :

    public class RestClientService : IRestClientService
    {
        //private readonly ILogger<RestClientService> _logger;
        public RestClientService()
        {
            //_logger = logger;
        }
    
        public async Task<bool> LoginAsync(Login login)
        {
            string jsonString = JsonSerializer.Serialize(login);
            try
            {
                Constants.Cookies = null;
                Constants.IsServerConnected = false;
    
                var uri = new Uri($"{Constants.RestBaseUrl}/login.jsp");
                var _RestClient = new RestClient(uri);
                var request = new RestRequest(uri, Method.Post);
                request.AddHeader("Content-Type", "application/json");
    
                request.AddParameter("application/json", login, ParameterType.RequestBody);
    
                RestResponse response = await _RestClient.ExecuteAsync(request);
    
                if (response.IsSuccessStatusCode)
                {
                    Constants.Cookies = response.Cookies;
                    Constants.IsServerConnected = true;
                }
                return response.IsSuccessStatusCode;
            }
            catch (Exception e)
            {
               // _logger.LogError(e, "LoginError");
                throw;
            }
        }
    
        public async Task<RootData<T>> RestServiceGetAsync<T>(string model, int offset = 0, int limit = 10)
        {
            try
            {
                var uri = $"{Constants.RestBaseUrl}/ws/rest/{model}";
                var _RestClient = new RestClient(uri);
                var request = new RestRequest(uri, Method.Get);
    
                request.AddHeader("Content-Type", "application/json");
    
                if (Constants.Cookies.Any() && Constants.IsServerConnected)
                {
                    string cookie = "";
                    Constants.Cookies.ToList().ForEach(x => cookie += $"{x.Name}={x.Value}; ");
                    request.AddHeader("Cookie", cookie);
                }
                else
                {
                    throw new Exception("The server is not connected !");
                }
    
                request.AddParameter("offset", offset, ParameterType.UrlSegment);
                request.AddParameter("limit", limit, ParameterType.UrlSegment);
    
                RestResponse response = await _RestClient.ExecuteAsync(request);
    
                if (response.IsSuccessStatusCode)
                {
                    var data = new MemoryStream(Encoding.UTF8.GetBytes(response.Content));
                    var rslt = await JsonSerializer.DeserializeAsync<RootData<T>>(data);
                    return rslt;
                }
                return null;
    
            }
            catch (Exception e)
            {
                //_logger.LogError(e, $"GetModelError: {model}");
                throw;
            }
        }
    
        public async Task<bool> LogoutAsync()
        {
            try
            {
                var uri = $"{Constants.RestBaseUrl}/logout";
                var _RestClient = new RestClient(uri);
                var request = new RestRequest(uri, Method.Get);
    
                request.AddHeader("Content-Type", "application/json");
    
                if (Constants.Cookies.Any() && Constants.IsServerConnected)
                {
                    string cookie = "";
                    Constants.Cookies.ToList().ForEach(x => cookie += $"{x.Name}={x.Value}; ");
                    request.AddHeader("Cookie", cookie);
                }
                else
                {
                    throw new Exception("The server is not connected !");
                }
    
                RestResponse response = await _RestClient.ExecuteAsync(request);
                return response.IsSuccessStatusCode;
            }
            catch (Exception e)
            {
                //_logger.LogError(e, "LogoutError");
                throw;
            }
        }
    }