使用ADAL C#作为机密用户/服务器守护程序/服务器到服务器 - 401未授权 [英] Using ADAL C# as Confidential User /Daemon Server /Server-to-Server - 401 Unauthorized

查看:351
本文介绍了使用ADAL C#作为机密用户/服务器守护程序/服务器到服务器 - 401未授权的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

指的是不回答的问题:

<一个href=\"http://stackoverflow.com/questions/37215742/401-unauthorized-authentication-using-rest-api-dynamics-crm-with-azure-ad#comment61963502_37215742\">401-使用REST API的Dynamics CRM和Azure的AD未经授权认证

<一个href=\"http://stackoverflow.com/questions/36171276/dynamics-crm-online-2016-daemon-server-application-azure-ad-authentication-e\">Dynamics CRM Online的2016 - 守护进程/服务器应用程序的Azure AD身份验证错误网页API

<一个href=\"http://stackoverflow.com/questions/36991294/dynamics-crm-2016-online-rest-api-with-client-credentials-oauth-flow\">Dynamics CRM 2016年在线REST API与客户端凭据的OAuth流

我需要没有任何loginscreen在Azure云和Dynamics CRM Online中的2016年Web服务之间的通信!这项服务将有一个REST API触发对CRM(我也将实施的鉴别)

CRUD操作

我想这就是所谓的机密客户或守护程序服务器或者服务器到服务器

设置我的服务在正常AD天青(用委托权限=访问动态在线为组织用户,没有其他选项)

我创建了VS这创造我的WebService在Azure中的ASP.NET Web API项目,也OFR的Azure AD的CRM

之内的应用程序项

我的code看起来像这样(请忽略的EntityType和ReturnValue):

 公共类WolfController:ApiController
  {
    私人静态只读字符串租客=xxxxx.onmicrosoft.com;
    私人静态只读字符串客户端Id =dxxx53-42xx-43bc-b14e-c1e84b62752d
    私人静态只读字符串密码=J + T / DXjn4PMVAHSvZGd5sptGxxxxxxxxxr5Ki8KU =; //客户端密钥,有效期为一年或两年
    私人静态只读字符串RESOURCEID =HTTPS://tenantname-naos$p$pview.crm.dynamics.com/
    公共静态异步任务&LT; AuthenticationResult&GT; AcquireAuthentificationToken()
    {
      AuthenticationContext authenticationContext =新AuthenticationContext(https://login.windows.net/+租客);
      ClientCredential clientCredentials =新ClientCredential(客户端ID,密码);
      返回等待authenticationContext.AcquireTokenAsync(RESOURCEID,clientCredentials);
    }    // GET:只是通过GET调用DataOperations法,忽略返回
    公共异步任务&LT;&IEnumerable的LT;狼&GT;&GT;得到()
    {
      AuthenticationResult结果=等待AcquireAuthentificationToken();
      等待DataOperations(结果);      返回新狼[] {新狼()};
    }
    私有静态异步任务DataOperations(AuthenticationResult authResult)
    {
      使用(HttpClient的HttpClient的=新的HttpClient())
      {
        httpClient.BaseAddress =新的URI(RESOURCEID);
        httpClient.Timeout =新时间跨度(0,2,0); //2分钟
        httpClient.DefaultRequestHeaders.Add(OData的-MAXVERSION,4.0);
        httpClient.DefaultRequestHeaders.Add(的OData版,4.0);
        httpClient.DefaultRequestHeaders.Accept.Add(新MediaTypeWithQualityHeaderValue(应用/ JSON));
        httpClient.DefaultRequestHeaders.Authorization =新AuthenticationHeaderValue(旗手,authResult.AccessToken);        帐户帐户=新帐户();
        account.name =测试帐号;
        account.telephone1 =555-555;        字符串内容=的String.Empty;
        内容= JsonConvert.SerializeObject(帐户,新JsonSerializerSettings(){DefaultValueHandling = DefaultValueHandling.Ignore});        //创建实体////////////////////////////////////////////// ///////////////////////////////////////
        HTT prequestMessage要求=新HTT prequestMessage(HttpMethod.Post,API /数据/ V8.1 /账户);
        request.Content =新的StringContent(内容);
        request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(应用/ JSON);
        HTT presponseMessage响应=等待httpClient.SendAsync(请求);
        如果(response.IsSuccessStatus code)
        {
          Console.WriteLine(帐户{0}创建,account.name);
        }
        否则//获取未授权这里
        {
          抛出新的异常(的String.Format(无法​​创建帐户{0},原因是{1}。,account.name,response.ReasonPhrase));
        } ...更多code

在叫我的GET请求,我得到401未经授权,虽然我并发送的accessToken。

任何想法?

编辑:
我也试过code在这个博客(唯一来源这似乎解决问题,没有工作或者)劝:

<一个href=\"https://samlman.word$p$pss.com/2015/06/04/getting-an-azure-access-token-for-a-web-application-entirely-in-$c$c/\" rel=\"nofollow\">https://samlman.word$p$pss.com/2015/06/04/getting-an-azure-access-token-for-a-web-application-entirely-in-$c$c/

有了这个code:

 公共类WolfController:ApiController
  {
    私人静态只读字符串租客= System.Configuration.ConfigurationManager.AppSettings [IDA:租客];
    私人静态只读字符串TenantGuid = System.Configuration.ConfigurationManager.AppSettings [IDA:TenantGuid];
    私人静态只读字符串客户端Id = System.Configuration.ConfigurationManager.AppSettings [IDA:客户端ID];
    私人静态只读字符串密码= System.Configuration.ConfigurationManager.AppSettings [IDA:密码]; //客户端密钥,有效期为一年或两年
    私人静态只读字符串RESOURCEID = System.Configuration.ConfigurationManager.AppSettings [IDA:资源ID];    // GET:API /狼
    公共异步任务&LT;&IEnumerable的LT;狼&GT;&GT;得到()
    {
      AuthenticationResponse authenticationResponse =等待GetAuthenticationResponse();
      字符串结果=等待DoSomeDataOperations(authenticationResponse);      返回新狼[]
      {
              新狼()
              {
                ID = 1,
                名称=结果
              }
      };
    }    私有静态异步任务&LT; AuthenticationResponse&GT; GetAuthenticationResponse()
    {
      //https://samlman.word$p$pss.com/2015/06/04/getting-an-azure-access-token-for-a-web-application-entirely-in-$c$c/
      //创建值的集合发送到POST      清单&LT; KeyValuePair&LT;字符串,字符串&GT;&GT;瓦尔斯=新的List&LT; KeyValuePair&LT;字符串,字符串&GT;&GT;();
      vals.Add(新KeyValuePair&LT;字符串,字符串&GT;(grant_type,client_credentials));
      vals.Add(新KeyValuePair&LT;字符串,字符串&GT;(资源,RESOURCEID));
      vals.Add(新KeyValuePair&LT;字符串,字符串&GT;(CLIENT_ID,客户端Id));
      vals.Add(新KeyValuePair&LT;字符串,字符串&GT;(client_secret,密码));
      vals.Add(新KeyValuePair&LT;字符串,字符串&GT;(用户名,someUser@someTenant.onmicrosoft.com));
      vals.Add(新KeyValuePair&LT;字符串,字符串&GT;(密码,XXXXXX));      //创建帖子网址
      字符串的URL =的String.Format(https://login.microsoftonline.com/{0}/oauth2/token,TenantGuid);      //发出请求
      HttpClient的HC =新的HttpClient();      // EN形式code中的数据我们要发布
      HttpContent内容=新FormUrlEn codedContent(瓦尔斯);      //插上后身体
      HTT presponseMessage人力资源管理= hc.PostAsync(URL,内容)。结果;      AuthenticationResponse authenticationResponse = NULL;
      如果(hrm.IsSuccessStatus code)
      {
        //获取流
        流数据=等待hrm.Content.ReadAsStreamAsync();
        DataContractJsonSerializer序列化=新DataContractJsonSerializer(typeof运算(AuthenticationResponse));
        authenticationResponse =(AuthenticationResponse)serializer.ReadObject(数据);
      }
      其他
      {
        authenticationResponse =新AuthenticationResponse(){的ErrorMessage = hrm.Status code ++ hrm.RequestMessage};
      }      返回authenticationResponse;
    }    私有静态异步任务&LT;串GT; DoSomeDataOperations(AuthenticationResponse authResult)
    {
      如果(authResult.ErrorMessage!= NULL)
      {
        回归的问题得到的authToken:+ authResult.ErrorMessage;
      }
      使用(HttpClient的HttpClient的=新的HttpClient())
      {
        httpClient.BaseAddress =新的URI(RESOURCEID);
        httpClient.Timeout =新时间跨度(0,2,0); //2分钟
        httpClient.DefaultRequestHeaders.Add(OData的-MAXVERSION,4.0);
        httpClient.DefaultRequestHeaders.Add(的OData版,4.0);
        httpClient.DefaultRequestHeaders.Add(的OData版,4.0);
        httpClient.DefaultRequestHeaders.Accept.Add(新MediaTypeWithQualityHeaderValue(应用/ JSON));
        httpClient.DefaultRequestHeaders.Authorization =新AuthenticationHeaderValue(旗手,authResult.access_token);
        // Retreive实体////////////////////////////////////////////// ///////////////////////////////////////
        VAR retrieveResponse =等待httpClient.GetAsync(/ API /数据/ 8.0 / $反馈=选择题目,评价和放大器; $顶部= 10);
        // VAR retrieveResponse =等待httpClient.GetAsync(/ API /数据/ 8.0 / $的元数据);        如果(!retrieveResponse.IsSuccessStatus code)
        {
          返回retrieveResponse.ReasonPhrase;        }
        返回它的工作!
      }
    }


解决方案

我终于找到了解决办法。通过若昂R.在这篇文章中提供的:

https://community.dynamics.com/crm/f/117/ T / 193506

首先:忘记ADAL

我的问题是整个过程中,我用错误的网址作为,似乎你不使用阿达尔(或更一般的:用户重定向)时,需要其他的不会忽略。


解决方案

构造以下HTTP-Reqest令牌:

网址:
https://login.windows.net/MyCompanyTenant.onmicrosoft.com/oauth2/token

标题:


  • 的Cache-Control:no-cache的

  • 内容类型:应用程序/ x-WWW的形式urlen codeD

正文:


  • CLIENT_ID:YourClientIdFromAzureAd

  • 资源: https://myCompanyTenant.crm.dynamics.com

  • 用户名:yourServiceUser@myCompanyTenant.onmicrosoft.com

  • 密码:yourServiceUserPassword

  • grant_type:密码

  • (可选)client_secret:YourClientSecretFromAzureAd

构建如下的HTTP请求的访问的WebAPI:

网址: HTTPS://MyCompanyTenant.api.crm。 dynamics.com/api/data/v8.0/accounts

标题:


  • 的Cache-Control:no-cache的

  • 接受:应用/ JSON

  • 的OData-版本:4.0

  • 授权:承载TokenRetrievedFomRequestAbove


C#-Solution

 公共类AuthenticationResponse
  {
    公共字符串token_type {搞定;组; }
    公共字符串范围{搞定;组; }
    公众诠释expires_in {搞定;组; }
    公众诠释expires_on {搞定;组; }
    公众诠释not_before {搞定;组; }
    公共字符串资源{搞定;组; }
    公共字符串的access_token {搞定;组; }
    公共字符串refresh_token {搞定;组; }
    公共字符串id_token {搞定;组; }
  }私有静态异步任务&LT; AuthenticationResponse&GT; GetAuthenticationResponse()
{//创建值的集合发送到POST  清单&LT; KeyValuePair&LT;字符串,字符串&GT;&GT;瓦尔斯=新的List&LT; KeyValuePair&LT;字符串,字符串&GT;&GT;();  vals.Add(新KeyValuePair&LT;字符串,字符串&GT;(CLIENT_ID,客户端Id));
  vals.Add(新KeyValuePair&LT;字符串,字符串&GT;(资源,RESOURCEID));
  vals.Add(新KeyValuePair&LT;字符串,字符串&GT;(用户名,yxcyxc@xyxc.onmicrosoft.com));
  vals.Add(新KeyValuePair&LT;字符串,字符串&GT;(密码,yxcycx));
  vals.Add(新KeyValuePair&LT;字符串,字符串&GT;(grant_type,密码));
  vals.Add(新KeyValuePair&LT;字符串,字符串&GT;(client_secret,密码));
  字符串的URL =的String.Format(https://login.windows.net/{0}/oauth2/token,租客);  使用(HttpClient的HttpClient的=新的HttpClient())
  {    //发出请求
httpClient.DefaultRequestHeaders.Add(缓存控制,无缓存);
//httpClient.DefaultRequestHeaders.Add(\"Content-Type,应用程序/ x-WWW的形式urlen codeD);// EN形式code中的数据我们要发布
HttpContent内容=新FormUrlEn codedContent(瓦尔斯);//插上后身体
HTT presponseMessage人力资源管理= httpClient.PostAsync(URL,内容)。结果;AuthenticationResponse authenticationResponse = NULL;
如果(hrm.IsSuccessStatus code)
{
  //获取流
  流数据=等待hrm.Content.ReadAsStreamAsync();
  DataContractJsonSerializer序列化=新DataContractJsonSerializer(typeof运算(AuthenticationResponse));
      authenticationResponse =(AuthenticationResponse)serializer.ReadObject(数据);
    }    返回authenticationResponse;
  }
}私有静态异步任务DataOperations(AuthenticationResponse authResult)
{  使用(HttpClient的HttpClient的=新的HttpClient())
  {
    httpClient.BaseAddress =新的URI(ResourceApiId);
    httpClient.Timeout =新时间跨度(0,2,0); //2分钟
    httpClient.DefaultRequestHeaders.Add(OData的-MAXVERSION,4.0);
    httpClient.DefaultRequestHeaders.Add(的OData版,4.0);
    httpClient.DefaultRequestHeaders.Add(缓存控制,无缓存);
    httpClient.DefaultRequestHeaders.Accept.Add(新MediaTypeWithQualityHeaderValue(应用/ JSON));
    httpClient.DefaultRequestHeaders.Authorization =新AuthenticationHeaderValue(旗手,authResult.access_token);    帐户帐户=新帐户();
    account.name =测试帐号;
    account.telephone1 =555-555;    字符串内容=的String.Empty;
    内容= JsonConvert.SerializeObject(帐户,新JsonSerializerSettings(){DefaultValueHandling = DefaultValueHandling.Ignore});    //创建实体////////////////////////////////////////////// ///////////////////////////////////////
    HTT prequestMessage要求=新HTT prequestMessage(HttpMethod.Post,API /数据/ 8.0 /账户);
    request.Content =新的StringContent(内容);
    request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(应用/ JSON);
    HTT presponseMessage响应=等待httpClient.SendAsync(请求);
    如果(response.IsSuccessStatus code)
    {
      Console.WriteLine(帐户{0}创建,account.name);
    }
    其他
    {
      抛出新的异常(的String.Format(无法​​创建帐户{0},原因是{1}'。
        , 用户名
        ,response.ReasonPhrase));
    }
(......)

Refering to not answered Questions:

401- Unauthorized authentication using REST API Dynamics CRM with Azure AD

and

Dynamics CRM Online 2016 - Daemon / Server application Azure AD authentication error to Web Api

and

Dynamics CRM 2016 Online Rest API with client credentials OAuth flow

I need a communication between an Web-Service in azure cloud and Dynamics CRM Online 2016 WITHOUT any loginscreen! The service will have a REST api which triggers CRUD operations on the CRM (also I will implement an authentification)

I think this is called "Confidential Client" or "Daemon Server" or just "Server-to-Server"

I set up my Service properly in Azure AD (with "delegate permission = access dynamics online as organization user", there are no other options)

I created a ASP.NET WEB API project in VS which created my WebService in Azure and also the entry ofr the "Application" within Azure AD of the CRM

My Code looks like this (pls ignore the EntityType and returnValue):

 public class WolfController : ApiController
  {
    private static readonly string Tenant = "xxxxx.onmicrosoft.com";
    private static readonly string ClientId = "dxxx53-42xx-43bc-b14e-c1e84b62752d";
    private static readonly string Password = "j+t/DXjn4PMVAHSvZGd5sptGxxxxxxxxxr5Ki8KU="; // client secret, valid for one or two years
    private static readonly string ResourceId = "https://tenantname-naospreview.crm.dynamics.com/";


    public static async Task<AuthenticationResult> AcquireAuthentificationToken()
    {
      AuthenticationContext authenticationContext = new AuthenticationContext("https://login.windows.net/"+ Tenant);
      ClientCredential clientCredentials = new ClientCredential(ClientId, Password);   
      return await authenticationContext.AcquireTokenAsync(ResourceId, clientCredentials);
    }

    // GET: just for calling the DataOperations-method via a GET, ignore the return
    public async Task<IEnumerable<Wolf>> Get()
    {
      AuthenticationResult result = await AcquireAuthentificationToken();
      await DataOperations(result);    

      return new Wolf[] { new Wolf() };
    }


    private static async Task DataOperations(AuthenticationResult authResult)
    {
      using (HttpClient httpClient = new HttpClient())
      {
        httpClient.BaseAddress = new Uri(ResourceId);
        httpClient.Timeout = new TimeSpan(0, 2, 0); //2 minutes
        httpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
        httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);

        Account account = new Account();
        account.name = "Test Account";
        account.telephone1 = "555-555";

        string content = String.Empty;
        content = JsonConvert.SerializeObject(account, new JsonSerializerSettings() {DefaultValueHandling = DefaultValueHandling.Ignore});            

        //Create Entity/////////////////////////////////////////////////////////////////////////////////////
        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "api/data/v8.1/accounts");
        request.Content = new StringContent(content);
        request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
        HttpResponseMessage response = await httpClient.SendAsync(request);
        if (response.IsSuccessStatusCode)
        {
          Console.WriteLine("Account '{0}' created.", account.name);
        }
        else //Getting Unauthorized here
        {
          throw new Exception(String.Format("Failed to create account '{0}', reason is '{1}'.",account.name, response.ReasonPhrase));
        } ... and more code

When calling my GET request I get the 401 Unauthorized although I got and send the AccessToken.

Any Ideas?

EDIT: I also tried the code adviced in this blog (only source which seemed to solve the problem, didnt work either):

https://samlman.wordpress.com/2015/06/04/getting-an-azure-access-token-for-a-web-application-entirely-in-code/

With this code:

public class WolfController : ApiController
  {
    private static readonly string Tenant = System.Configuration.ConfigurationManager.AppSettings["ida:Tenant"];
    private static readonly string TenantGuid = System.Configuration.ConfigurationManager.AppSettings["ida:TenantGuid"];
    private static readonly string ClientId = System.Configuration.ConfigurationManager.AppSettings["ida:ClientID"];
    private static readonly string Password = System.Configuration.ConfigurationManager.AppSettings["ida:Password"]; // client secret, valid for one or two years
    private static readonly string ResourceId = System.Configuration.ConfigurationManager.AppSettings["ida:ResourceID"];

    // GET: api/Wolf
    public async Task<IEnumerable<Wolf>> Get()
    {
      AuthenticationResponse authenticationResponse = await GetAuthenticationResponse();
      String result = await DoSomeDataOperations(authenticationResponse);

      return new Wolf[]
      {
              new Wolf()
              {
                Id = 1,
                Name = result
              }
      };
    }

    private static async Task<AuthenticationResponse> GetAuthenticationResponse()
    {
      //https://samlman.wordpress.com/2015/06/04/getting-an-azure-access-token-for-a-web-application-entirely-in-code/
      //create the collection of values to send to the POST

      List<KeyValuePair<string, string>> vals = new List<KeyValuePair<string, string>>();
      vals.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
      vals.Add(new KeyValuePair<string, string>("resource", ResourceId));
      vals.Add(new KeyValuePair<string, string>("client_id", ClientId));
      vals.Add(new KeyValuePair<string, string>("client_secret", Password));
      vals.Add(new KeyValuePair<string, string>("username", "someUser@someTenant.onmicrosoft.com"));
      vals.Add(new KeyValuePair<string, string>("password", "xxxxxx"));

      //create the post Url   
      string url = string.Format("https://login.microsoftonline.com/{0}/oauth2/token", TenantGuid);

      //make the request
      HttpClient hc = new HttpClient();

      //form encode the data we’re going to POST
      HttpContent content = new FormUrlEncodedContent(vals);

      //plug in the post body
      HttpResponseMessage hrm = hc.PostAsync(url, content).Result;

      AuthenticationResponse authenticationResponse = null;
      if (hrm.IsSuccessStatusCode)
      {
        //get the stream
        Stream data = await hrm.Content.ReadAsStreamAsync();
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof (AuthenticationResponse));
        authenticationResponse = (AuthenticationResponse) serializer.ReadObject(data);
      }
      else
      {
        authenticationResponse = new AuthenticationResponse() {ErrorMessage = hrm.StatusCode +" "+hrm.RequestMessage};
      }

      return authenticationResponse;
    }

    private static async Task<String> DoSomeDataOperations(AuthenticationResponse authResult)
    {
      if (authResult.ErrorMessage != null)
      {
        return "problem getting AuthToken: " + authResult.ErrorMessage;
      }


      using (HttpClient httpClient = new HttpClient())
      {
        httpClient.BaseAddress = new Uri(ResourceId);
        httpClient.Timeout = new TimeSpan(0, 2, 0); //2 minutes
        httpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
        httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");
        httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.access_token);


        //Retreive Entity/////////////////////////////////////////////////////////////////////////////////////
        var retrieveResponse = await httpClient.GetAsync("/api/data/v8.0/feedback?$select=title,rating&$top=10");
        //var retrieveResponse = await httpClient.GetAsync("/api/data/v8.0/$metadata");

        if (!retrieveResponse.IsSuccessStatusCode)
        {
          return retrieveResponse.ReasonPhrase;

        }
        return "it worked!";
      }
    }

解决方案

I finally found a solution. Provided by Joao R. in this Post:

https://community.dynamics.com/crm/f/117/t/193506

First of all: FORGET ADAL

My problem was the whole time that I was using "wrong" URLS as it seems you need other adresses when not using Adal (or more general: user-redirect).


Solution

Construct following HTTP-Reqest for the Token:

URL: https://login.windows.net/MyCompanyTenant.onmicrosoft.com/oauth2/token

Header:

  • Cache-Control: no-cache
  • Content-Type: application/x-www-form-urlencoded

Body:

  • client_id: YourClientIdFromAzureAd
  • resource: https://myCompanyTenant.crm.dynamics.com
  • username: yourServiceUser@myCompanyTenant.onmicrosoft.com
  • password: yourServiceUserPassword
  • grant_type: password
  • (optional) client_secret: YourClientSecretFromAzureAd

Construct the following HTTP-Request for the access to WebApi:

URL: https://MyCompanyTenant.api.crm.dynamics.com/api/data/v8.0/accounts

Header:

  • Cache-Control: no-cache
  • Accept: application/json
  • OData-Version: 4.0
  • Authorization: Bearer TokenRetrievedFomRequestAbove

C#-Solution

  public class AuthenticationResponse
  {
    public string token_type { get; set; }
    public string scope { get; set; }
    public int expires_in { get; set; }
    public int expires_on { get; set; }
    public int not_before { get; set; }
    public string resource { get; set; }
    public string access_token { get; set; }
    public string refresh_token { get; set; }
    public string id_token { get; set; }
  }

private static async Task<AuthenticationResponse> GetAuthenticationResponse()
{

//create the collection of values to send to the POST

  List<KeyValuePair<string, string>> vals = new List<KeyValuePair<string, string>>();

  vals.Add(new KeyValuePair<string, string>("client_id", ClientId));  
  vals.Add(new KeyValuePair<string, string>("resource", ResourceId));
  vals.Add(new KeyValuePair<string, string>("username", "yxcyxc@xyxc.onmicrosoft.com"));
  vals.Add(new KeyValuePair<string, string>("password", "yxcycx"));
  vals.Add(new KeyValuePair<string, string>("grant_type", "password"));
  vals.Add(new KeyValuePair<string, string>("client_secret", Password));


  string url = string.Format("https://login.windows.net/{0}/oauth2/token", Tenant);

  using (HttpClient httpClient = new HttpClient())
  {

    //make the request
httpClient.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
//httpClient.DefaultRequestHeaders.Add("Content-Type", "application/x-www-form-urlencoded");

//form encode the data we’re going to POST
HttpContent content = new FormUrlEncodedContent(vals);

//plug in the post body
HttpResponseMessage hrm = httpClient.PostAsync(url, content).Result;

AuthenticationResponse authenticationResponse = null;
if (hrm.IsSuccessStatusCode)
{
  //get the stream
  Stream data = await hrm.Content.ReadAsStreamAsync();
  DataContractJsonSerializer serializer = new 

DataContractJsonSerializer(typeof(AuthenticationResponse));
      authenticationResponse = (AuthenticationResponse)serializer.ReadObject(data);
    }

    return authenticationResponse;
  }
}

private static async Task DataOperations(AuthenticationResponse authResult)
{

  using (HttpClient httpClient = new HttpClient())
  {
    httpClient.BaseAddress = new Uri(ResourceApiId);
    httpClient.Timeout = new TimeSpan(0, 2, 0); //2 minutes
    httpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
    httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");
    httpClient.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.access_token);

    Account account = new Account();
    account.name = "Test Account";
    account.telephone1 = "555-555";

    string content = String.Empty;
    content = JsonConvert.SerializeObject(account, new JsonSerializerSettings() { DefaultValueHandling = DefaultValueHandling.Ignore });

    //Create Entity/////////////////////////////////////////////////////////////////////////////////////
    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "api/data/v8.0/accounts");
    request.Content = new StringContent(content);
    request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
    HttpResponseMessage response = await httpClient.SendAsync(request);
    if (response.IsSuccessStatusCode)
    {
      Console.WriteLine("Account '{0}' created.", account.name);
    }
    else
    {
      throw new Exception(String.Format("Failed to create account '{0}', reason is '{1}'."
        , account.name
        , response.ReasonPhrase));
    }
(...)

这篇关于使用ADAL C#作为机密用户/服务器守护程序/服务器到服务器 - 401未授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆