<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      ASP.NET Web API與Owin OAuth:調用與用戶相關的Web API

      在前一篇博文中,我們通過以 OAuth 的 Client Credential Grant 授權方式(只驗證調用客戶端,不驗證登錄用戶)拿到的 Access Token ,成功調用了與用戶無關的 Web API。

      在這篇博文中,我們將以 OAuth 的 Resource Owner Password Credentials Grant 的授權方式( grant_type=password )獲取 Access Token,并以這個 Token 調用與用戶相關的 Web API。

      對應的應用場景是:為自家的網站開發手機 App(非第三方 App),只需用戶在 App 上登錄,無需用戶對 App 所能訪問的數據進行授權。

      根據 OAuth 規范,客戶端獲取 Access Token 的請求方式如下:

      POST /token HTTP/1.1
      Host: server.example.com
      Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
      Content-Type: application/x-www-form-urlencoded
      
      grant_type=password&username=johndoe&password=A3ddj3w

      根據上面的請求方式,在 C# 中用 HttpClient 實現一個簡單的客戶端,代碼如下:

      public class OAuthClientTest
      {
          private HttpClient _httpClient;
      
          public OAuthClientTest()
          {
              _httpClient = new HttpClient();
              _httpClient.BaseAddress = new Uri("http://openapi.cnblogs.com");
          } 
      
          [Fact]
          public async Task Get_Accesss_Token_By_Resource_Owner_Password_Credentials_Grant()
          {
              Console.WriteLine(await GetAccessToken());
          }
      
          private async Task<string> GetAccessToken()
          {
              var clientId = "1234";
              var clientSecret = "5678";
      
              var parameters = new Dictionary<string, string>();            
              parameters.Add("grant_type", "password");
              parameters.Add("username", "博客園團隊");
              parameters.Add("password", "cnblogs.com");
      
              _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
                  "Basic",
                  Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret))
                  );
      
              var response = await _httpClient.PostAsync("/token", new FormUrlEncodedContent(parameters));
              var responseValue = await response.Content.ReadAsStringAsync();
              if (response.StatusCode == System.Net.HttpStatusCode.OK)
              {
                  return JObject.Parse(responseValue)["access_token"].Value<string>();
              }
              else
              {
                  Console.WriteLine(responseValue);
                  return string.Empty;
              }
          }
      }

      (注:與之前相比,這里的 client_id/client_secret 改為了 Basic Authorization,以更好的遵循 OAuth 規范)

      在服務端,基于 Owin OAuth, 針對 Resource Owner Password Credentials Grant 的授權方式,只需重載 OAuthAuthorizationServerProvider.GrantResourceOwnerCredentials() 方法即可。代碼如下:

      public class CNBlogsAuthorizationServerProvider : OAuthAuthorizationServerProvider
      {
          //...
      
          public override async Task GrantResourceOwnerCredentials(
              OAuthGrantResourceOwnerCredentialsContext context)
          {
              //調用后臺的登錄服務驗證用戶名與密碼
      
              var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
              oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
              var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
              context.Validated(ticket);
      
              await base.GrantResourceOwnerCredentials(context);
          }
      }

      完整的CNBlogsAuthorizationServerProvider實現代碼如下(與之前相比,context.TryGetFormCredentials 改為了 context.TryGetBasicCredentials):

      public class CNBlogsAuthorizationServerProvider : OAuthAuthorizationServerProvider
      {
          public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
          {
              string clientId;
              string clientSecret;
              context.TryGetBasicCredentials(out clientId, out clientSecret);
      
              if (clientId == "1234"
                  && clientSecret == "5678")
              {
                  context.Validated(clientId);
              }
      
              await base.ValidateClientAuthentication(context);
          }
      
          public override async Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
          {
              var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
              var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
              context.Validated(ticket);
      
              await base.GrantClientCredentials(context);
          }
      
          public override async Task GrantResourceOwnerCredentials(
              OAuthGrantResourceOwnerCredentialsContext context)
          {
              //調用后臺的登錄服務驗證用戶名與密碼
      
              var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
              oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
              var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
              context.Validated(ticket);
      
              await base.GrantResourceOwnerCredentials(context);
          }
      }
      CNBlogsAuthorizationServerProvider

      這樣,運行客戶端程序就可以拿到 Access Token 了。

      接下來,我們拿著以這種方式獲取的 Access Token,就可以調用與用戶相關的 Web API 了。

      在服務端我們通過一個簡單的 Web API 測試一下,代碼如下:

      public class UsersController : ApiController
      {
          [Authorize]
          public string GetCurrent()
          {
              return User.Identity.Name;
              //這里可以調用后臺用戶服務,獲取用戶相關數所,或者驗證用戶權限進行相應的操作
          }
      }

      然后,客戶端用以 grant_type=password 方式拿到的 Access Token 調用這個Web API,客戶端增加的代碼如下:

      [Fact]
      public async Task Call_WebAPI_By_Resource_Owner_Password_Credentials_Grant()
      {
          var token = await GetAccessToken();
          _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
          Console.WriteLine(await (await _httpClient.GetAsync("/api/users/current")).Content.ReadAsStringAsync());
      }

      客戶端運行結果如下:

      "博客園團隊"

      調用成功!運行結果正是獲取 Access Token 時所用的 username 。 

      結合 ASP.NET 現有的安全機制,借助 OWIN 的威力,Microsoft.Owin.Security.OAuth 的確讓開發基于 OAuth 的 Web API 變得更簡單。

      posted @ 2015-06-15 17:09  dudu  閱讀(30890)  評論(56)    收藏  舉報
      主站蜘蛛池模板: 九九热久久这里全是精品| 韶关市| 久久精品国产久精国产| 亚洲无人区码一二三四区| 国产线播放免费人成视频播放| 亚洲人妻一区二区精品| 九九热在线视频观看这里只有精品| 成人免费看片又大又黄| 熟女人妻aⅴ一区二区三区电影 | 人妻在线无码一区二区三区| 国产一区二区三区小说| av一区二区中文字幕| 亚洲五月天一区二区三区| 国产亚洲天堂另类综合| 噜噜噜噜私人影院| 色成人亚洲| 久久人人97超碰精品 | 中文字幕乱妇无码AV在线| 国产成人精品午夜2022| 大伊香蕉在线精品视频75| 国产一区国产二区在线视频| a级国产乱理伦片在线观看al| 狠狠色狠狠色综合日日不卡| 日本深夜福利在线观看| 亚洲国产成人久久综合区| 免费无码成人AV在线播放不卡| 建昌县| 久久夜色撩人国产综合av| 久久精品国产福利一区二区| 久久精品99国产国产精| 最新国产精品好看的精品| 一区二区中文字幕久久| 无码人妻视频一区二区三区| 久久国产精品99久久蜜臀| 久久精品一本到99热免费| 亚洲精品久久久久国色天香| 国产精品无码一区二区牛牛| 亚洲鸥美日韩精品久久| 欧美人与zoxxxx另类| 国产亚洲真人做受在线观看| 中文字幕av无码免费一区|