-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathReseller.cs
266 lines (234 loc) · 10.9 KB
/
Reseller.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
*********************************************************/
namespace Microsoft.Partner.CSP.Api.V1.Samples
{
using IdentityModel.Clients.ActiveDirectory;
using System;
using System.IO;
using System.Net;
using System.Web;
using System.Web.Helpers;
public static class Reseller
{
/// <summary>
/// This method returns the CID of the reseller given the Microsoft ID and the sales agent token
/// </summary>
/// <param name="microsoftId">Microsoft ID of the reseller</param>
/// <param name="sa_Token">sales agent token of the reseller</param>
/// <returns>CID of the reseller</returns>
public static string GetCid(string microsoftId, string sa_Token)
{
return GetResellerCid(microsoftId, sa_Token);
}
/// <summary>
/// Get the latest sales agent token given the AD Authorization Token
/// </summary>
/// <param name="adAuthorizationToken">AD Authorization Token</param>
/// <param name="saAuthorizationToken">Sales agent authorization token, can be null</param>
/// <returns>Latest sales agent token</returns>
public static AuthorizationToken GetSA_Token(AuthorizationToken adAuthorizationToken, AuthorizationToken saAuthorizationToken = null)
{
if (saAuthorizationToken == null || (saAuthorizationToken != null && saAuthorizationToken.IsNearExpiry()))
{
//// Refresh the token on one of two conditions
//// 1. If the token has never been retrieved
//// 2. If the token is near expiry
var saToken = GetSA_Token(adAuthorizationToken.AccessToken);
saAuthorizationToken = new AuthorizationToken(saToken.access_token, Convert.ToInt64(saToken.expires_in));
}
return saAuthorizationToken;
}
/// <summary>
/// Get the latest AD token given the reseller domain and client credentials
/// </summary>
/// <param name="domain">domain of the reseller</param>
/// <param name="clientId">clientID of the application</param>
/// <param name="clientSecret">client secret of the application, also refered to as key</param>
/// <param name="adAuthorizationToken">ad authorization token, can be null</param>
/// <returns>Latest AD Authorization token</returns>
public static AuthorizationToken GetAD_Token(string domain, string clientId, string clientSecret, AuthorizationToken adAuthorizationToken = null)
{
if (adAuthorizationToken == null || (adAuthorizationToken != null && adAuthorizationToken.IsNearExpiry()))
{
//// Refresh the token on one of two conditions
//// 1. If the token has never been retrieved
//// 2. If the token is near expiry
var adToken = GetADToken(domain, clientId, clientSecret);
adAuthorizationToken = new AuthorizationToken(adToken.access_token, Convert.ToInt64(adToken.expires_in));
}
return adAuthorizationToken;
}
/// <summary>
/// Given the reseller domain, clientid and clientsecret of the app, this method helps to retrieve the AD token
/// </summary>
/// <param name="resellerDomain">domain of the reseller including .onmicrosoft.com</param>
/// <param name="clientId">AppId from the azure portal registered for this app</param>
/// <param name="clientSecret">Secret from the azure portal registered for this app</param>
/// <returns>this is the authentication token object that contains access_token, expiration time, can be used to get the authorization token from a resource</returns>
private static dynamic GetADToken(string resellerDomain, string clientId, string clientSecret)
{
var request = WebRequest.Create(string.Format("https://login.microsoftonline.com/{0}/oauth2/token", resellerDomain));
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string content = string.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&resource={2}", clientId, HttpUtility.UrlEncode(clientSecret), HttpUtility.UrlEncode("https://graph.windows.net"));
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(content);
}
try
{
Utilities.PrintWebRequest((HttpWebRequest)request, content);
var response = request.GetResponse();
using (var reader = new StreamReader(response.GetResponseStream()))
{
var responseContent = reader.ReadToEnd();
var adResponse = Json.Decode(responseContent);
Utilities.PrintWebResponse((HttpWebResponse)response, responseContent);
return adResponse;
}
}
catch (WebException webException)
{
if (webException.Response != null)
{
using (var reader = new StreamReader(webException.Response.GetResponseStream()))
{
var responseContent = reader.ReadToEnd();
Utilities.PrintErrorResponse((HttpWebResponse)webException.Response, responseContent);
}
}
}
return string.Empty;
}
/// <summary>
/// Given the ad token this method retrieves the sales agent token for accessing any of the partner apis
/// </summary>
/// <param name="adToken">this is the access_token we get from AD</param>
/// <returns>the sales agent token object which contains access_token, expiration duration</returns>
private static dynamic GetSA_Token(string adToken)
{
var request = (HttpWebRequest)WebRequest.Create("https://api.cp.microsoft.com/my-org/tokens");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Accept = "application/json";
request.Headers.Add("api-version", "2015-03-31");
request.Headers.Add("x-ms-correlation-id", Guid.NewGuid().ToString());
request.Headers.Add("Authorization", "Bearer " + adToken);
string content = "grant_type=client_credentials";
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(content);
}
try
{
Utilities.PrintWebRequest(request, content);
var response = request.GetResponse();
using (var reader = new StreamReader(response.GetResponseStream()))
{
var responseContent = reader.ReadToEnd();
Utilities.PrintWebResponse((HttpWebResponse)response, responseContent);
return Json.Decode(responseContent);
}
}
catch (WebException webException)
{
using (var reader = new StreamReader(webException.Response.GetResponseStream()))
{
var responseContent = reader.ReadToEnd();
Utilities.PrintErrorResponse((HttpWebResponse)webException.Response, responseContent);
}
}
return string.Empty;
}
/// <summary>
/// This method is used to retrieve the reseller cid given the reseller microsoft id, and is used to perform any transactions by the reseller
/// </summary>
/// <param name="resellerMicrosoftId">Microsoft ID of the reseller</param>
/// <param name="accessToken">unexpired access token to call the partner apis</param>
/// <returns>Reseller cid that is required to use the partner apis</returns>
private static string GetResellerCid(string resellerMicrosoftId, string accessToken)
{
var request = (HttpWebRequest)WebRequest.Create(string.Format("https://api.cp.microsoft.com/customers/get-by-identity?provider=AAD&type=tenant&tid={0}", resellerMicrosoftId));
request.Method = "GET";
request.Accept = "application/json";
request.Headers.Add("api-version", "2015-03-31");
request.Headers.Add("x-ms-correlation-id", Guid.NewGuid().ToString());
request.Headers.Add("x-ms-tracking-id", Guid.NewGuid().ToString());
request.Headers.Add("Authorization", "Bearer " + accessToken);
try
{
Utilities.PrintWebRequest(request, string.Empty);
var response = request.GetResponse();
using (var reader = new StreamReader(response.GetResponseStream()))
{
var responseContent = reader.ReadToEnd();
var crestResponse = Json.Decode(responseContent);
Utilities.PrintWebResponse((HttpWebResponse)response, responseContent);
return crestResponse.id;
}
}
catch (WebException webException)
{
using (var reader = new StreamReader(webException.Response.GetResponseStream()))
{
var responseContent = reader.ReadToEnd();
Utilities.PrintErrorResponse((HttpWebResponse)webException.Response, responseContent);
}
}
return string.Empty;
}
/// <summary>
/// Get the token for authenticating requests to Azure Resource Manager in customer tenant.
/// </summary>
/// <param name="appId">appid that is registered for this application in Azure Active Directory (AAD)</param>
/// <param name="credentialName">Internet or network address of entry in Credential Manager (Windows Credentials / Generic Credential) </param>
/// <param name="customerTenantId">cid of the customer</param>
/// <param name="azureAuthToken">Existing token (if available)</param>
/// <returns>Azure Auth Token in the context of the customer tenant.</returns>
public static string GetAzureAuthTokenForCustomerTenant(string appId, string credentialName, string customerTenantId, AuthorizationToken azureAuthToken = null)
{
if (azureAuthToken == null || (azureAuthToken != null && azureAuthToken.IsNearExpiry()))
{
//// Refresh the token on one of two conditions
//// 1. If the token has never been retrieved
//// 2. If the token is near expiry
var azToken = GetAzureAuthTokenForCustomerTenant(appId, credentialName, customerTenantId);
azureAuthToken = new AuthorizationToken(azToken.AccessToken, azToken.ExpiresOn);
}
return azureAuthToken.AccessToken;
}
/// <summary>
/// Get the token for authenticating requests to Azure Resource Manager in customer tenant.
/// </summary>
/// <param name="appId">appid that is registered for this application in Azure Active Directory (AAD)</param>
/// <param name="key">This is the key for this application in Azure Active Directory</param>
/// <param name="customerTenantId">cid of the customer</param>
/// <returns>Azure Auth Token in the context of the customer tenant.</returns>
private static AuthenticationResult GetAzureAuthTokenForCustomerTenant(string appId, string credentialName, string customerTenantId)
{
AuthenticationResult authResult = null;
string resource = "https://management.core.windows.net/";
var authenticationContext = new AuthenticationContext("https://login.windows.net/" + customerTenantId);
try
{
authResult = authenticationContext.AcquireTokenSilent(resource: resource, clientId: appId);
}
catch (AdalException aex)
{
if (aex.ErrorCode == "failed_to_acquire_token_silently")
{
UserCredential uc = CredentialManager.GetCredential(credentialName);
authResult = authenticationContext.AcquireToken(resource: resource, clientId: appId, userCredential: uc);
}
}
catch (Exception ex)
{
throw;
}
return authResult;
}
}
}