[Asp.Net Identity (four)] Xamarin.iOS calls require validation ASP.Net WebApi

Abstract: [Asp.Net Identity] Xamarin.iOS calls require validation ASP.Net WebApi


In the design of whether iOS App or Android App, and with your Backend Server has application interaction should be very often encounter. More and more companies offer services to replace WebApi Web Service. Usually your WebApi will provide front-end interface to make interacting with the back-end database contains data access. This is related to CRUD action, the current time to end Mobile Device may receive data better, because that action Select the database to do. But when you have to write data back when it relates to the insert, Update, delete the action. So this one first discuss the fundamental part of how to integrate Asp.Net Identity mechanism to require front-end user must call your WebApi can be verified. This article will discuss how the iOS App to call with [Authorize] WebApi property.

This article is a reference to the translation of foreign authors James article, the original source

http://www.azurefromthetrenches.com/?p=471

1. First, to establish a project in Visual Studio WebApi inside. Select [individual user accounts] in place of authentication

On this project, called ValuesController find API Controller Controllers in the data folder. This is WebApi WebApi project templates provided. At the top you can see that most have a Authorize attribute property. It is used to protect the WebApi not anonymous access. After compiling the implementation of this project, to access this Api, you will get the following error message. (Http: // localhost: 5287 / api / Values)


  
  

   
   
    
    Authorization has been denied for this request.
   
   

  
  

So far, we hope this WebApi can not be anonymous user on the network access.

2.接下来要存取这个WebApi之前,第一步就是要去注册一个使用者账号。

连结到这个项目中的help页面,可以看到底下的WebApi列表 (for example http://localhost:5287/Help)

,列表中看到一个Api叫做Register,这个Api可以允许匿名存取,他是用来协助前端使用者注册一个账号到数据库里面。

把这个项目发布到Windows Azure上,并且在Windows Azure上面建立一个SQL 数据库。

3. 接下来建立注册数据的Model

在MVC WebApi项目中,有一个RegisterBindingModel类,这个类主要写入数据到数据库的DTO类。另 外在Xamarin.iOS项目中作者也建立了一个RegisterModel类,这两个类型结构是一样的。一个是iOS Device要送出数据的结构,另一个是Webapi Server site要接收数据的结构。原作者是用Xamarin.iOS来执行这个范例,所以他建议把这类型的Model放到Portable Class Library里面,这样就可以在Xamarin.iOS或者是Xamarin.Android以及MVC项目中去共用这个类。

class RegisterModel{
    public string UserName { get; set; }
    public string Password { get; set; }
    public string ConfirmPassword { get; set; }
}

在Xamain.ios的项目中,有一个RegisterService Class,这是在iOS程序中用HttpWebRequest来传送一个注册资讯给Server site Controller。

class RegisterService
{
    public async Task Register(string username, string password, string confirmPassword)
    {
        RegisterModel model = new RegisterModel
        {
            ConfirmPassword = confirmPassword,
            Password = password,
            UserName = username
        };
 
        HttpWebRequest request = new HttpWebRequest(new Uri(String.Format("{0}api/Account/Register", Constants.BaseAddress)));
        request.Method = "POST";
        request.ContentType = "application/json";
        request.Accept = "application/json";
        string json = JsonConvert.SerializeObject(model);
        byte[] bytes = Encoding.UTF8.GetBytes(json);
        using(Stream stream = await request.GetRequestStreamAsync())
        {
            stream.Write(bytes, 0, bytes.Length);
        }
 
        try
        {
            await request.GetResponseAsync();
            return true;
        }
        catch (Exception ex)
        {
            return false;
        }
    }
}

刚刚的程序协助使用者注册一个账号,但是要如何实践登入?我们再回头看到WebApi的Help区块,里面并没有一个Login的方法。接下来就是Owin登场的地方了。开启在项目范例中App_Start数据夹里面的Startup.Auth.cs文件。

看到Startup.cs文件的OAuthOptions区块。

实际上,Owin是一个跑在我们网站中的的OAuth验证服务器 ( OAuth authentication server),并且他会针对验证使用者来设定一个OAuth endpoints。

而Server site的验证会需要使用者提供一个Token,它用使用者的username与password去验证辨别使用者本身。后续若有其他的Service需要验证身份时,这个token会在Http header里面做传送的动作。上图 /Token的区块是Web Server上的Token end point。除了传送账号与密码外,还需要设定grant_type 为 password。接着在Xamarin.iOS里面建立LoginService Class,负责送出Endpoint所需要的Form Data。

class LoginService
{
    public async Task Login(string username, string password)
    {
        HttpWebRequest request = new HttpWebRequest(new Uri(String.Format("{0}Token", Constants.BaseAddress)));
        request.Method = "POST";
 
        string postString = String.Format("username={0}&password={1}&grant_type=password",    HttpUtility.HtmlEncode(username), HttpUtility.HtmlEncode(password));
        byte[] bytes = Encoding.UTF8.GetBytes(postString);
        using (Stream requestStream = await request.GetRequestStreamAsync())
        {
            requestStream.Write(bytes, 0, bytes.Length);
        }
 
        try
        {
            HttpWebResponse httpResponse =  (HttpWebResponse)(await request.GetResponseAsync());
            string json;
            using (Stream responseStream = httpResponse.GetResponseStream())
            {
                json = new StreamReader(responseStream).ReadToEnd();
            }
            TokenResponseModel tokenResponse = JsonConvert.DeserializeObject(json);
            return tokenResponse.AccessToken;
        }
        catch (Exception ex)
        {
            throw new SecurityException("Bad credentials", ex);
        }
    }
}

登入成功后,OAuth Server会回复一个Json数据,里面包含着一个access token以及一些资讯。这边把这个资讯序列化回TokenResponseModel对象。

class TokenResponseModel
{
    [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("userName")]
    public string Username { get; set; }
 
    [JsonProperty(".issued")]
    public string IssuedAt { get; set; }
 
    [JsonProperty(".expires")]
    public string ExpiresAt { get; set; }
}

现在我们有了服务器建立与回传的Token后,后续要连接到任何需要验证或授权的WebApi,都可以使用这个Token。现在就用这个attempt来连接ValuesController。

在调用WebApi的时候,Client端必须在Http Header提供access token。名称必须被声明为Authorization,并且Header必须要有“Bearer {token}”的format声明。

class ValuesService
{
    public async Task GetValues(string accessToken)
    {
        HttpWebRequest request = new HttpWebRequest(new Uri(String.Format("{0}api/Values", Constants.BaseAddress)));
        request.Method = "GET";
        request.Accept = "application/json";
        request.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken));
 
        try
        {
            HttpWebResponse httpResponse = (HttpWebResponse)(await request.GetResponseAsync());
            string json;
            using (Stream responseStream = httpResponse.GetResponseStream())
            {
                json = new StreamReader(responseStream).ReadToEnd();
            }
            List values = JsonConvert.DeserializeObject(json);
            return values;
        }
        catch (Exception ex)
        {
            throw new SecurityException("Bad credentials", ex);
        }
    }
}

接着就可以去测试你的这个Xamarin.iOS项目了。

原作者范例文件GitHub下载位置: https://github.com/JamesRandall/WebAPI2AuthenticationExample

参考文献:

How To: Register and Authenticate with Web API 2, OAuth and OWIN

http://www.azurefromthetrenches.com/?p=471

OAuth 2.0 笔记 (1) 世界观

http://blog.yorkxin.org/posts/2013/09/30/oauth2-1-introduction/

原文:大专栏  [Asp.Net Identity(四)] Xamarin.iOS 调用需要验证的ASP.Net WebApi


Guess you like

Origin www.cnblogs.com/chinatrump/p/11458222.html