在另一个 Xero 组织的用户授权我的应用程序后,我真的一直在努力交换从 Xero 收到的代码。
无论我尝试什么,我始终收到 400 - 错误请求,出于明显的安全原因,“错误请求”是响应中的所有信息。
我尝试过使用
StringContent
。设置 HttpClient
的接受标头。使用 httpClient.PostAsync()
。
这是请求标头和正文需要包含的内容:
POST https://identity.xero.com/connect/token
authorization: "Basic " + base64encode(client_id + ":" + client_secret)
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=xxxxxx
&redirect_uri=https://myapp.com/redirect
其中 xxxxx 是返回给回调方法的代码。
下面是我的服务中处理应用程序授权回调的方法。如果有人能指出我做得不对的地方,我将非常感激。
public async Task<string> AuthoriseApp(string code, string state)
{
try
{
var clientState = TokenUtilities.GetCurrentState();
if (state != clientState)
{
return "Cross site forgery attack detected!";
}
var paramss = new Dictionary<string, string>
{
{ "grant_type", "authorization_code" },
{ "code", code },
{ "redirect_uri", xeroConfig.CallbackUri.AbsoluteUri }
};
var body = new FormUrlEncodedContent(paramss);
var httpClient = new HttpClient();
using var requestMessage = new HttpRequestMessage(HttpMethod.Post, xeroConfig.XeroIdentityBaseUri + "/connect/token")
{
Content = body
};
requestMessage.Headers.Authorization = new BasicAuthenticationHeaderValue(xeroConfig.ClientId, xeroConfig.ClientSecret);
var response = await httpClient.SendAsync(requestMessage);
return "Success"; // This will change when I actually receive a 200 and the access token
}
catch (Exception ex)
{
logger.LogError(ex.Message);
return ex.Message;
}
}
提前致谢
乔恩
这对我有用 - 经过一番挣扎。
async Task<TokenResponseModel> GetAccessTokenAsync(string authCode)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var parameters = new Dictionary<string, string>
{
{ "grant_type", "authorization_code" },
{ "code", authCode },
{ "redirect_uri", redirectUri }
};
var body = new FormUrlEncodedContent(parameters);
var httpClient = new HttpClient();
string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{clientId}:{clientSecret}"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
var requestMessage = new HttpRequestMessage(HttpMethod.Post, tokenEndpoint)
{
Content = body
};
var response = await httpClient.SendAsync(requestMessage);
var content = response.Content.ReadAsStringAsync().Result;
TokenResponseModel tokenResponse = JsonConvert.DeserializeObject<TokenResponseModel>(content);
return tokenResponse;
}
public class TokenResponseModel
{
[JsonProperty("access_token")]
public string AccessToken { get; set; }
[JsonProperty("id_token")]
public string IdentityToken { get; set; }
public string Scope { get; set; }
public string IssuedTokenType { get; set; }
[JsonProperty("token_type")]
public string TokenType { get; set; }
[JsonProperty("refresh_token")]
public string RefreshToken { get; set; }
public string ErrorDescription { get; set; }
[JsonProperty("expires_in")]
public int ExpiresIn { get; set; } = 0;
}