Skip to content
This repository has been archived by the owner on Nov 16, 2023. It is now read-only.

Dev/agera/msal #67

Merged
merged 10 commits into from Jan 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion occupancy-quickstart/README.md
Expand Up @@ -10,11 +10,12 @@ Below are some details on how to get up and running. For a more detailed walkth

### Update appSettings.json

`appSettings.json` is used to specify info on which Digital Twins instance to connect to. The three fields you will need to fill in are:
[appSettings.json](./src/appSettings.json) is used to specify info on which Digital Twins instance to connect to. The three fields you will need to fill in are:

- `ClientId`: The **application ID** of a native Azure Active Directory app that has permissions to call the Azure Digital Twins service.
- `Tenant`: The **directory ID** of a your Azure Active Directory.
- `BaseUrl`: The management api url to your Digital Twins instance (see `appSetting.json` for what this should look like).
- `AadRedirectUri`: A valid **Redirect URI** configured for your Azure Active Directory app. We recommend using the default **Redirect URI** `http://www.localhost:8080`. However, you may also choose another port or domain as required.

### Use a shell

Expand Down
3 changes: 3 additions & 0 deletions occupancy-quickstart/src/appSettings.cs
Expand Up @@ -11,14 +11,17 @@ public class AppSettings {
// Note: this is a constant because it is the same for every user authorizing
// against the Digital Twins Apis
private static string DigitalTwinsAppId = "0b07f429-9f4b-4714-9392-cc5e8e80c8b0";
private static string[] AadScopes = new string[] { DigitalTwinsAppId + "/Read.Write" };

public string AADInstance { get; set; }
public string AadRedirectUri { get; set; }
public string ClientId { get; set; }
public string ClientSecret { get; set; }
public string Resource { get; set; } = DigitalTwinsAppId;
public string Tenant { get; set; }
public string BaseUrl { get; set; }
public string Authority => AADInstance + Tenant;
public string[] Scopes { get; set; } = AadScopes;

public static AppSettings Load()
{
Expand Down
9 changes: 5 additions & 4 deletions occupancy-quickstart/src/appSettings.json
@@ -1,6 +1,7 @@
{
"AADInstance": "https://login.microsoftonline.com/",
"ClientId": "<Azure Active Directory App Id>",
"Tenant": "<Directory Id of your AAD tenant>",
"BaseUrl": "https://<your resource name>.<your resource's location>.azuresmartspaces.net/management/api/v1.0/"
"AADInstance": "https://login.microsoftonline.com/",
"AadRedirectUri": "http://localhost:8080/",
"ClientId": "<Azure Active Directory App Id>",
"Tenant": "<Directory Id of your AAD tenant>",
"BaseUrl": "https://<your resource name>.<your resource's location>.azuresmartspaces.net/management/api/v1.0/"
}
37 changes: 20 additions & 17 deletions occupancy-quickstart/src/auth.cs
Expand Up @@ -4,7 +4,7 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.Identity.Client;
using System.Net.Http;

namespace Microsoft.Azure.DigitalTwins.Samples
Expand All @@ -14,13 +14,13 @@ internal static class Authentication
// Gets an access token
// First tries (by making a request) using a cached token and if that
// fails we generated a new one using device login and cache it.
internal static async Task<string> GetToken(ILogger logger, AppSettings appSettings)
internal static async Task<string> GetToken(AppSettings appSettings)
{
var accessTokenFilename = ".accesstoken";
var accessToken = ReadAccessTokenFromFile(accessTokenFilename);
if (accessToken == null || !(await TryRequestWithAccessToken(new Uri(appSettings.BaseUrl), accessToken)))
{
accessToken = await Authentication.GetNewToken(logger, appSettings);
accessToken = await Authentication.GetNewToken(appSettings);
System.IO.File.WriteAllText(accessTokenFilename, accessToken);
}

Expand All @@ -44,21 +44,24 @@ private static async Task<bool> TryRequestWithAccessToken(Uri baseAddress, strin
private static string ReadAccessTokenFromFile(string filename)
=> System.IO.File.Exists(filename) ? System.IO.File.ReadAllText(filename) : null;

private static async Task<string> GetNewToken(
ILogger logger,
AppSettings appSettings)
// MSAL.NET configuration. Review the product documentation for more information about MSAL.NET authentication options.
// https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/
private static async Task<string> GetNewToken(AppSettings appSettings)
{
var authContext = new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(appSettings.Authority);
return (await GetResultsUsingDeviceCode(authContext, appSettings)).AccessToken;
}
IPublicClientApplication app = PublicClientApplicationBuilder
.Create(appSettings.ClientId)
.WithRedirectUri(appSettings.AadRedirectUri)
.WithAuthority(appSettings.Authority)
.Build();

// This prompts the user to open a browser and input a unique key to authenticate their app
// This allows dotnet core apps to authorize an application through user credentials without displaying UI.
private static async Task<AuthenticationResult> GetResultsUsingDeviceCode(AuthenticationContext authContext, AppSettings appSettings)
{
var codeResult = await authContext.AcquireDeviceCodeAsync(appSettings.Resource, appSettings.ClientId);
Console.WriteLine(codeResult.Message);
return await authContext.AcquireTokenByDeviceCodeAsync(codeResult);
AuthenticationResult result = await app
.AcquireTokenInteractive(appSettings.Scopes)
.ExecuteAsync();

Console.WriteLine("");
Console.WriteLine("MSAL Authentication Token Acquired: {0}", result.AccessToken);
Console.WriteLine("");
return result.AccessToken;
}
}
}
}
4 changes: 2 additions & 2 deletions occupancy-quickstart/src/occupancyQuickstart.csproj
Expand Up @@ -11,11 +11,11 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.1" />
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="3.19.3" allowedVersions="[3,4)" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.7.1.0" Culture="neutral" PublicKeyToken="0a613f4dd989e8ae" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="2.1.1" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="YamlDotNet" Version="5.0.1" />
<Content Include="appSettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
Expand Down
8 changes: 4 additions & 4 deletions occupancy-quickstart/src/program.cs
Expand Up @@ -14,7 +14,7 @@
using Newtonsoft.Json;
using YamlDotNet.Serialization;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.Identity.Client;

namespace Microsoft.Azure.DigitalTwins.Samples
{
Expand Down Expand Up @@ -85,10 +85,10 @@ private static async Task<HttpClient> SetupHttpClient(ILogger logger, AppSetting
{
BaseAddress = new Uri(appSettings.BaseUrl),
};
var accessToken = (await Authentication.GetToken(logger, appSettings));


var accessToken = await Authentication.GetToken(appSettings);
httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
return httpClient;
}
}
}
}
4 changes: 2 additions & 2 deletions occupancy-quickstart/tests/occupancyQuickstart.tests.csproj
Expand Up @@ -9,7 +9,7 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="Moq" Version="4.9.0" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<Content Include="userDefinedFunctions/function1.js">
Expand All @@ -24,4 +24,4 @@
<ProjectReference Include="..\src\occupancyQuickstart.csproj" />
</ItemGroup>

</Project>
</Project>