Home > Software engineering >  Adding a fake user when developing
Adding a fake user when developing

Time:07-30

I am trying to add a fake user when running the application in development mode. Insted of adding a fake JWT header is there a way to add some fake user details?

This is what I have done so far:

  1. I created a fake filter:
internal class FakeUserFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        context.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
        {
            new(ClaimTypes.NameIdentifier, "123"),
            new(ClaimTypes.Name, "Test user"),
            new(ClaimTypes.Email, "[email protected]"),
            new(ClaimTypes.Role, "Admin")
        }));

        await next();
    }
}
  1. Added it to Controllers
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
//...
builder.Services.AddControllers(options =>
{
    if (!builder.Configuration.GetValue<bool>("UseAuthorization"))
    {
        options.Filters.Add(new AllowAnonymousFilter());
        options.Filters.Add(new FakeUserFilter());
    }
    
});
//...
  1. And later in the I enabled Authentication and Authorization
//...
app.UseAuthentication();
app.UseAuthorization();
//...

I still get an unauthorised error. As of now, I am just adding a global anonymous attribute by doing

if (app.Environment.IsDevelopment())
{
    app.MapControllers().WithMetadata(new AllowAnonymousAttribute());
}
else
{
    app.MapControllers();
}

This obviously doesn't give me a fake user. Is there a way to set the fake user in development mode? Any help is appreciated.

CodePudding user response:

ActionFilter is not the right tool for this job. What you should do is to fake authentication handler. Just write some kind of TestAuthenticationHandler implementing AuthenticationHandler class.

Example:

    public class TestAuthHandlerOptions : AuthenticationSchemeOptions
    {

    }

    public class TestAuthHandler : AuthenticationHandler<TestAuthHandlerOptions>
    {
        public const string AuthenticationScheme = "Test";
        public TestAuthHandler(IOptionsMonitor<TestAuthHandlerOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
        {
        }

        protected override Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            var claims = new List<Claim>
            {
                new(ClaimTypes.NameIdentifier, "123"),
                new(ClaimTypes.Name, "Test user"),
                new(ClaimTypes.Email, "[email protected]"),
                new(ClaimTypes.Role, "Admin")
            };

            var identity = new ClaimsIdentity(claims, AuthenticationScheme);
            var principal = new ClaimsPrincipal(identity);
            var ticket = new AuthenticationTicket(principal, AuthenticationScheme);

            var result = AuthenticateResult.Success(ticket);

            return Task.FromResult(result);
        }
    }

And register it:

builder.Services.AddAuthentication(TestAuthHandler.AuthenticationScheme)
                .AddScheme<TestAuthHandlerOptions, TestAuthHandler>(TestAuthHandler.AuthenticationScheme, options => { });

And that's it. In such a way, you're going to have access to your fake user at HttpContext.

  • Related