使用ASP.NET MVC身份作为后端的Xamarin auth和令牌

时间:2017-03-12 20:40:19

标签: web-services xamarin oauth-2.0 xamarin.forms xamarin.auth

所以我使用本教程设置了一个带有Identity和Oauth2的ASP.NET MVC应用程序:

http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/

如果您尝试这样做,我无法推荐该教程,它非常出色。我现在可以使用以下HTTP请求使用存储在MVC数据库中的用户名/密码登录:

POST /token HTTP/1.1
Host: mymvcsite.azurewebsites.net
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
grant_type=password&username=MyUserName&password=MyPassword

我使用javascript作为使用HttpRequest的概念证明,它的效果非常好。我得到一个令牌回来了。我的回答如下:

{
    "access_token": "A Really long character string",
    "token_type": "bearer",
    "expires_in": 86399
}

所以现在一切都在Xamarin之外工作,现在我试图将我的脑袋包裹起来如何将所有这些插入到我的Xamarin项目中。我的第一个混淆源是Xamarin.auth插件以及如何在这种情况下使用它,如果有的话。我在这个没有使用Facebook或Google作为身份验证提供商的插件上找不到任何内容,而我所做的事情似乎并不适合您拥有客户机密和客户端ID的模型。类似。我试图做的第二件事是,一旦我拥有它,我就会使用该令牌。这里的最终目标是在MVC站点中创建一些Web服务,让用户使用oauth对MVC身份进行身份验证,然后安全地访问这些Web服务。所以我的问题是:

1)在这种情况下我会使用Xamain.auth吗?如果是这样,是否有任何好的资源可以举例说明我尝试做什么?

2)获得令牌之后,如何保护Web服务以期望像这样的oauth2令牌?

1 个答案:

答案 0 :(得分:1)

你在那里发布了很棒的资源。我也使用过它,我已经构建了一个完整的(Xamarin)可移植类库,它可以在每次请求时自动提交此标记等。

在ASP.NET MVC中,它就像添加

一样简单
[Authorize]

- 覆盖您的API控制器。如果您正确地遵循指南,这将立即保护它们。

保护您的API之后,您需要发送包含持有者令牌的请求。这就是我在项目中实现它的方式:

// First logging in and getting a token:
public async Task<bool> OAuthLoginAsync(string username, string password)
{
    var formContent = new FormUrlEncodedContent(new[]
    {
      new KeyValuePair<string, string>("username", username),
      new KeyValuePair<string, string>("password", password),
      new KeyValuePair<string, string>("grant_type", "password")
    });

    Token = await PostAndReadAsync<TokenResponse>(_oauthEndpointUri, formContent);

}
// this method is responsible for sending the request and returning an object
public async Task<T> PostAndReadAsync<T>(string path, HttpContent content)
    {
        var httpClient = new HttpClient();
        httpClient.DefaultRequestHeaders.Add("Accept", "application/json");

        var responseMessage = await httpClient.PostAsync(path, content, cancellationToken);
        if (!responseMessage.IsSuccessStatusCode) {
          throw new Exception("Something went wrong...");
        }

        return await responseMessage.Content.ReadAsAsync<T>(cancellationToken);
      }
}

令牌定义:

public class TokenResponse
  {
    [JsonProperty("access_token")]
    public string AccessToken { get; set; }

    [JsonProperty("token_type")]
    public string TokenType { get; set; }

    [JsonProperty("expires_in")]
    public int ExpiresIn { get; set; }

    [JsonProperty("refresh_token")]
    public string RefreshToken { get; set; }

    [JsonProperty("as:client_id")]
    public string ClientId { get; set; }

    [JsonProperty("userName")]
    public string UserName { get; set; }

    [JsonProperty(".issued")]
    public DateTime IssueDate { get; set; }

    [JsonProperty(".expires")]
    public DateTime ExpireDate { get; set; }
  }

然后在任何后续的api调用中(您应该提供oauth令牌),您应该添加访问令牌。

HttpClient.DefaultRequestHeaders.Authorization = 
new AuthenticationHeaderValue("Bearer", Token.AccessToken);

作为额外的奖励,前面指定的PostAndReadAsync方法可以重用来调用任何其他资源(因为它返回<T>),因此它是可重用的。

我希望这会对你有所帮助(和许多其他人面临同样的问题)。如果您的情况不完整,请随时询问更多信息。

请注意,为简单起见,我删除了所有try / catches和cancellationtokens。

您的(共享)移动项目中需要以下nuget包:

Microsoft.Bcl
Microsoft.Bcl.Build
Microsoft.Bcl.Http
Microsoft.AspNet.WebApi.Client
Newtonsoft.Json