ASP.NET Core and GraphQl problem with JWT Authentication

ASP.NET Core and GraphQl problem with JWT Authentication


0

I am building an ASP.NET Core Web API with GraphQl, but I am facing issues with JWT token authentication. When the user is logged in I am returning the token, but when I want to create a query or mutation with token provided I see message

The current user is not authorized to access this resource

Here is my Program.cs:

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));

builder.Services.AddIdentity<ApplicationUser, IdentityRole>(IdentityHelper.GetIdentityOptions)
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

// Services

builder.Services.AddTransient<IAuthenticationService, AuthenticationService>();
builder.Services.AddTransient<IUserService, UserService>();

builder.Services.AddGraphQLServer()
    .AddAuthorization()
    .AddQueryType<BaseQuery>()
        .AddTypeExtension<UserQuery>()
    .AddMutationType<BaseMutation>()
        .AddTypeExtension<UserMutation>()
    .AddFiltering()
    .AddMutationConventions()
    .AddSorting()
    .AddInMemorySubscriptions();

builder.Services.AddCors();

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options => {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = builder.Configuration[GlobalConstants.JwtIssuer],
            ValidAudience = builder.Configuration[GlobalConstants.JwtAudience],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration[GlobalConstants.JwtKey]))
        };
    });

builder.Services.AddAuthorization();

builder.Services.AddEndpointsApiExplorer();

var app = builder.Build();

AutoMapperConfig.RegisterMappings(typeof(ErrorViewModel).GetTypeInfo().Assembly);

// Configure the HTTP request pipeline.

app.UseRouting();

app.UseCors(config =>
{
    config.AllowAnyOrigin();
    config.AllowAnyMethod();
    config.AllowAnyHeader();
});

app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.MapGraphQL();

app.Run();

And here is UserQuery.cs:

[ExtendObjectType(typeof(BaseQuery))]
public class UserQuery
{
    [GraphQLName("user")]
    [Authorize]
    [UsePaging(IncludeTotalCount = true, MaxPageSize = 100), UseFiltering, UseSorting]        
    public IQueryable<UserModel> GetUserById([Service] IUserService userService, string userId)
    {
        var user = userService.GetUserById<UserModel>(userId);

        return user;
    }

    [GraphQLName("users")]
    [UsePaging(IncludeTotalCount = true, MaxPageSize = 100), UseFiltering, UseSorting]
    [Authorize]
    public IQueryable<UserModel> GetUsers([Service] IUserService userService)
    {
        var user = userService.GetUsers<UserModel>();

        return user;
    }
}

Here is Token Generator

    private string GenerateToken(string email)
    {
        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration[GlobalConstants.JwtKey]));
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

        var claims = new[]
        {
            new Claim(ClaimTypes.NameIdentifier,email),
            new Claim(ClaimTypes.Role,GlobalConstants.UserRoleName)
        };

        var token = new JwtSecurityToken(_configuration[GlobalConstants.JwtIssuer],
            _configuration[GlobalConstants.JwtAudience],
            claims,
            expires: DateTime.Now.AddYears(1),
            signingCredentials: credentials);

        return new JwtSecurityTokenHandler().WriteToken(token);
    }

I tried swapping the places of the middleware but there is no result.


Load 7 more related questions


Show fewer related questions

0



Leave a Reply

Your email address will not be published. Required fields are marked *