Skip to content

Renaming2 #269

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 20, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApp-OpenIDConnect-DotNet
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Identity.Web", "..\..\Microsoft.Identity.Web\Microsoft.Identity.Web.csproj", "{E0CEF26A-6CE6-4505-851B-6580D5564752}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Identity.Web.Test", "..\..\Microsoft.Identity.Web.Test\Microsoft.Identity.Web.Test.csproj", "{0EEC3E2E-69D0-4A7F-98D6-4386330F4965}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -21,6 +23,10 @@ Global
{E0CEF26A-6CE6-4505-851B-6580D5564752}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E0CEF26A-6CE6-4505-851B-6580D5564752}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E0CEF26A-6CE6-4505-851B-6580D5564752}.Release|Any CPU.Build.0 = Release|Any CPU
{0EEC3E2E-69D0-4A7F-98D6-4386330F4965}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0EEC3E2E-69D0-4A7F-98D6-4386330F4965}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0EEC3E2E-69D0-4A7F-98D6-4386330F4965}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0EEC3E2E-69D0-4A7F-98D6-4386330F4965}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public async Task<IActionResult> Profile()
{
return GraphServiceClientFactory.GetAuthenticatedGraphClient(async () =>
{
string result = await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(scopes);
string result = await tokenAcquisition.GetAccessTokenForUserAsync(scopes);
return result;
}, webOptions.GraphApiUrl);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public IActionResult Index()
public async Task<IActionResult> Profile()
{
var accessToken =
await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(new[] {Constants.ScopeUserRead});
await tokenAcquisition.GetAccessTokenForUserAsync(new[] {Constants.ScopeUserRead});

var me = await graphApiOperations.GetUserInformation(accessToken);
var photo = await graphApiOperations.GetPhotoAsBase64Async(accessToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public async Task<IActionResult> Edit(int id)
var userTenant = User.GetTenantId();

// Acquiring token for graph in the signed-in users tenant, so it can be used to retrieve all the users from their tenant
var graphAccessToken = await _tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(new string[] { GraphScope.UserReadAll }, userTenant);
var graphAccessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new string[] { GraphScope.UserReadAll }, userTenant);

TempData["UsersDropDown"] = (await _msGraphService.GetUsersAsync(graphAccessToken))
.Select(u => new SelectListItem
Expand Down
4 changes: 2 additions & 2 deletions 2-WebApp-graph-user/2-3-Multi-Tenant/README-National-Cloud.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,10 @@ If a multi-tenant app needs to acquire an access token for Microsoft Graph to be
```csharp
var userTenant = User.GetTenantId();
// Acquiring token for graph using the user's tenant, so it can return all the users from their tenant
var graphAccessToken = await _tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(new string[] { GraphScope.UserReadAll }, userTenant);
var graphAccessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new string[] { GraphScope.UserReadAll }, userTenant);
```

We are acquiring an access token for Graph with the scope `User.Read.All`, to list all the users from the tenant so you can assign a todo item to them. `GetAccessTokenOnBehalfOfUserAsync` is a helper method found on `Microsoft.Identity.Web` project, and it receives a **tenantId** as parameter to acquire a token for the desired authority. For that, we get the current authority from the built `IConfidentialClientApplication` and replace the tenantId. Below is an example of this logic.
We are acquiring an access token for Graph with the scope `User.Read.All`, to list all the users from the tenant so you can assign a todo item to them. `GetAccessTokenForUserAsync` is a helper method found on `Microsoft.Identity.Web` project, and it receives a **tenantId** as parameter to acquire a token for the desired authority. For that, we get the current authority from the built `IConfidentialClientApplication` and replace the tenantId. Below is an example of this logic.

```csharp
string signedUserAuthority = confidentialClientApplication.Authority.Replace(new Uri(confidentialClientApplication.Authority).PathAndQuery, $"/{tenant}/");
Expand Down
4 changes: 2 additions & 2 deletions 2-WebApp-graph-user/2-3-Multi-Tenant/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,10 @@ If a multi-tenant app needs to acquire an access token for Microsoft Graph to be
```csharp
var userTenant = User.GetTenantId();
// Acquiring token for graph using the user's tenant, so it can return all the users from their tenant
var graphAccessToken = await _tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(new string[] { GraphScope.UserReadAll }, userTenant);
var graphAccessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new string[] { GraphScope.UserReadAll }, userTenant);
```

We are acquiring an access token for Graph with the scope `User.Read.All`, to list all the users from the tenant so you can assign a todo item to them. `GetAccessTokenOnBehalfOfUserAsync` is a helper method found on `Microsoft.Identity.Web` project, and it receives a **tenantId** as parameter to acquire a token for the desired authority. For that, we get the current authority from the built `IConfidentialClientApplication` and replace the tenantId. Below is an example of this logic.
We are acquiring an access token for Graph with the scope `User.Read.All`, to list all the users from the tenant so you can assign a todo item to them. `GetAccessTokenForUserAsync` is a helper method found on `Microsoft.Identity.Web` project, and it receives a **tenantId** as parameter to acquire a token for the desired authority. For that, we get the current authority from the built `IConfidentialClientApplication` and replace the tenantId. Below is an example of this logic.

```csharp
string signedUserAuthority = confidentialClientApplication.Authority.Replace(new Uri(confidentialClientApplication.Authority).PathAndQuery, $"/{tenant}/");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public IActionResult Index()
public async Task<IActionResult> Profile()
{
var accessToken =
await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(new[] {Constants.ScopeUserRead});
await tokenAcquisition.GetAccessTokenForUserAsync(new[] {Constants.ScopeUserRead});

var me = await graphApiOperations.GetUserInformation(accessToken);
var photo = await graphApiOperations.GetPhotoAsBase64Async(accessToken);
Expand Down
8 changes: 4 additions & 4 deletions 3-WebApp-multi-APIs/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public IActionResult Index()
public async Task<IActionResult> Profile()
{
var accessToken =
await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(new[] {Constants.ScopeUserRead});
await tokenAcquisition.GetAccessTokenForUserAsync(new[] {Constants.ScopeUserRead});

var me = await graphApiOperations.GetUserInformation(accessToken);
var photo = await graphApiOperations.GetPhotoAsBase64Async(accessToken);
Expand All @@ -56,12 +56,12 @@ public async Task<IActionResult> Profile()
public async Task<IActionResult> Tenants()
{
var accessToken =
await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(new[] { $"{ArmApiOperationService.ArmResource}user_impersonation" });
await tokenAcquisition.GetAccessTokenForUserAsync(new[] { $"{ArmApiOperationService.ArmResource}user_impersonation" });

var tenantIds = await armOperations.EnumerateTenantsIdsAccessibleByUser(accessToken);
/*
var tenantsIdsAndNames = await graphApiOperations.EnumerateTenantsIdAndNameAccessibleByUser(tenantIds,
async tenantId => { return await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(new string[] { "Directory.Read.All" }, tenantId); });
async tenantId => { return await tokenAcquisition.GetAccessTokenForUserAsync(new string[] { "Directory.Read.All" }, tenantId); });
*/
ViewData["tenants"] = tenantIds;

Expand All @@ -77,7 +77,7 @@ public async Task<IActionResult> Blob()
var scopes = new string[] { "https://storage.azure.com/user_impersonation" };

var accessToken =
await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(scopes);
await tokenAcquisition.GetAccessTokenForUserAsync(scopes);

// create a blob on behalf of the user
TokenCredential tokenCredential = new TokenCredential(accessToken);
Expand Down
2 changes: 1 addition & 1 deletion 4-WebApp-your-API/Client/Services/TodoListService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public async Task<IEnumerable<Todo>> GetAsync()

private async Task PrepareAuthenticatedClient()
{
var accessToken = await this._tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(new[] { this._TodoListScope });
var accessToken = await this._tokenAcquisition.GetAccessTokenForUserAsync(new[] { this._TodoListScope });
Debug.WriteLine($"access token-{accessToken}");
this._httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
this._httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Expand Down
2 changes: 1 addition & 1 deletion 5-WebApp-AuthZ/5-1-Roles/Controllers/AccountController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public async Task<IActionResult> Groups()

GraphServiceClient graphServiceClient = GraphServiceClientFactory.GetAuthenticatedGraphClient(async () =>
{
string result = await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(scopes);
string result = await tokenAcquisition.GetAccessTokenForUserAsync(scopes);
return result;
}, webOptions.GraphApiUrl);

Expand Down
2 changes: 1 addition & 1 deletion 5-WebApp-AuthZ/5-1-Roles/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public async Task<IActionResult> Profile()
{
return GraphServiceClientFactory.GetAuthenticatedGraphClient(async () =>
{
string result = await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(scopes);
string result = await tokenAcquisition.GetAccessTokenForUserAsync(scopes);
return result;
}, webOptions.GraphApiUrl);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public async Task<IActionResult> Index()
// Using group ids/names in the IsInRole method
// var isinrole = User.IsInRole("8873daa2-17af-4e72-973e-930c94ef7549");

string accessToken = await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(new[] { Constants.ScopeUserRead, Constants.ScopeDirectoryReadAll });
string accessToken = await tokenAcquisition.GetAccessTokenForUserAsync(new[] { Constants.ScopeUserRead, Constants.ScopeDirectoryReadAll });

User me = await graphService.GetMeAsync(accessToken);
ViewData["Me"] = me;
Expand Down
2 changes: 1 addition & 1 deletion Microsoft.Identity.Web/ClaimsPrincipalFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static class ClaimsPrincipalFactory
/// subscriptionStore.GetSubscriptionInfo(notification.SubscriptionId);
/// HttpContext.User = ClaimsPrincipalExtension.FromTenantIdAndObjectId(subscription.TenantId,
/// subscription.UserId);
/// string accessToken = await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(scopes);
/// string accessToken = await tokenAcquisition.GetAccessTokenForUserAsync(scopes);
/// </code>
/// </example>
public static ClaimsPrincipal FromTenantIdAndObjectId(string tenantId, string objectId)
Expand Down
14 changes: 14 additions & 0 deletions Microsoft.Identity.Web/ITokenAcquisition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Http;
using Microsoft.Identity.Client;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

Expand Down Expand Up @@ -54,8 +55,21 @@ public interface ITokenAcquisition
/// <param name="tenantId">Enables to override the tenant/account for the same identity. This is useful in the
/// cases where a given account is a guest in other tenants, and you want to acquire tokens for a specific tenant</param>
/// <returns>An access token to call on behalf of the user, the downstream API characterized by its scopes</returns>
[Obsolete("Renamed to GetAccessTokenForUserAsync")]
Task<string> GetAccessTokenOnBehalfOfUserAsync(IEnumerable<string> scopes, string tenantId = null);

/// <summary>
/// Typically used from an ASP.NET Core Web App or Web API controller, this method gets an access token
/// for a downstream API on behalf of the user account which claims are provided in the <see cref="HttpContext.User"/>
/// member of the <paramref name="context"/> parameter
/// </summary>
/// <param name="context">HttpContext associated with the Controller or auth operation</param>
/// <param name="scopes">Scopes to request for the downstream API to call</param>
/// <param name="tenantId">Enables to override the tenant/account for the same identity. This is useful in the
/// cases where a given account is guest in other tenants, and you want to acquire tokens for a specific tenant</param>
/// <returns>An access token to call on behalf of the user, the downstream API characterized by its scopes</returns>
Task<string> GetAccessTokenForUserAsync(IEnumerable<string> scopes, string tenantId = null);

/// <summary>
/// Removes the account associated with context.HttpContext.User from the MSAL.NET cache
/// </summary>
Expand Down
6 changes: 3 additions & 3 deletions Microsoft.Identity.Web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public class HomeController : Controller
...
```

Then in your controller actions, you'll need to call: `ITokenAcquisition.GetAccessTokenOnBehalfOfUserAsync` passing the scopes for which to request a token. The other methods of ITokenAcquisition are used from the `AddWebAppCallsProtectedWebApi()` method and similar methods for web APIs (see below).
Then in your controller actions, you'll need to call: `ITokenAcquisition.GetAccessTokenForUserAsync` passing the scopes for which to request a token. The other methods of ITokenAcquisition are used from the `AddWebAppCallsProtectedWebApi()` method and similar methods for web APIs (see below).

```CSharp
[Authorize]
Expand All @@ -130,7 +130,7 @@ public class HomeController : Controller
public async Task<IActionResult> Action()
{
string[] scopes = new []{"user.read"};
string token = await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(scopes);
string token = await tokenAcquisition.GetAccessTokenForUserAsync(scopes);
...
// call the downstream API with the bearer token in the Authorize header
}
Expand Down Expand Up @@ -235,7 +235,7 @@ For your web API to call downstream APIs, you'll need to:

<img alt="ScopesRequiredHttpContextExtensions" src="https://user-images.githubusercontent.com/13203188/64253176-f9e3ca80-cf1c-11e9-8fe9-df06cee11c25.png" width="80%"/>

- in your controller actions, to call: `ITokenAcquisition.GetAccessTokenOnBehalfOfUserAsync` passing the scopes for which to request a token.
- in your controller actions, to call: `ITokenAcquisition.GetAccessTokenForUserAsync` passing the scopes for which to request a token.

The following code snippet shows how to combine these steps:

Expand Down
28 changes: 27 additions & 1 deletion Microsoft.Identity.Web/TokenAcquisition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,34 @@ public async Task AddAccountToCacheFromAuthorizationCodeAsync(AuthorizationCodeR
/// passing the validated token (as a JwtSecurityToken). Calling it from a Web App supposes that
/// you have previously called AddAccountToCacheFromAuthorizationCodeAsync from a method called by
/// OpenIdConnectOptions.Events.OnAuthorizationCodeReceived</remarks>
[Obsolete("Renamed to GetAccessTokenForUserAsync. Please use that method")]
public async Task<string> GetAccessTokenOnBehalfOfUserAsync(
IEnumerable<string> scopes,
string tenant = null)
{
return await GetAccessTokenForUserAsync(scopes, tenant);
}

/// <summary>
/// Typically used from a Web App or WebAPI controller, this method retrieves an access token
/// for a downstream API using;
/// 1) the token cache (for Web Apps and Web APis) if a token exists in the cache
/// 2) or the <a href='https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow'>on-behalf-of flow</a>
/// in Web APIs, for the user account that is ascertained from claims are provided in the <see cref="HttpContext.User"/>
/// instance of the current HttpContext
/// </summary>
/// <param name="scopes">Scopes to request for the downstream API to call</param>
/// <param name="tenant">Enables overriding of the tenant/account for the same identity. This is useful in the
/// cases where a given account is guest in other tenants, and you want to acquire tokens for a specific tenant, like where the user is a guest in</param>
/// <returns>An access token to call the downstream API and populated with this downstream Api's scopes</returns>
/// <remarks>Calling this method from a Web API supposes that you have previously called,
/// in a method called by JwtBearerOptions.Events.OnTokenValidated, the HttpContextExtensions.StoreTokenUsedToCallWebAPI method
/// passing the validated token (as a JwtSecurityToken). Calling it from a Web App supposes that
/// you have previously called AddAccountToCacheFromAuthorizationCodeAsync from a method called by
/// OpenIdConnectOptions.Events.OnAuthorizationCodeReceived</remarks>
public async Task<string> GetAccessTokenForUserAsync(
IEnumerable<string> scopes,
string tenant = null)
{
if (scopes == null)
{
Expand All @@ -179,8 +204,9 @@ public async Task<string> GetAccessTokenOnBehalfOfUserAsync(

catch (MsalUiRequiredException ex)
{
// GetAccessTokenForUserAsync is an abstraction that can be called from a Web App or a Web API
Debug.WriteLine(ex.Message);
// GetAccessTokenOnBehalfOfUserAsync is an abstraction that can be called from a Web App or a Web API

// to get a token for a Web API on behalf of the user, but not necessarily with the on behalf of OAuth2.0
// flow as this one only applies to Web APIs.
JwtSecurityToken validatedToken = CurrentHttpContext.GetTokenUsedToCallWebAPI();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ public async Task ClearAsync()
{
// This is a user token cache
await RemoveKeyAsync(GetCacheKey(false)).ConfigureAwait(false);

// TODO: Clear the cookie session if any. Get inspiration from
// https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/issues/240
}

/// <summary>
Expand Down
Loading