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.