Comments (10)
I was able to setup Subscription auth using built in elements alone. If you are interested @jonmill I can give you my method.
from authorization.
Sure.
The main issue I ran into with authorization and graphql-dotnet is the inconsistent handling of the user context. In graphql-dotnet proper, we are told to implement a Dictionary<string,object>
and here in authorization we are told to implement an IProvideClaimsPrincipal
. After digging through the source I discovered that really it should be the same implementation for both types as the validator here in authorization casts the user context to an IProvideClaimsPrincipal
before authorizing. It does work when the GraphQLMiddleware sets up the execution context because that middleware invokes the BuildUserContext
method. The GraphQLWebSocketMiddleware does not invoke this method and instead sends a MessageHandlingContext
to the executor. Due to this, whatever authenticate pipeline we setup in native AspNetCore is ignored completely by the authorizing validator here in authorization
.
I know this preamble was long but bear with me because it explains this next part: I'm not using the authorization
repo for the authorization. I dug through the graphql-dotnet repositories and found a namespace tucked away in the server
repository: Authorization.AspNetCore.
This repository has very similar code to what exists here in the authorization
repo except that its authorization validator uses the IHttpContextAccessor
to find the actual AspNetCore user context (I believe this makes way more sense than having an arbitrary Dictionary<string,object>
provider for user context. This validator works for whichever GraphQL middleware is currently executing the result. The error handling is a little dry in the server repo but it really doesn't matter to me because it properly leverages the well written Microsoft Authorization types.
The final step here is how to actually handle the token during a websocket request. Obviously we cannot pass it through the headers as browsers do not allow header values beyond web socket protocol. In my case, I'm sending the access token as a query param and then using a message event handler in my JWT config to set the token during a websocket request. Here's startup psuedocode that should work for you.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "some authority";
options.Audience = "some audience";
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = ClaimTypes.NameIdentifier
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
if (context.Request.Query.TryGetValue("access_token", out StringValues queryToken) &&
context.Request.Headers.ContainsKey("Sec-WebSocket-Protocol"))
{
context.Token = queryToken.Single();
}
return Task.CompletedTask;
}
};
});
// Add schema types...
services.AddGraphQL()
.AddGraphQLAuthorization()
.AddWebSockets();
}
public void Configure(IApplicationBuilder builder)
{
builder.UseAuthentication();
builder.UseWebsockets();
builder.UseGraphQLWebsockets<Schema>();
builder.UseGraphQL<Schema>();
}
I can probably put together a sample repo a little later on.
from authorization.
@joemcbride any ideas here? :)
from authorization.
same issue
from authorization.
I ended up switching away from the built in provider and rolled my own in order to work with Subscriptions and Queries / Mutations
from authorization.
It's not directly supported from what I've seen - from previous dicussions on the topic, auth is expected to more/less be your own custom coding.
Ideally you're running this under a WebAPI controller - so JWT should already be negotiated to the context.
For usage you'd do like:
settings.AddPolicy(AuthConstants.ADMIN_POLICY, _ => { _.AddRequirement(new RoleAuthorizationRequirement(UserRoles.Administrator)); });
....
ExecutionResult result = await _executer.ExecuteAsync(_ =>
{
...
_.UserContext = HttpContext.Current
...
}
....
public class RoleAuthorizationRequirement : IAuthorizationRequirement
...
public RoleAuthorizationRequirement(params string[] roles)
....
public Task Authorize(AuthorizationContext ac)
....
HttpContext ctx = (HttpContext)ac.UserContext;
if (ctx == null || ctx.User == null || ctx.User.Identity == null ||String.IsNullOrEmpty(ctx.User.Identity.Name))
throw;
...
Do lookups with - ctx.User.Identity.Name
from authorization.
Also keep in mind, "UserContext" can be anything you want.
from authorization.
@jonmill Is this issue still actual for you?
from authorization.
@sungam3r it would be nice if there was a way that this was built-in, instead of having to roll-your-own auth...but no, I have moved on from this issue and done auth myself
from authorization.
@mlynam May I ask if you would share the snipped to anyone? Thank you very much @mlynam
from authorization.
Related Issues (20)
- Checking for a valid JWT and integrating with a Refresh-Token-Workflow HOT 10
- UNAUTHENTICATED error code HOT 3
- In AuthorizationValidationRule.cs the method CheckAuth is called multiple times. Why? HOT 4
- ETA for v4? HOT 18
- IAuthorizationRequirement is not sent the same variable names as those in IResolveField context HOT 2
- ClaimsPrincipal not retrived trying to use AuthorizeWith in GraphQL queries HOT 6
- Any example for schema first auth example? HOT 2
- How to get a status code 401 when not authorized HOT 6
- Move GraphQLAuthExtensions from Harness into new package HOT 6
- Add docs about IAuthorizationSkipCondition and DI
- Method 'ValidateAsync' in type 'GraphQL.Authorization.AuthorizationValidationRule' from assembly 'GraphQL.Authorization, Version=4.0.0.0 HOT 7
- Question: AuthorizeWithPolicy is being ignored HOT 10
- GraphQL .net authorization with JWT token HOT 7
- AddGraphQLAuth no longer works after switching to Middleware HOT 1
- Return 401 and 403 status code HOT 5
- Is this library still relevant with GraphQL 7+ HOT 22
- How to read graphql query from authorization requirement ?
- Graphql Authorization not working HOT 4
- Faulty reference HOT 6
- How to login user and return token and id ? HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from authorization.