You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin Forms调用Axelor Rest服务时持续返回401未授权状态

问题:Xamarin Forms连接Axelor服务器登录成功后调用接口返回401未授权

使用Xamarin Forms应用连接Axelor服务器,登录请求返回成功并获取到JSESSIONID,但后续调用数据接口时始终返回HTTP 401未授权状态,浏览器测试则可得到正确响应。相关代码如下:

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

问题原因与解决方法

1. Cookie处理逻辑错误

直接将响应头中的Set-Cookie添加到HttpClient默认请求头的方式不符合HTTP规范,Axelor服务器无法识别这种方式传递的JSESSIONID。浏览器会自动管理Cookie会话,但HttpClient需要通过CookieContainer来正确维护会话Cookie。

2. 修正后的代码

初始化HttpClient时配置CookieContainer,它会自动保存登录响应中的JSESSIONID,后续请求会自动携带该Cookie:

// 初始化带Cookie容器的HttpClient
var handler = new HttpClientHandler();
handler.CookieContainer = new CookieContainer();
var httpClient = new HttpClient(handler);

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

// 构建Basic认证字符串
byte[] bytes = Encoding.UTF8.GetBytes($"{login.UserName}:{login.Password}");
string authorizationString = Convert.ToBase64String(bytes);

// 添加Basic认证头
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authorizationString);

// 发送登录请求
string url = $"{Constants.RestBaseUrl}/{strRoot}";
var sessionResponse = await httpClient.PostAsync(url, null);

// 无需手动处理Set-Cookie,CookieContainer自动管理会话

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

var returnValue = await response.Content.ReadAsStringAsync();
var stat = response.StatusCode;
var cc = response.IsSuccessStatusCode;

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

3. 额外检查项

  • 确认Constants.RestBaseUrl与浏览器请求的地址完全一致,包括上下文路径(比如/Gradle___com_axelor___axelor_erp_6_3_0_war)
  • 检查Axelor服务器的跨域配置,确保允许Xamarin应用的访问来源
  • 验证登录端点login.jsp是否为Axelor对应版本的正确登录路径,部分版本可能使用/login端点

内容的提问来源于stack exchange,提问作者dal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 14:30:49