Skip to content

Commit b6ccf6b

Browse files
author
Justin Marks
committed
Edits to bring samples inline and fix some errors in readmes
1 parent 33ca7fb commit b6ccf6b

File tree

8 files changed

+86
-136
lines changed

8 files changed

+86
-136
lines changed

ClientLibraryConsoleAppSample/Program.cs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,22 @@ namespace ClientLibraryConsoleAppSample
1313
{
1414
class Program
1515
{
16+
//============= Config [Edit these with your settings] =====================
17+
internal const string vstsCollectionUrl = "http://myaccount.visualstudio.com"; //change to the URL of your VSTS account
18+
// internal const string vstsCollectioUrl = "http://myserver:8080/tfs/DefaultCollection" alternate URL for a TFS collection
19+
//==========================================================================
20+
1621
//Console application to execute a user defined work item query
1722
static void Main(string[] args)
1823
{
19-
//=========== Config [edit these] ===================
20-
string collectionUri = "https://fabrikam-fiber-inc.visualstudio.com";
21-
Wiql query = new Wiql() { Query = "Select [State], [Title] from WorkItems where [Work Item Type] = 'Bug' And [Tags] Contains 'findMe'" };
22-
//===================================================
23-
2424
//Prompt user for credential for collection specified above
2525
VssCredentials cred = new VssClientCredentials(false);
2626
cred.PromptType = CredentialPromptType.PromptIfNeeded;
27-
VssConnection connection = new VssConnection(new Uri(collectionUri), cred);
27+
VssConnection connection = new VssConnection(new Uri(vstsCollectionUrl), cred);
2828

2929
//create http client and query for resutls
3030
WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();
31+
Wiql query = new Wiql() { Query = "Select [State], [Title] from WorkItems where [Work Item Type] = 'Bug' And [Tags] Contains 'findMe'" };
3132
WorkItemQueryResult queryResults = witClient.QueryByWiqlAsync(query).Result;
3233

3334
//Display reults in console
@@ -42,13 +43,6 @@ static void Main(string[] args)
4243
Console.WriteLine(item.Id);
4344
}
4445
}
45-
46-
//prevetns console from closing
47-
while (true)
48-
{
49-
50-
}
51-
5246
}
5347
}
5448
}

ClientLibraryConsoleAppSample/README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ git clone https://github.com/Microsoft/vsts-auth-samples.git
1717

1818
1. Navigate to the sample in cloned repo `vsts-auth-samples/ClientLibraryConsoleAppSample/`
1919
2. Use [Nuget package restore](https://docs.microsoft.com/en-us/nuget/consume-packages/package-restore) to ensure you have all dependencies installed
20-
3. Open the solution file `ClientLibraryConsoleAppSample.sln` in [Visual Studio IDE 2017](https://www.visualstudio.com/downloads/)
21-
4. Open CS file `Program.cs` and there will be 2 input fields:
22-
* `collectionUri` - Mutable value. This is the url to your VSTS/TFS account.
23-
* `query` - Mutable value. This is the WIQL query you want to execute. Replace this with any query you want to execute.
20+
3. Open the solution file `ClientLibraryConsoleAppSample.csproj` in [Visual Studio 2017](https://www.visualstudio.com/downloads/)
21+
4. Open CS file `Program.cs` and there is a section with input values to change at the top of the class:
22+
* `vstsCollectionUrl` - Mutable value. This is the url to your VSTS/TFS collection, e.g. http://myaccount.visualstudio.com for VSTS or http://myserver:8080/tfs/DefaultCollection for TFS.
2423
5. Build and run solution. After running you should see a list of the IDs all work items which match your query restrictions.

DeviceProfileSample/Program.cs

Lines changed: 50 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -13,106 +13,83 @@ namespace DeviceProfileSample
1313
{
1414
public class Program
1515
{
16-
public const string resource_vsts = "499b84ac-1321-427f-aa17-267ca6975798";
17-
public const string clientId_vs = "872cd9fa-d31f-45e0-9eab-6e460a02d1f1";
18-
public static void Main(string[] args)
19-
{
20-
//============= Config [Edit these with your settings] =====================
21-
var vstsAccountUri = "https://mseng.VisualStudio.com";
22-
var restEndpoint = "_apis/projects?api-version=2.0";
23-
//==========================================================================
16+
//============= Config [Edit these with your settings] =====================
17+
internal const string vstsCollectionUrl = "http://myaccount.visualstudio.com"; //change to the URL of your VSTS account
18+
//==========================================================================
2419

25-
UserData(vstsAccountUri,restEndpoint);
20+
internal const string VSTSResourceId = "499b84ac-1321-427f-aa17-267ca6975798"; //Static value to target VSTS. Do not change
21+
internal const string clientId = "872cd9fa-d31f-45e0-9eab-6e460a02d1f1"; //VS ClientId. Please use this instead of your app's clientId
2622

27-
//prevents console from closing immediately at the end of output
28-
Console.ReadLine();
29-
}
30-
31-
static void UserData(string vstsAccountUri, string restEndpoint)
23+
public static void Main(string[] args)
3224
{
33-
//get auth token
34-
AuthenticationResult result = GetToken(null);
35-
var authHeader = new AuthenticationHeaderValue("Bearer", result.AccessToken);
36-
37-
//call VSTS REST API
38-
using (var client = new HttpClient())
25+
AuthenticationContext ctx = GetAuthenticationContext(null);
26+
AuthenticationResult result = null;
27+
try
3928
{
40-
client.BaseAddress = new Uri(vstsAccountUri);
41-
client.DefaultRequestHeaders.Accept.Clear();
42-
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
43-
client.DefaultRequestHeaders.Add("User-Agent", "VstsRestApiSamples");
44-
client.DefaultRequestHeaders.Add("X-TFS-FedAuthRedirect", "Suppress");
45-
client.DefaultRequestHeaders.Authorization = authHeader;
46-
47-
//connect to REST endpoint
48-
HttpResponseMessage response = client.GetAsync(restEndpoint).Result;
29+
DeviceCodeResult codeResult = ctx.AcquireDeviceCodeAsync(VSTSResourceId, clientId).Result;
30+
result = ctx.AcquireTokenByDeviceCodeAsync(codeResult).Result;
31+
Console.WriteLine("Token expires on: " + result.ExpiresOn);
4932

50-
if (response.IsSuccessStatusCode)
51-
{
52-
Console.WriteLine("\tSuccessful REST call\n");
53-
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
54-
}
55-
else
56-
{
57-
Console.WriteLine("{0}:{1}", response.StatusCode, response.ReasonPhrase);
58-
}
33+
var bearerAuthHeader = new AuthenticationHeaderValue("Bearer", result.AccessToken);
34+
ListProjects(VSTSAccountName, bearerAuthHeader);
35+
}
36+
catch (Exception ex)
37+
{
38+
Console.ForegroundColor = ConsoleColor.Red;
39+
Console.WriteLine("Something went wrong.");
40+
Console.WriteLine("Message: " + exc.Message + "\n");
5941
}
42+
return result;
6043
}
6144

62-
static AuthenticationResult GetToken(string tenant)
45+
private static AuthenticationContext GetAuthenticationContext(string tenant)
6346
{
6447
AuthenticationContext ctx = null;
6548
if (tenant != null)
6649
ctx = new AuthenticationContext("https://login.microsoftonline.com/" + tenant);
6750
else
6851
{
69-
ctx = new AuthenticationContext("https://login.microsoftonline.com/common");
52+
ctx = new AuthenticationContext("https://login.windows.net/common");
7053
if (ctx.TokenCache.Count > 0)
7154
{
7255
string homeTenant = ctx.TokenCache.ReadItems().First().TenantId;
7356
ctx = new AuthenticationContext("https://login.microsoftonline.com/" + homeTenant);
7457
}
7558
}
76-
AuthenticationResult result = null;
77-
try
78-
{
79-
result = ctx.AcquireTokenSilentAsync(resource_vsts, clientId_vs).Result;
80-
}
81-
catch (Exception exc)
59+
60+
return ctx;
61+
}
62+
63+
private static void ListProjects(string vstsAccountName, AuthenticationHeaderValue authHeader)
64+
{
65+
// use the httpclient
66+
using (var client = new HttpClient())
8267
{
83-
var adalEx = exc.InnerException as AdalException;
84-
if ((adalEx != null) && (adalEx.ErrorCode == "failed_to_acquire_token_silently"))
68+
client.BaseAddress = new Uri(vstsCollectionUrl);
69+
client.DefaultRequestHeaders.Accept.Clear();
70+
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
71+
client.DefaultRequestHeaders.Add("User-Agent", "VstsRestApiSamples");
72+
client.DefaultRequestHeaders.Add("X-TFS-FedAuthRedirect", "Suppress");
73+
client.DefaultRequestHeaders.Authorization = authHeader;
74+
75+
// connect to the REST endpoint
76+
HttpResponseMessage response = client.GetAsync("_apis/projects?stateFilter=All&api-version=2.2").Result;
77+
78+
// check to see if we have a succesfull respond
79+
if (response.IsSuccessStatusCode)
80+
{
81+
Console.WriteLine("\tSuccesful REST call");
82+
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
83+
}
84+
else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
8585
{
86-
result = GetTokenViaCode(ctx);
86+
throw new UnauthorizedAccessException();
8787
}
8888
else
8989
{
90-
Console.ForegroundColor = ConsoleColor.Red;
91-
Console.WriteLine("Something went wrong.");
92-
Console.WriteLine("Message: " + exc.InnerException.Message + "\n");
90+
Console.WriteLine("{0}:{1}", response.StatusCode, response.ReasonPhrase);
9391
}
9492
}
95-
return result;
96-
}
97-
98-
static AuthenticationResult GetTokenViaCode(AuthenticationContext ctx)
99-
{
100-
AuthenticationResult result = null;
101-
try
102-
{
103-
DeviceCodeResult codeResult = ctx.AcquireDeviceCodeAsync(resource_vsts, clientId_vs).Result;
104-
Console.ResetColor();
105-
Console.WriteLine("You need to sign in.");
106-
Console.WriteLine("Message: " + codeResult.Message + "\n");
107-
result = ctx.AcquireTokenByDeviceCodeAsync(codeResult).Result;
108-
}
109-
catch (Exception exc)
110-
{
111-
Console.ForegroundColor = ConsoleColor.Red;
112-
Console.WriteLine("Something went wrong.");
113-
Console.WriteLine("Message: " + exc.Message + "\n");
114-
}
115-
return result;
11693
}
11794
}
11895
}

DeviceProfileSample/README.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@ Package: `Microsoft.Identity.Model.Clients.ActiveDirectory` has already been ins
2121

2222
1. Navigate to the sample in cloned repo `vsts-auth-samples/DeviceProfileSample/`
2323
2. Use [Nuget package restore](https://docs.microsoft.com/en-us/nuget/consume-packages/package-restore) to ensure you have all dependencies installed
24-
3. Open the solution file `DeviceProfileSample.sln` in [Visual Studio IDE 2017](https://www.visualstudio.com/downloads/)
25-
4. Open CS file `Program.cs` and there are 4 important fields to be aware of:
26-
* `VSTSResourceId` - Immutable value. Denotes that we need a VSTS access token.
27-
* `clientId` - Immutable value*. *Normally your app's registered AAD clientId, but for VSTS is must be the VS client ID provided.
28-
* `vstsAccountUri` - Mutable value. Denotes your vsts account URL (i.e. https://myaccount.visualstudio.com). Please update this with your account URL.
29-
* `restEndpoint` - Mutable value. Denotes which REST API endpoint we want to hit. We have configured it to return team project information.
24+
3. Open the solution file `DeviceProfileSample.csproj` in [Visual Studio 2017](https://www.visualstudio.com/downloads/)
25+
4. Open CS file `Program.cs` and there is a section with input values to change at the top of the class:
26+
* `vstsCollectionUrl` - Mutable value. This is the url to your VSTS collection, e.g. http://myaccount.visualstudio.com for VSTS.
3027
5. Build and run solution. You should see a console window with instruction on how to authenticate via the Device Profile flow. After authenticating you should see all team project information viewable by the authenticated identity displayed in the console window.

ManagedClientConsoleAppSample/Program.cs

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,50 +14,35 @@ namespace ManagedClientConsoleAppSample
1414
{
1515
class Program
1616
{
17+
//============= Config [Edit these with your settings] =====================
18+
internal const string vstsCollectionUrl = "http://myaccount.visualstudio.com"; //change to the URL of your VSTS account
19+
// internal const string vstsCollectioUrl = "http://myserver:8080/tfs/DefaultCollection" alternate URL for a TFS collection
20+
//==========================================================================
21+
1722
internal const string VSTSResourceId = "499b84ac-1321-427f-aa17-267ca6975798"; //Static value to target VSTS. Do not change
1823
internal const string clientId = "872cd9fa-d31f-45e0-9eab-6e460a02d1f1"; //VS ClientId. Please use this instead of your app's clientId
19-
internal const string VSTSAccountName = "myaccount"; //change to domain of your VSTS account (e.g. "myaccount" when account name is myaccount.visualstudio.com)
2024

21-
static void Main(string[] args)
25+
public static void Main(string[] args)
2226
{
23-
int iteration = 0;
24-
2527
AuthenticationContext ctx = GetAuthenticationContext(null);
2628
AuthenticationResult result = null;
2729
try
2830
{
2931
//PromptBehavior.RefreshSession will enforce an authn prompt every time. NOTE: Auto will take your windows login state if possible
3032
result = ctx.AcquireTokenAsync(VSTSResourceId, clientId, new Uri("urn:ietf:wg:oauth:2.0:oob"), new PlatformParameters(PromptBehavior.Auto)).Result;
3133
Console.WriteLine("Token expires on: " + result.ExpiresOn);
34+
35+
var bearerAuthHeader = new AuthenticationHeaderValue("Bearer", result.AccessToken);
36+
ListProjects(VSTSAccountName, bearerAuthHeader);
3237
}
33-
catch (Exception ex)
38+
catch (UnauthorizedAccessException)
3439
{
35-
throw ex.InnerException;
40+
// If the token has expired, prompt the user with a login prompt
41+
result = ctx.AcquireTokenAsync(VSTSResourceId, clientId, new Uri("urn:ietf:wg:oauth:2.0:oob"), new PlatformParameters(PromptBehavior.Always)).Result;
3642
}
37-
38-
//loop allows you to re-authenticate if you have authenticated with a user that does not have access
39-
var unauthorizedAuthAgain = true;
40-
while (unauthorizedAuthAgain)
43+
catch (Exception ex)
4144
{
42-
Console.WriteLine("({1}) Iteration {0}", iteration++, DateTime.UtcNow);
43-
44-
var bearerAuthHeader = new AuthenticationHeaderValue("Bearer", result.AccessToken);
45-
46-
try
47-
{
48-
ListProjects(VSTSAccountName, bearerAuthHeader);
49-
//unauthorizedAuthAgain = false;
50-
Thread.Sleep(300000); //Sleep for 5 minutes
51-
}
52-
catch (UnauthorizedAccessException)
53-
{
54-
//prompts user with a login prompt, so they can login with a different user when receiving a 401 for the last authenticated user
55-
result = ctx.AcquireTokenAsync(VSTSResourceId, clientId, new Uri("urn:ietf:wg:oauth:2.0:oob"), new PlatformParameters(PromptBehavior.Always)).Result;
56-
}
57-
catch (Exception ex)
58-
{
59-
Console.WriteLine("{0}: {1}", ex.GetType(), ex.Message);
60-
}
45+
Console.WriteLine("{0}: {1}", ex.GetType(), ex.Message);
6146
}
6247
}
6348

@@ -84,7 +69,7 @@ private static void ListProjects(string vstsAccountName, AuthenticationHeaderVal
8469
// use the httpclient
8570
using (var client = new HttpClient())
8671
{
87-
client.BaseAddress = new Uri(String.Format("https://{0}.visualstudio.com", vstsAccountName));
72+
client.BaseAddress = new Uri(vstsCollectionUrl);
8873
client.DefaultRequestHeaders.Accept.Clear();
8974
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
9075
client.DefaultRequestHeaders.Add("User-Agent", "VstsRestApiSamples");

ManagedClientConsoleAppSample/README.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,11 @@ Package: `Microsoft.Identity.Model.Clients.ActiveDirectory` has already been ins
1919

2020
## Step 3: Run the sample
2121

22-
1. Navigate to the ADAL C# sample in cloned repo `vsts-auth-samples/Managed_Client_ADAL_Sample/`
22+
1. Navigate to the ADAL C# sample in cloned repo `vsts-auth-samples/ManagedClientConsoleAppSample/`
2323
2. Use [Nuget package restore](https://docs.microsoft.com/en-us/nuget/consume-packages/package-restore) to ensure you have all dependencies installed
24-
3. Open the solution file `SimpleAdalConsoleApp.sln` in [Visual Studio IDE 2017](https://www.visualstudio.com/downloads/)
25-
4. Open CS file `Program.cs` and there will be 3 input fields:
26-
* `VSTSResourceId` - Immutable value. Denotes that we need a VSTS access token.
27-
* `clientId` - Immutable value*. *Normally your app's registered AAD clientId, but for VSTS is must be the VS client ID provided
28-
* `VSTSAccountName` - Mutable value. Update with the name of the VSTS account you would like to access. (e.g. "myaccount" from myaccount.visualstuido.com)
24+
3. Open the solution file `ManagedClientConsoleAppSample.csproj` in [Visual Studio 2017](https://www.visualstudio.com/downloads/)
25+
4. Open CS file `Program.cs` and there is a section with input values to change at the top of the class:
26+
* `vstsCollectionUrl` - Mutable value. This is the url to your VSTS/TFS collection, e.g. http://myaccount.visualstudio.com for VSTS or http://myserver:8080/tfs/DefaultCollection for TFS.
2927
5. Build and run solution. After running you should see a list of all projects inside of myaccount.
3028

3129

OAuthWebSample/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
This sample shows how to prompt a user to authorize a cloud service that can call APIs on Visual Studio Team Services on behalf of the user.
44

5-
To learn more about OAuth in Visual Studio Team Services, see [Authorize access with OAuth 2.0](https://www.visualstudio.com/docs/integrate/get-started/auth/oauth)
5+
To learn more about OAuth in Visual Studio Team Services, see [Authorize access with OAuth 2.0](https://www.visualstudio.com/docs/integrate/get-started/authentication/oauth)
66

77
## How to setup
88

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
Samples that show how to auth with Visual Studio Team Services and Team Foundation Server.
66

7-
Learn more about [integrating with Team Services](https://www.visualstudio.com/docs/integrate/extensions/overview) and [specific authentication guidence](https://www.visualstudio.com/en-us/docs/integrate/get-started/auth/authentication_guidance)
7+
Learn more about [integrating with Team Services](https://www.visualstudio.com/docs/integrate/extensions/overview) and [specific authentication guidence](https://www.visualstudio.com/en-us/docs/integrate/get-started/authentication/authentication_guidance)
88

99
## Samples
1010

11-
* [Managed client sample (using Azure Active Directory Auth)](./ManagedClientConsoleAppSample/README.md)
11+
* [Managed client sample (using Azure Active Directory Library)](./ManagedClientConsoleAppSample/README.md)
1212
* [Device profile sample (.NET Core)](./DeviceProfileSample/README.md)
1313
* [ASP.NET Web app OAuth sample](./OAuthWebSample/README.md)
14-
* [Client library sample](./ClientLibraryConsoleAppSample/README.md)
14+
* [Client library sample (using VSSConnection)](./ClientLibraryConsoleAppSample/README.md)

0 commit comments

Comments
 (0)