Comments (11)
You need to add [Authorize(AuthenticationSchemes=JwtBearerDefaults.AuthenticationScheme)]
to your GraphQLController
to make ASP.NET Core run the jwt authorization. See the following docs.
Provide a UserContext
class that implements IProvideClaimsPrincipal
.
public class GraphQLUserContext : IProvideClaimsPrincipal
{
public ClaimsPrincipal User { get; set; }
}
Provide that UserContext
to the DocumentExecutor
.
var executionOptions = new ExecutionOptions
{
...
UserContext = new GraphQLUserContext
{
// this is the User on your controller
// which is populated from your jwt
User = User
}
};
Register the AuthorizationValidationRule
(and other required services).
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.TryAddSingleton<IAuthorizationEvaluator, AuthorizationEvaluator>();
services.AddTransient<IValidationRule, AuthorizationValidationRule>();
Inject those validation rules into the ctor
of your GraphQLController
.
public GraphQLController(IDocumentExecuter documentExecuter,
ISchema schema,
ILogger<GraphQLController> logger,
IEnumerable<IValidationRule> validationRules)
{
_documentExecuter = documentExecuter;
_schema = schema;
_logger = logger;
_validationRules = validationRules;
}
}
Add the rules to the ExecutionOptions
.
var executionOptions = new ExecutionOptions
{
...
ValidationRules = DocumentValidator.CoreRules().Concat(_validationRules).ToList();
};
from authorization.
services.AddGraphQLAuth(_ =>
{
// _.AddPolicy("dev", p => p.RequireClaim("role", "dve") || p.RequireClaim("role", "admin"));
_.AddPolicy("AdminPolicy", p => p.RequireClaim("Role", "Manager"));
});
public static class GraphQLAuthExtensions
{
public static void AddGraphQLAuth(this IServiceCollection services, Action<AuthorizationSettings> configure)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<GraphQL.Authorization.IAuthorizationEvaluator, AuthorizationEvaluator>();
services.AddTransient<IValidationRule, AuthorizationValidationRule>();
services.AddSingleton(s =>
{
var authSettings = new AuthorizationSettings();
configure(authSettings);
return authSettings;
});
public class GraphQLUserContext : IProvideClaimsPrincipal
{
public ClaimsPrincipal User { get; set; }
}
from authorization.
Is adding .UseAuthentication();
enough? My HttpContext.User never seems to have any claims or properties set though I'm not 100% sure if this is an issue with the token or not.
Turns out I had an expired JWT. The following should be enough for anyone else who ends up here.
In ConfigureServices:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options => options.AddAuth0JwtBearerOptions(Configuration));
In Configure:
app.UseAuthentication(); // must be before it needs to be used
app.UseGraphQL<ISchema>();
from authorization.
You would handle the JWT outside of GraphQL Auth. See https://developer.okta.com/blog/2018/03/23/token-authentication-aspnetcore-complete-guide
You would then create GraphQL Auth Policies that check the claims in the ClaimsPrincipal. The ClaimsPrincipal gets populated from the JWT.
from authorization.
Hello,
Please can you educate me on how to create the graphql auth policy. Also I have found that the examples are using middleware. However I am not using a middleware approach.
from authorization.
Hello
I have tried this:
services.TryAddTransient<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IJwtFactory, JwtFactory>();
var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));
// Configure JwtIssuerOptions
services.Configure<JwtIssuerOptions>(
options =>
{
options.Issuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
options.Audience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)];
options.SigningCredentials = new SigningCredentials(_signingKey, SecurityAlgorithms.HmacSha256);
});
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],
ValidateAudience = true,
ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],
ValidateIssuerSigningKey = true,
IssuerSigningKey = _signingKey,
RequireExpirationTime = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
services.AddAuthentication(
options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(
configureOptions =>
{
configureOptions.ClaimsIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
configureOptions.TokenValidationParameters = tokenValidationParameters;
configureOptions.SaveToken = true;
});
services.TryAddSingleton<IAuthorizationEvaluator, AuthorizationEvaluator>();
services.AddTransient<IValidationRule, AuthorizationValidationRule>();
services.TryAddSingleton(s =>
{
var authSettings = new AuthorizationSettings();
authSettings.AddPolicy("AuthPolicy",
builder =>
{
builder.RequireClaim(ClaimTypes.NameIdentifier);
builder.RequireClaim(ClaimTypes.Country);
});
return authSettings;
});
I would like to know what else should I do to get the authenticated user. This is my graphql controller:
public class GraphQLController : Controller
{
private readonly IDocumentExecuter _documentExecuter;
private readonly ILogger _logger;
private readonly ISchema _schema;
/// <summary>
/// </summary>
/// <param name="documentExecuter"></param>
/// <param name="schema"></param>
/// <param name="logger"></param>
public GraphQLController(IDocumentExecuter documentExecuter,
ISchema schema,
ILogger<GraphQLController> logger)
{
_documentExecuter = documentExecuter;
_schema = schema;
_logger = logger;
}
/// <summary>
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
public async Task<IActionResult> Post([FromBody] GraphQLQuery query)
{
if (query == null) throw new ArgumentNullException(nameof(query));
try
{
var inputs = query.Variables.ToInputs();
var executionOptions = new ExecutionOptions
{
Schema = _schema,
Query = query.Query,
Inputs = inputs,
ExposeExceptions = true,
EnableMetrics = true
};
var result = await _documentExecuter.ExecuteAsync(executionOptions).ConfigureAwait(false);
if (result.Errors?.Count > 0)
{
_logger.LogWarning($"Errors: {JsonConvert.SerializeObject(result.Errors)}");
return BadRequest(result);
}
return Ok(result);
}
catch (Exception e)
{
_logger.LogError(e, string.Empty);
}
return StatusCode((int) HttpStatusCode.InternalServerError);
}
}
from authorization.
Thank you so much for the explanation.
from authorization.
HI @joemcbride I am using app.UseGraphQLHttp(options);
I am not using controller.
my issue is I have to call jwt token validation manually. I wanted to get it called automatically.
from authorization.
I've got a similar issue to you @som-nitjsr. Just trying to figure out how this works when using graphql-dotnet/server. We can't just add the Authorize attribute onto our controller to make the AuthorizeEvents trigger. What did you end up doing?
from authorization.
cheers :)
from authorization.
I am currently building a SPA aswell. That uses JWT. Can you guys show me the code for your project. I can't seem to make it work in any way...
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.