[Asp.Net Identity(四)] Xamarin.iOS 调用需要验证的ASP.Net WebApi

摘要: [Asp.Net Identity] Xamarin.iOS 调用需要验证的ASP.Net WebApi


在设计不管是iOS App或者是Android App的时候,跟你的Backend Server有交互应该是很常碰到的应用。越来越多的企业提供WebApi的服务来取代Web Service。,通常你的WebApi会提供界面让前端跟后端的数据库有数据存取的交互。这关系到CRUD的动作,当前端Mobile Device要接收数据的时候可能还好,因为就是对数据库去做Select的动作。但是当你有数据回写的时候,那就关系到insert,Update,delete的动作。所以这一篇先来讨论最基本的部分,如何整合Asp.Net Identity机制来要求前端使用者必须通过验证才可以调用你的WebApi。这一篇文章就来讨论iOS的App要如何去调用带有[Authorize]属性的WebApi。

这篇文章是参考与翻译外国作者James的文章,原文出处

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

1. 首先要在Visual Studio里面建立一个WebApi的项目。在验证方式的地方选择[个别使用者账户]

在这个项目里面,在Controllers数据夹下找到一个名为ValuesController的API Controller。这是WebApi项目范本所提供的WebApi。在这个类最上方可以看到有一个Authorize attribute属性。这是用来保护这个WebApi不可匿名存取。编译执行这个项目后,去存取这个Api,会得到以下的错误消息。(http://localhost:5287/api/Values)


  
  

   
   
    
    Authorization has been denied for this request.
   
   

  
  

到目前为止,我们就是希望这个WebApi无法被网络上的匿名使用者存取。

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


猜你喜欢

转载自www.cnblogs.com/chinatrump/p/11458222.html
今日推荐