首页 > 解决方案 > 从 Xamarin Forms 在 Web API 中请求 JWT 时出现错误请求

问题描述

因此,我创建了一个使用 JSON Web 令牌进行身份验证的 Web API,但是,我无法使用我的 xamarin 表单应用程序中的 HttpClient 进行身份验证。奇怪的是,我可以毫无问题地连接我为测试而制作的控制台应用程序,并且控制台应用程序和 xamarin 表单应用程序都使用几乎完全相同的代码。

控制台应用程序中的代码是这样的:

public static async Task<AutenticacionModel> PostCredentialsAsync(string UserName, string Password)
{
    HttpClient cliente = new HttpClient();
    cliente.BaseAddress = new Uri("http://172.25.1.53:9891");
    HttpResponseMessage response = new HttpResponseMessage();
    string _result = String.Empty;
    try
    {
        string Path = cliente.BaseAddress + "oauth/secreto";
        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, Path);
        string autenticacion = "username=" + UserName + "&password=" + Password + "&grant_type=password";
        request.Content = new StringContent(autenticacion, Encoding.UTF8, "application/x-www-form-urlencoded");
        response = await cliente.SendAsync(request);
        response.EnsureSuccessStatusCode();
        _result = await response.Content.ReadAsStringAsync();
    }
    catch (Exception ex)
    {
        // something to do
    }
    return response.Content != null ? JsonConvert.DeserializeObject<AutenticacionModel>(_result) : new AutenticacionModel();
}

Xamarin 表单中的代码:

public async Task<AutenticacionDTO> GetUsuario(string email, string clave)
{
    string JSONAutenticacion;
    HttpResponseMessage response = new HttpResponseMessage();

    try
    {
        var client = new HttpClient();

        client.BaseAddress = new Uri(GlobalSetting.UrlWebApi);
        string Path = client.BaseAddress + "oauth/secreto";
        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, Path);
        string autenticacion = "username=" + email + "&password=" + clave + "&grant_type=password";
        request.Content = new StringContent(autenticacion, Encoding.UTF8, "application/x-www-form-urlencoded");
        response = await client.SendAsync(request);
        response.EnsureSuccessStatusCode();
        JSONAutenticacion = await response.Content.ReadAsStringAsync();
    }
    catch (Exception ex)
    {
        string sss = ex.ToString();
        return null;
    }
    return response.Content != null ? JsonConvert.DeserializeObject<AutenticacionDTO>(JSONAutenticacion) : new AutenticacionDTO();
}

当我使用邮递员连接到我在本地 IIS 中托管的 Web API 时,没有问题,与控制台应用程序相同。但每当我尝试连接 Xamarin Forms 应用程序时,我都会收到 400 Bad Request 响应。

使 Jwt 工作的代码如下所示:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
    var allowedOrigin = "*";
    context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });
    Seguridad _Seguridad = new fovissste.bll.Seguridad();
    LoginDTO Usuario = _Seguridad.Login(context.UserName, context.Password).FirstOrDefault();

    if (Usuario == null)
    {
        context.SetError("invalid_grant", "Usuario o contraseña incorrectos");
        return;
    }

    ClaimsIdentity oauthIdentity = new ClaimsIdentity(new ApplicationUser(context.UserName, "JWT"), new[] { new Claim(ClaimTypes.Role, "Publico") });
    var ticket = await Task.Run(() => new AuthenticationTicket(oauthIdentity, null));
    context.Validated(ticket);
}

有人可以帮忙吗?这是 Xamarin Forms 的问题吗?我真的需要一些评论,因为老实说我看不出我错过了什么。我已经阅读了该站点中的其他帖子,这些帖子表明这可能是在 IIS 上启用远程请求的问题或 CORS 问题,但我认为这是在这一行中处理的:context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });

标签: c#xamarin.formsasp.net-web-api2

解决方案


试试下面的代码:

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri("http://172.25.1.53:9891");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    string autenticacion = "?username=" + email + "&password=" + clave + "&grant_type=password";
    HttpResponseMessage response = await client.PostAsync(client.BaseAddress + "oauth/secreto", new StringContent(autenticacion, Encoding.UTF8, "application/x-www-form-urlencoded"));

    response.EnsureSuccessStatusCode();

    string JSONAutenticacion = await response.Content.ReadAsStringAsync();
}

这条线之后的价值是Path多少?

string Path = client.BaseAddress + "oauth/secreto";

也尝试在之前添加这一行using (var client...

System.Net.ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;

编辑

改变了

HttpResponseMessage response = await client.PostAsync(client.BaseAddress + autenticacion, new StringContent(autenticacion));

HttpResponseMessage response = await client.PostAsync(client.BaseAddress + "oauth/secreto", new StringContent(autenticacion, Encoding.UTF8, "application/x-www-form-urlencoded"));

推荐阅读