Skip to content

Commit

Permalink
Fixes #2855 (#2859)
Browse files Browse the repository at this point in the history
Tested with End to end test
  • Loading branch information
jmprieur authored May 27, 2024
1 parent 1a5fd81 commit a439bd1
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Identity.Abstractions;
Expand Down Expand Up @@ -58,6 +59,7 @@ public async Task AuthenticateRequestAsync(

scopes = authenticationOptions?.Scopes ?? _defaultAuthenticationOptions.Scopes;
graphServiceClientOptions = authenticationOptions ?? _defaultAuthenticationOptions;
ClaimsPrincipal? user = authenticationOptions?.User;

// Remove the authorization header if it exists
if (request.Headers.ContainsKey(AuthorizationHeaderKey))
Expand Down Expand Up @@ -86,13 +88,16 @@ public async Task AuthenticateRequestAsync(
if (authorizationHeaderProviderOptions!.RequestAppToken)
{
authorizationHeader = await _authorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync("https://graph.microsoft.com/.default",
authorizationHeaderProviderOptions);
authorizationHeaderProviderOptions,
cancellationToken);
}
else
{
authorizationHeader = await _authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(
scopes!,
authorizationHeaderProviderOptions);
authorizationHeaderProviderOptions,
claimsPrincipal: user,
cancellationToken);
}
request.Headers.Add(AuthorizationHeaderKey, authorizationHeader);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using Microsoft.Identity.Abstractions;
using System.Collections.Generic;
using System.Security.Claims;

namespace Microsoft.Identity.Web
{
Expand All @@ -28,5 +29,11 @@ public GraphServiceClientOptions()
/// should end in "./default")
/// </summary>
public IEnumerable<string> Scopes { get; set; }

/// <summary>
/// When calling Microsoft graph with delegated permissions offers a way to override the
/// user on whose behalf the call is made.
/// </summary>
public ClaimsPrincipal? User { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using Microsoft.Kiota.Abstractions;

namespace Microsoft.Identity.Web
Expand Down Expand Up @@ -106,6 +107,25 @@ public static IList<IRequestOption> WithAuthenticationScheme(this IList<IRequest
graphAuthenticationOptions.AcquireTokenOptions.AuthenticationOptionsName = authenticationScheme;
return options;
}
#endif
#endif

/// <summary>
/// Specifies to use app only permissions for Graph.
/// </summary>
/// <param name="options">Options to modify.</param>
/// <param name="user">Overrides the user on behalf of which Microsoft Graph is called
/// (for delegated permissions in some specific scenarios)</param>
/// <returns></returns>
public static IList<IRequestOption> WithUser(this IList<IRequestOption> options, ClaimsPrincipal user)
{
GraphAuthenticationOptions? graphAuthenticationOptions = options.OfType<GraphAuthenticationOptions>().FirstOrDefault();
if (graphAuthenticationOptions == null)
{
graphAuthenticationOptions = new GraphAuthenticationOptions();
options.Add(graphAuthenticationOptions);
}
graphAuthenticationOptions.User = user;
return options;
}
}
}
15 changes: 15 additions & 0 deletions src/Microsoft.Identity.Web.MicrosoftGraph/BaseRequestExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Security.Claims;
using Microsoft.Graph;
using Microsoft.Identity.Abstractions;

Expand Down Expand Up @@ -95,5 +96,19 @@ private static T SetParameter<T>(T baseRequest, Action<TokenAcquisitionAuthentic

return baseRequest;
}

/// <summary>
/// Overrides authentication options for a given request.
/// </summary>
/// <typeparam name="T">Request</typeparam>
/// <param name="baseRequest">Request.</param>
/// <param name="user">Delegate to override
/// the authentication options</param>
/// <returns>Base request</returns>
public static T WithUser<T>(this T baseRequest,
ClaimsPrincipal user) where T : IBaseRequest
{
return SetParameter(baseRequest, options => options.User = user );
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.Graph;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Client;

namespace Microsoft.Identity.Web
{
Expand Down Expand Up @@ -37,13 +36,15 @@ public async Task AuthenticateRequestAsync(HttpRequestMessage request)
bool appOnly = _initialOptions.AppOnly ?? false;
string? tenant = _initialOptions.Tenant ?? null;
string? scheme = _initialOptions.AuthenticationScheme ?? null;
ClaimsPrincipal? user = null;
// Extract per-request options from the request if present
TokenAcquisitionAuthenticationProviderOption? msalAuthProviderOption = GetMsalAuthProviderOption(request);
if (msalAuthProviderOption != null) {
scopes = msalAuthProviderOption.Scopes ?? scopes;
appOnly = msalAuthProviderOption.AppOnly ?? appOnly;
tenant = msalAuthProviderOption.Tenant ?? tenant;
scheme = msalAuthProviderOption.AuthenticationScheme ?? scheme;
user = msalAuthProviderOption.User ?? user;
}

if (!appOnly && scopes == null)
Expand Down Expand Up @@ -71,7 +72,8 @@ public async Task AuthenticateRequestAsync(HttpRequestMessage request)
{
authorizationHeader = await _authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(
scopes!,
downstreamOptions).ConfigureAwait(false);
downstreamOptions,
claimsPrincipal: user).ConfigureAwait(false);
}

// add or replace authorization header
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Security.Claims;
using Microsoft.Graph;
using Microsoft.Identity.Abstractions;

Expand All @@ -14,5 +15,6 @@ internal class TokenAcquisitionAuthenticationProviderOption : IAuthenticationPro
public string? Tenant { get; set; }
public string? AuthenticationScheme { get; set; }
public Action<AuthorizationHeaderProviderOptions>? AuthorizationHeaderProviderOptions { get; set; }
public ClaimsPrincipal? User { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ public IndexModel(ILogger<IndexModel> logger, GraphServiceClient graphServiceCli

public async Task OnGet()
{
var user = await _graphServiceClient.Me.GetAsync(r => r.Options.WithScopes("user.read"));
var user = await _graphServiceClient.Me.GetAsync(r =>
r.Options.WithScopes("user.read")
//.WithUser(User)
);

try
{
Expand Down

0 comments on commit a439bd1

Please sign in to comment.