了解Oauth 2.0授权流
想要调微软REST API,第一步学会获取Access Token是必须的。
OAuth 2.0 授权流
这里附上微软OAuth 2.0 authorization官方文档
授权调用API代码
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using JsonRawDataFilter = System.Func<System.Object, System.String>;
namespace AzureWebTest.Controllers
{
public class HomeController : Controller
{
//private String ApiKey { get; set; }
string AccessToken = "";
string RefreshToken = "";
public ActionResult Index()
{
return View();
}
//public ActionResult About()
//{
// ViewBag.Message = "Your application description page.";
// return View();
//}
public ActionResult Contact(AuthResponse response)
{
AuthenticationParameters parm = new AuthenticationParameters();
parm.ClientId = "Your Client ID";
//parm.Code = response.Code;
//parm.scope = "https%3a%2f%2fgraph.microsoft.com%2fUser.Read.All+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.Read.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fUser.Read+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadBasic.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.AccessAsUser.All"; //%20https%3a%2f%2fgraph.microsoft.com%2fuser_impersonation
//parm.RedirectUri = "https://localhost:8000/Home/Contact";
parm.GrantType = "client_credentials";
parm.ClientSecret = "Your Secret";
parm.tenant = response.tenant;
var result = AcquireTokenWithOutUser(parm);
//var AccessToken = GetAccessToken();
ViewData["Message"] = result.AccessToken; //result.AccessToken;
//this.ApiKey = result.AccessToken;
GetMyData(result.AccessToken, result.RefreshToken, null);
ViewBag.Message = "Your contact page.";
return View();
}
[HttpPost]
public JsonResult AzureRedirect()
{
var authorizationRequest = $"https://login.microsoftonline.com/common/oauth2/v2.0/authorize?" +
$"client_id=****" +
$"&response_type=code" +
$"&redirect_uri=https://localhost:8000/Home/About" + //https://air-east-us-x.avepointonlineservices.com/collector/paygo/authcode
$"&response_mode=query" +
$"&scope=https%3a%2f%2fgraph.microsoft.com%2fUser.Read.All+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.Read.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fUser.Read+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadBasic.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.AccessAsUser.All" + //%20https%3a%2f%2fmanagement.azure.com%2fuser_impersonation https://management.azure.com/user_impersonation
$"&state=12345";
return Json(authorizationRequest);
}
[HttpPost]
public JsonResult AzureRedirectWithoutUser()
{
var authorizationRequest = $"https://login.microsoftonline.com/common/adminconsent?" +
$"client_id=**" +
$"&redirect_uri=https://localhost:8000/Home/Contact" +
$"&state=12345";
return Json(authorizationRequest);
}
//[Route("collector/paygo/authcode")]
public ActionResult About(AuthResponse response)
{
AuthenticationParameters parm = new AuthenticationParameters();
parm.ClientId = "**";
parm.Code = response.Code;
parm.scope = "https%3a%2f%2fgraph.microsoft.com%2fUser.Read.All+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.Read.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fUser.Read+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadBasic.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.AccessAsUser.All"; //%20https%3a%2f%2fgraph.microsoft.com%2fuser_impersonation
parm.RedirectUri = "https://localhost:8000/Home/About"; //"https://localhost:44383/Home/About";
parm.GrantType = "authorization_code";
parm.ClientSecret = "**";
var result = AcquireToken(parm);
//var AccessToken = GetAccessToken();
ViewData["Message"] = result.AccessToken; //result.AccessToken;
//this.ApiKey = result.AccessToken;
GetMyData(result.AccessToken, result.RefreshToken, null);
ViewBag.Message = "Your application description page.";
return View();
}
// Line breaks for legibility only
//POST /{tenant}/oauth2/v2.0/token HTTP/1.1
//Host: https://login.microsoftonline.com
//Content-Type: application/x-www-form-urlencoded
public AuthenticationResult AcquireToken(AuthenticationParameters parameters)
{
var result = new AuthenticationResult();
var serviceRoot = "https://login.microsoftonline.com";
var tokenRequest = $"{serviceRoot}/**/oauth2/v2.0/token";
var postContent = new
{
client_id = parameters.ClientId,
scope = "https%3a%2f%2fgraph.microsoft.com%2fUser.Read.All+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.Read.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fUser.Read+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadBasic.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.AccessAsUser.All",
code = System.Web.HttpUtility.UrlEncode(parameters.Code),
grant_type = parameters.GrantType,
redirect_uri = parameters.RedirectUri,
client_secret = System.Web.HttpUtility.UrlEncode(parameters.ClientSecret),
};
//Send request
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.TryParseAdd("application/json");
var body = new StringContent(ConvertToFormData(postContent), System.Text.Encoding.UTF8);
//body.Headers.ContentType = new MediaTypeHeaderValue("application/json");
body.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
var responseMessage = httpClient.PostAsync(tokenRequest, body).Result;
var content = responseMessage.Content.ReadAsStringAsync().Result;
if (responseMessage.StatusCode == System.Net.HttpStatusCode.OK)
{
var accessToken = JsonConvert.DeserializeObject<AzureAccessToken>(content);
result.AccessToken = accessToken.Access_token;
result.RefreshToken = accessToken.Refresh_token;
result.AccessTokenType = accessToken.Token_type;
result.ExpiresOn = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero).AddSeconds(accessToken.Expires_on);
//result = AcquireTokenByResfeshToken(result);
if (!String.IsNullOrEmpty(accessToken.Id_token))
{
//payload = GetByIdToken(accessToken.Id_token);
}
}
else
{
}
}
return result;
}
// Line breaks are for legibility only.
//POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token HTTP/1.1
//Host: login.microsoftonline.com
//Content-Type: application/x-www-form-urlencoded
public AuthenticationResult AcquireTokenWithOutUser(AuthenticationParameters parameters)
{
var result = new AuthenticationResult();
var serviceRoot = "https://login.microsoftonline.com";
var tokenRequest = $"{serviceRoot}/**/oauth2/v2.0/token";
var postContent = new
{
client_id = parameters.ClientId,
scope = "https%3a%2f%2fgraph.microsoft.com%2f.default",
client_secret = System.Web.HttpUtility.UrlEncode(parameters.ClientSecret),
grant_type = parameters.GrantType,
};
//Send request
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.TryParseAdd("application/json");
var body = new StringContent(ConvertToFormData(postContent), System.Text.Encoding.UTF8);
//body.Headers.ContentType = new MediaTypeHeaderValue("application/json");
body.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
var responseMessage = httpClient.PostAsync(tokenRequest, body).Result;
var content = responseMessage.Content.ReadAsStringAsync().Result;
if (responseMessage.StatusCode == System.Net.HttpStatusCode.OK)
{
var accessToken = JsonConvert.DeserializeObject<AzureAccessToken>(content);
result.AccessToken = accessToken.Access_token;
result.RefreshToken = accessToken.Refresh_token;
result.AccessTokenType = accessToken.Token_type;
result.ExpiresOn = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero).AddSeconds(accessToken.Expires_on);
//result = AcquireTokenByResfeshToken(result);
if (!String.IsNullOrEmpty(accessToken.Id_token))
{
//payload = GetByIdToken(accessToken.Id_token);
}
}
else
{
}
}
return result;
}
public AuthenticationResult AcquireTokenByResfeshToken(AuthenticationResult parameters)
{
var result = new AuthenticationResult();
var serviceRoot = "https://login.microsoftonline.com";
var tokenRequest = $"{serviceRoot}/**/oauth2/v2.0/token";
var postContent = new
{
client_id = "**",
scope = "https%3a%2f%2fmanagement.azure.com%2fuser_impersonation",
refresh_token = System.Web.HttpUtility.UrlEncode(parameters.RefreshToken),
grant_type = "refresh_token", //parameters.GrantType,
client_secret = System.Web.HttpUtility.UrlEncode("**"),
};
//Send request
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.TryParseAdd("application/json");
var body = new StringContent(ConvertToFormData(postContent), System.Text.Encoding.UTF8);
//body.Headers.ContentType = new MediaTypeHeaderValue("application/json");
body.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
var responseMessage = httpClient.PostAsync(tokenRequest, body).Result;
var content = responseMessage.Content.ReadAsStringAsync().Result;
if (responseMessage.StatusCode == System.Net.HttpStatusCode.OK)
{
var accessToken = JsonConvert.DeserializeObject<AzureAccessToken>(content);
result.AccessToken = accessToken.Access_token;
result.RefreshToken = accessToken.Refresh_token;
result.AccessTokenType = accessToken.Token_type;
result.ExpiresOn = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero).AddSeconds(accessToken.Expires_on);
if (!String.IsNullOrEmpty(accessToken.Id_token))
{
//payload = GetByIdToken(accessToken.Id_token);
}
}
else
{
}
}
return result;
}
public JsonResult GetMyData(string token, string refreshToken, JsonRawDataFilter filter)
{
AccessToken = token;
RefreshToken = refreshToken;
//JsonRawDataFilter filter;
//token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImllX3FXQ1hoWHh0MXpJRXN1NGM3YWNRVkduNCIsImtpZCI6ImllX3FXQ1hoWHh0MXpJRXN1NGM3YWNRVkduNCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuY29yZS53aW5kb3dzLm5ldC8iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9mZTNhZjJjMS1lNzYyLTRiNjItYWQzYi1lM2YxZWQ1ZGQwYTAvIiwiaWF0IjoxNTY2NTI0MzUwLCJuYmYiOjE1NjY1MjQzNTAsImV4cCI6MTU2NjUyODI1MCwiYWNyIjoiMSIsImFpbyI6IjQyRmdZRmh5L0U1UlpvSXJROWk5ODdYcXZ5enVHci9rNkhDTnVLQTNkOXNqVzh1U2tFTUEiLCJhbXIiOlsid2lhIl0sImFwcGlkIjoiN2Y1OWE3NzMtMmVhZi00MjljLWEwNTktNTBmYzViYjI4YjQ0IiwiYXBwaWRhY3IiOiIyIiwiZmFtaWx5X25hbWUiOiJXYW5nIiwiZ2l2ZW5fbmFtZSI6IkJvYiIsImdyb3VwcyI6WyJjZDI4NjFlNy01ZTlkLTQ5OTMtOTNkZC00NWMwNDE4YzM2ZjkiLCJkYWZlZGVhNC1hOTI1LTQyYjItYTE0YS1mYzkzMTNmZWFmY2MiLCJkZDNmMjE5Yi1mNzhiLTRiNmItYmMwNy1mZmY5ZDQ3YzA5YTUiLCJiMzcyMzc2Yy1mNzJiLTQxZDctOTkyNy0wOWE2OGUwMjExNGYiLCIyNTgyN2JjNy05ZDc5LTQ0ZDAtODQxNy1jZDJhYWRmNzk2YWQiLCIxZjRkMTc1Mi1iZWZkLTQ3MmYtOGNiMS03Mjg3NGRlNDZhZjkiLCJmNjM0NWQxMy0yYWE2LTQ3MTItOTY2OS04NTg2NTlmYzQ2YTkiLCI0MmQ4YjZlNi1mZDdiLTRiZmUtYTJkYi0xY2VmNjcwMTVmNWIiLCI3YWE5MGQ2My05ZTRhLTQyY2EtOTRlZi0xMjY5ODI3OWFjMjEiLCJhOGZlMWE4Zi00MzljLTQxOTMtYTE0Zi05N2E5OGJjZDc2ZGQiLCIxYThlMDk1NC1hNDY2LTQ4OTYtYTllNC1hZjA5YTAwZDMxN2YiLCI2ZDczMjMyZi1kM2JhLTQyZTgtODM5MS0wYzU2OTNmOTc3NDQiLCIzNzE5ZjIxOC1mNzIzLTQ0MmMtOTA5MC04YjE4OWI3NGQxZTMiLCJhMDE1MjA3Ny02MGVkLTRkMzUtYTQ0Ni0wOGZlMjg1Y2E3OGYiLCJhMzAxNWFlYy02YjRkLTQ2MDctOTZmMC01ZGIyODMzODE4MzkiLCJjNjNlZjQ0NC1mYzYyLTQzMjQtODNiNC04ZTg0NWMxNDVlNWYiLCI0ODIwMWEwZS1mODM5LTQwYmYtOTViZi05YTI0MjY1NDQwYTEiLCIzZjNlMTk5Mi05NGU0LTRjZjQtYmNkZS0zMTZlN2NlYmI1ZDciLCIzOGE0ZmJiZC00YzYzLTQyMTAtYWZkMC1lMDgzYmQ4MTYxNjIiLCI1NjE1MjA1ZS0yZTRkLTQ2ODUtYmZiZi1kYWQ1ZjlkZDllMmUiLCI4ZmY4ODUwYi0zODU2LTRkYWItYjBmNC03OTEwMDM2OTllM2EiLCI0YTQ0Mjk1ZC0zMTk3LTQxMmYtOTdmNi1lM2RmZGYxNmE1Y2EiLCIxODY1OWJmNy00MjhiLTQ2ZTctODM4ZC03NmZmNTgyYjY5N2UiXSwiaXBhZGRyIjoiMTIzLjE3Ny4yMi4yNTEiLCJuYW1lIjoiQm9iIFdhbmciLCJvaWQiOiJkYTBkMGQ5YS1jOWEyLTQ5YzgtODAwOC1iYjg1Y2UzOGM1OGMiLCJvbnByZW1fc2lkIjoiUy0xLTUtMjEtNDI1MDQ3NTg3OC0zMzE4MzE0ODI0LTIxMTUxNTc1MTQtNDkzODIiLCJwdWlkIjoiMTAwMzIwMDA1MDFBQUU4OSIsInNjcCI6InVzZXJfaW1wZXJzb25hdGlvbiIsInN1YiI6IndhWGlTbGdYekVhZXZ3UWF5djFEZDgtMWhYb2lJUlhiNVhHcmFvVXhiZXMiLCJ0aWQiOiJmZTNhZjJjMS1lNzYyLTRiNjItYWQzYi1lM2YxZWQ1ZGQwYTAiLCJ1bmlxdWVfbmFtZSI6ImJvYi53YW5nQGF2ZXBvaW50LmNvbSIsInVwbiI6ImJvYi53YW5nQGF2ZXBvaW50LmNvbSIsInV0aSI6IkF6LUJUWm9CTWttV1d5cFJEaXBnQUEiLCJ2ZXIiOiIxLjAifQ.rS4PDQa4h43JNDhUB1i8C03S10F_lZWOAXD-TIMyl38t7pIUvVzO9GTsb7TcJAiQylsSxvhaaUQHWMBOA0NyTG-T4WR_ByWi-OvQxi5LFaPXEaSBvKF_dxmHDyuIIrgIiTHkxlxqGHVJeeV64tTY5fFnCOR8Bj0h4R6txwPp40uGhLZBfmKMpyOz0S9CpBfGnJB_x_xXpocAtcUf93njqLeKJjCge6us8_aGhFjbwxzqb_tBCBr99EYiRIdLSok3ZJMD4Oc9dn6D2sP88iKP2Vhc3pfJcEHjwaAyT9LPz5qyz9I3AXc6Mp22aCiZFx7wKlGJIv9zlbBhe8SNDCUzBg";
//var requestUri = "https://graph.microsoft.com/v1.0/users";
//var requestUri = "https://graph.microsoft.com/v1.0/me";
var requestUri = "https://graph.microsoft.com/v1.0/users/**";
//RawData result = null;
UsageAggregateRawData result = null;
var tempResult = new UsageAggregateRawData { Value = new List<UsageAggregate>() };
//do
//{
using (var httpClient = new HttpClient { Timeout = TimeSpan.FromHours(1) })
{
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {AccessToken}");
httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
using (var httpResponseMessage = httpClient.GetAsync(requestUri).Result)
{
if (httpResponseMessage.StatusCode == HttpStatusCode.OK)
{
var resultValue = httpResponseMessage.Content.ReadAsStringAsync().Result;
//var jsonObject = JsonConvert.DeserializeObject<UsageAggregateRawData>(resultValue);
//jsonObject.Value.ForEach(data =>
//{
// if (filter != null)
// filter(data);
// tempResult.Value.Add(data);
//});
//requestUri = jsonObject.NextLink;
//Thread.Sleep(600000); //1000 * 60 * 10 = 10min
}
else
{
//var AuthResult = new AuthenticationResult();
//AuthenticationResult parameters = new AuthenticationResult();
//parameters.RefreshToken = refreshToken;
//AuthResult = AcquireTokenByResfeshToken(parameters);
//RefreshToken = AuthResult.RefreshToken;
//AccessToken = AuthResult.AccessToken;
}
}
}
//} while (requestUri != null && requestUri != "");
return Json(null);
}
public class AuthResponse
{
public String Code { get; set; }
public String Id_Token { get; set; }
public String Error { get; set; }
public String Error_Description { get; set; }
public String Resource { get; set; }
public String State { get; set; }
public string session_state { get; set; }
public string tenant { get; set; }
public Boolean admin_consent { get; set; }
}
public class AuthenticationResult
{
public String AccessTokenType { get; set; }
public String AccessToken { get; set; }
public String RefreshToken { get; set; }
public DateTimeOffset ExpiresOn { get; set; }
public String TenantId { get; set; }
public AzureUserInfo UserInfo { get; set; }
public String IdToken { get; set; }
}
public class AzureUserInfo
{
/// <summary>
/// Gets identifier of the user authenticated during token acquisition.
/// </summary>
public String UniqueId { get; set; }
public String UserPrincipalName { get; set; }
public String GivenName { get; set; }
public String FamilyName { get; set; }
}
public class AuthenticationParameters
{
public string scope { get; set; }
public String GrantType { get; set; }
public String ClientId { get; set; }
public String ClientSecret { get; set; }
public String Code { get; set; }
public String RedirectUri { get; set; }
/// <summary>
/// Jwt token format
/// </summary>
public String IdToken { get; set; }
public String RefreshToken { get; set; }
public string tenant { get; set; }
public Boolean admin_consent { get; set; }
}
private static String ConvertToFormData(Object data)
{
var bodyBuilder = new System.Text.StringBuilder();
var objectType = data.GetType();
Array.ForEach(objectType.GetProperties(),
item => bodyBuilder.Append(item.Name).Append('=').Append(item.GetValue(data, null)).Append('&'));
return bodyBuilder.ToString().Trim('&');
}
public class AzureAccessToken
{
public String Access_token { get; set; }
public String Token_type { get; set; }
/// <summary>
/// How long the access token is valid (in seconds).
/// </summary>
public Int64 Expires_in { get; set; }
/// <summary>
/// The time when the access token expires.
/// The date is represented as the number of seconds from 1970-01-01T0:0:0Z UTC until the expiration time.
/// </summary>
public Int64 Expires_on { get; set; }
/// <summary>
/// The App ID URI of the web API (secured resource).
/// </summary>
public String Resource { get; set; }
public String Refresh_token { get; set; }
/// <summary>
/// An unsigned JSON Web Token (JWT).
/// The app can base64Url decode the segments of this token to request information about the user who signed in.
/// </summary>
public String Id_token { get; set; }
}
public class UsageAggregateRawData : RawData
{
public List<UsageAggregate> Value { get; set; }
public String NextLink { get; set; }
}
public class UsageAggregate
{
public String Id { get; set; }
public String Name { get; set; }
public String Type { get; set; }
public Properties Properties { get; set; }
}
public class Properties
{
public String SubscriptionId { get; set; }
public String UsageStartTime { get; set; }
public String UsageEndTime { get; set; }
public String MeterId { get; set; }
public InfoFields InfoFields { get; set; }
[JsonProperty("instanceData")]
public String InstanceDataRaw { get; set; }
public InstanceDataType InstanceData
{
get
{
if (!String.IsNullOrEmpty(this.InstanceDataRaw))
{
return JsonConvert.DeserializeObject<InstanceDataType>(InstanceDataRaw.Replace("\\\"", ""));
}
return null;
}
}
public Double Quantity { get; set; }
public String Unit { get; set; }
public String MeterName { get; set; }
public String MeterCategory { get; set; }
public String MeterSubCategory { get; set; }
public String MeterRegion { get; set; }
}
public class RawData { }
public class InfoFields
{
public String MeteredRegion { get; set; }
public String MeteredService { get; set; }
public String Project { get; set; }
public String MeteredServiceType { get; set; }
public String ServiceInfo1 { get; set; }
}
public class InstanceDataType
{
[JsonProperty("Microsoft.Resources")]
public MicrosoftResources MicrosoftResources { get; set; }
}
public class MicrosoftResources
{
public String ResourceUri { get; set; }
public IDictionary<String, String> Tags { get; set; }
public IDictionary<String, String> AdditionalInfo { get; set; }
public String Location { get; set; }
public String PartNumber { get; set; }
public String OrderNumber { get; set; }
}
}
}
更多请了解Rest API官方文档
仅供学习参考,如有侵权请联系我删除