-
-
Notifications
You must be signed in to change notification settings - Fork 788
Open
Labels
Area: AuthorizationIssue is related to authorizationIssue is related to authorization🌶️ hot chocolate📚 documentationThis issue is about working on our documentation.This issue is about working on our documentation.
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
mac2000, llasapg, romanyevd, vadymkutsenko, yev-anna and 4 more
Metadata
Metadata
Assignees
Labels
Area: AuthorizationIssue is related to authorizationIssue is related to authorization🌶️ hot chocolate📚 documentationThis issue is about working on our documentation.This issue is about working on our documentation.