Open
Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
Cannot find a way to make introspection queries available for anonymours users with global authorization.
I would expect to find an way to specify exclusion for introspection.
I saw similar issue 5056, but I didn't understand why it hadn't pull attention and had been marked as stale, therefore I decided to open this issue.
Steps to reproduce
1. Build code
HotChocolateAuthDemo.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HotChocolate.AspNetCore" Version="12.14.0" />
<PackageReference Include="HotChocolate.AspNetCore.Authorization" Version="12.14.0" />
</ItemGroup>
</Project>
Properties/launchSettings.json
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"HotChocolateAuthDemo": {
"commandName": "Project",
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5014",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Program.cs
using System.Security.Claims;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGraphQLServer().AddQueryType<Query>().AddAuthorization();
builder.Services.AddSingleton<NotesRepository>();
builder.Services.AddAuthentication(defaultScheme: "UserId")
.AddScheme<AuthenticationSchemeOptions, UserIdAuthHandler>(authenticationScheme: "UserId", _ => { });
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapGraphQLHttp("/graphql").RequireAuthorization();
endpoints.MapGraphQLSchema("/graphql/schema");
endpoints.MapBananaCakePop("/graphql/ui");
});
app.Run();
public class UserIdAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
public UserIdAuthHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
{ }
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
if (!Request.Headers.TryGetValue("UserId", out var userId))
{
return Task.FromResult(AuthenticateResult.NoResult());
}
var ticket = new AuthenticationTicket(
authenticationScheme: "UserId",
principal: new ClaimsPrincipal(
identity: new ClaimsIdentity(
authenticationType: "UserId",
claims: new []{ new Claim("UserId", userId) }
)));
return Task.FromResult(AuthenticateResult.Success(ticket));
}
}
[ObjectType]
public class Query
{
public NoteViewModel[] GetMyNotes(
[Service] NotesRepository repository,
ClaimsPrincipal user)
{
var userId = user.FindFirstValue("UserId");
var viewModels = repository.Value
.Where(note => note.OwnerId == userId)
.Select(note => note.ToViewModel())
.ToArray();
return viewModels;
}
}
[ObjectType("Note")]
public record NoteViewModel(string Id, string Title, string Body);
public class NotesRepository
{
public readonly NoteDto[] Value = new[]
{
new NoteDto(Id: "1", OwnerId: "1", Title: "user 1 note 1 title", Body: "user 1 note 1 body"),
new NoteDto(Id: "1", OwnerId: "2", Title: "user 2 note 1 title", Body: "user 2 note 1 body")
};
}
public record NoteDto(string Id, string OwnerId, string Title, string Body)
{
public NoteViewModel ToViewModel() => new NoteViewModel(Id, Title, Body);
}
2. Open http://localhost:5014/graphql/ui
You will see that introspection query to http://localhost:5014/graphql
is failed with http status code 401.
query introspection_phase_1 {
schema: __type(name: "__Schema") {
name
fields {
name
}
}
directive: __type(name: "__Directive") {
name
fields {
name
}
}
}
Relevant log output
No response
Additional Context?
No response
Product
Hot Chocolate
Version
12.14.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment