Passing HttpContext in a ActionBlock

79 Views Asked by At

I am doing AzureAD implict flow for authenticating on a ASP.NET Core (2.2) api. For a specific reference to a library the application is in .net 4.8 but the api is hosted inside asp.net core.

The API makes a service to service call using the TPL dataflow blocks. The access token received when the UI(react) makes the request has got the roles and scopes and is stored inside HttpContext for downstream api calls (OnBehalfOf flow).

The HttpContextAccessor.HttpContext is null inside the pipeline. Outside of the pipeline I have access to the HttpContext. It looks to be really ugly to pass the context into every method call as a parameter.

Is there any other way to do this? I know I can use Client Credential flow, where I could configure the AD and use daemon app and get a token. But if I am stuck doing an OnBehalfOf flow, what could be the solution.

public class AuthenticationHandler : AuthenticationHandler<JwtBearerOptions>
{
    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        if (!Request.Headers.ContainsKey(HeaderNames.Authorization))
        {
            return Task.FromResult(AuthenticateResult.Fail("Header Not Found."));
        }

        var requestHeader = Request.Headers["Authorization"];
        var token = requestHeader.FirstOrDefault()?.Split(' ').Last();

        Request.HttpContext.Items.Add("tokenfordownstream", token); // retrieve from context for api to api calls

        return Task.FromResult(AuthenticateResult.Success(ticket));
    }
}

Microsoft.Identity.Web could not be installed because of a number of package downgrade. I think it is conflicting with binaries in Microsoft.Identity.Client

using Microsoft.Identity.Client;
public class RiskPipelineFactory : IRiskPipelineFactory
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    
    public RiskPipelineFactory(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor; //httpContext is NOT null
    }   
    
    public IRiskPipeline Create()
    {
        var preLoaderAction = new ActionBlock<(pricingExercise, risks)>(LoadStep, loadOptions);
        return new RiskSlicePipeline(preLoaderAction);
        
        //I don't want to pass the httpContext here, because there are also other blocks that
        //gets stitched togther and many method calls, so it will be quite messy
        private async Task LoadStep((PricingExercise pricingExercise, Risks risks) input)
        {
            //HttpContext is null here, if _httpContextAccessor is not passed as a param        
            //do the other api call here for the sake of simplicity, but retrieving the access token will fail
        }
    }
}
0

There are 0 best solutions below