Open drewbj21 opened 2 years ago
I had the same issue. I've created a policy of two authorization schemes and use it in global authorization:
app.MapGraphQL().RequireAuthorization("CustomPolicy");
I don't know why using attributes didn't work for me.
I have a similar requirement as @drewbj21, for Angular code generation but also for StrawberryShake schema updates (running dotnet graphql update
locally without having to pass a token/API-key).
As far as I understand, this seems to be a limitation of the HotChocolate Authorization implementation. It doesn't call Authenticate
on schemes in the policy, so only relies on the authenticate being called on the default-scheme by the ASP.NET Core UseAuthenticate()
middleware.
Current workaround is to create a custom authentication scheme that combines both, creating your own ASP.NET Core middleware to authenticate all schemes, or doing the same in a HotChocolate HttpRequestInterceptor
.
Sample code I got from @tobias-tengler in slack:
services.AddGraphQLServer()
.AddHttpRequestInterceptor<AuthenticationHttpRequestInterceptor>();
public class AuthenticationHttpRequestInterceptor : DefaultHttpRequestInterceptor {
public override async ValueTask OnCreateAsync(HttpContext context, IRequestExecutor requestExecutor, IQueryRequestBuilder requestBuilder,
CancellationToken cancellationToken) {
var schemeProvider = context.RequestServices.GetRequiredService<IAuthenticationSchemeProvider>();
var schemes = (await schemeProvider.GetAllSchemesAsync()).ToArray();
if (schemes.Length > 1) {
foreach (var scheme in schemes) {
var result = await context.AuthenticateAsync(scheme.Name);
if (result.Succeeded) {
context.User = result.Principal;
break;
}
}
}
await base.OnCreateAsync(context, requestExecutor, requestBuilder, cancellationToken);
}
}
Is there an existing issue for this?
Describe the bug
We have a requirement to be able to authorize a request to our GraphQL/HC API using a bearer token or API key while also allowing anonymous calls for introspection. Up until a week or two ago we were able to accomplish this using the below set up in Program.cs. Our settings were based on a Stackoverflow answer on the topic (link below):
Link: https://stackoverflow.com/questions/61157111/specifying-an-authentication-scheme-for-a-single-route-thats-handled-by-middlew
Code (Program.cs):
This did not make much sense to me since I am globally requiring authorization then allowing anonymous but this worked for months so I left it. Now, the above set up allows me to authorize using a bearer token or api key but is also requiring authorization on introspection calls. We need introspection to allow anonymous calls to allow our Angular app to use it for code generation.
My first thought to fix is this was to remove the "RequireAuthorization" settings above and specify multiple authorization schemes within our individual Authorization attributes but I do not see a way to do this. Based on my research, the only way to specify multiple authorization schemes within GraphQL/HC is the above set up.
Steps to reproduce
Relevant log output
No response
Additional Context?
I have also tried to different endpoint configuration combinations (as suggested in current documentation) to require authorization on GraphQL https calls but not Banana Cake Pop endpoints without any success.
Our current work around is to comment out the "RequireAuthorization" settings. This allows us to still authorize using a bearer token on calls with the [Authorize] attribute and use introspection anonymously. This set up does not allow us to authorize using an api key.
I am by no means a GraphQL/HotChocolate expert so any help finding a solution would be greatly appreciated! Thanks.
Product
Hot Chocolate
Version
12.12.1