Reputation: 2672
I need to make use of two steps in multiple places on my .NET Core website. I've decided to implement an interface and supporting class in my Startup.cs
so I can use DI to inject the object into my PageModel
on various Razor pages in my project.
services.AddSingleton<IAuthenticatedGraphClient, AuthenticatedGraphClient>();
public interface IAuthenticatedGraphClient
{
Task<GraphServiceClient> GetAuthenticatedGraphClientAsync(HttpContext httpContext);
}
public class AuthenticatedGraphClient : IAuthenticatedGraphClient
{
private ITokenAcquisition tokenAcquisition;
public AuthenticatedGraphClient(ITokenAcquisition tokenAcquisition)
{
this.tokenAcquisition = tokenAcquisition;
}
public async Task<GraphServiceClient> GetAuthenticatedGraphClientAsync(HttpContext httpContext)
{
var accessToken = await TokenAcquisition.GetAccessTokenOnBehalfOfUser(httpContext, new[] { ScopeConstants.ScopeUserRead });
return new GraphServiceClient(new DelegateAuthenticationProvider((requestMessage) => {
requestMessage
.Headers
.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
return Task.FromResult(0);
}));
}
}
public class TestPageModel : PageModel
{
private IAuthenticatedGraphClient graphClient;
public TestPage(IAuthenticatedGraphClient graphClient)
{
this.graphClient = graphClient;
}
public async Task OnPostAsync()
{
var graphServiceClient = await graphClient.GetAuthenticatedGraphClientAsync(HttpContext);
//truncated for brevity...
}
}
I thought I had to provide the HttpContext
from the PageModel
class into the called method but I'm not entirely sure as this gives me an error:
An object reference is required for the non-static field, method, or property 'TokenAcquisition.GetAccessTokenOnBehalfOfUser(HttpContext, IEnumerable, string)'
I've also tried:
var accessToken = await TokenAcquisition.GetAccessTokenOnBehalfOfUser(HttpContext, new[] { ScopeConstants.ScopeUserRead });
...however this gives me the error:
'HttpContext' is a type, which is not valid in the given context
If I put the GetAuthenticatedGraphClientAsync
as a method in the same PageModel
class it works without issue and HttpContext
is understood.
Any ideas? Is there a better pattern?
Upvotes: 0
Views: 1094
Reputation: 814
Your first error about an object reference being required, would seem to be because your AuthenticatedGraphClient
constructor takes an ITokenAcquisition
parameter, which you don't seem to be passing in your Startup.cs
As for your second error about HttpContext
being a type, that is true, I'm pretty sure you should be passing HttpContext.Current
into GetAccessTokenOnBehalfOfUser
.
EDIT: Also, you're not even using the passed in ITokenAcquisition
.
var accessToken = await TokenAcquisition.GetAccessTokenOnBehalfOfUser(httpContext, new[] { ScopeConstants.ScopeUserRead });
should be:
var accessToken = await tokenAcquisition.GetAccessTokenOnBehalfOfUser(httpContext, new[] { ScopeConstants.ScopeUserRead });
Upvotes: 1