-
-
Notifications
You must be signed in to change notification settings - Fork 158
Authorization example #1300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
If you want to add |
It's not clear from the documentation what it the best way to achieve that. Should I copy the |
Our documentation assumes basic knowledge of C#, ASP.NET and EF Core. We favor covering just the basics to keep it concise and maintainable. And we assume that users are willing to experiment, look at the samples and integration tests, search the history of GitHub issues and the Gitter chat, google for common solutions etc. How to inherit from a base class is not something you should learn here. See also the issue template for asking a question. To get a satisfying answer, you'll need to put in some more effort upfront. How do you propose to implement adding |
That's probably the piece I was missing. I thought the generated controllers were the idiomatic way to go. |
For future readers you can follow the section earlier versions and create such controller: public class UsersController : JsonApiController<User, long>
{
public UsersController(
IJsonApiOptions options,
IResourceGraph resourceGraph,
ILoggerFactory loggerFactory,
IResourceService<User, long> resourceService)
: base(options, resourceGraph, loggerFactory, resourceService)
{
}
[HttpGet("{id}")]
[HttpHead("{id}")]
[Authorize(AuthenticationSchemes = "XXX")]
public override Task<IActionResult> GetAsync(long id, CancellationToken cancellationToken)
{
return base.GetAsync(id, cancellationToken);
}
} This is only a partial answer because
|
To overcome these, you can inject |
I was able to implement a basic scope-based authorization middleware using internal class JsonApiAuthorizationMiddleware
{
private readonly RequestDelegate _next;
public JsonApiAuthorizationMiddleware(RequestDelegate next)
{
_next = next ?? throw new ArgumentNullException(nameof(next));
}
public Task Invoke(HttpContext context, IJsonApiRequest jsonApiRequest)
{
var resourceType = jsonApiRequest.SecondaryResourceType ?? jsonApiRequest.PrimaryResourceType;
if (resourceType != null)
{
string expectedScope = (jsonApiRequest.IsReadOnly ? "read" : "write") + ':' + resourceType;
string? scopeClaim = context.User.GetClaim("scope");
if (scopeClaim == null || !Array.Exists(scopeClaim.Split(','), s => s == expectedScope))
{
throw new JsonApiException(new ErrorObject(HttpStatusCode.Forbidden)
{
// ...
});
}
}
return _next(context);
}
} Several limitations:
|
There's a sample usage of constraint providers at https://github.com/json-api-dotnet/JsonApiDotNetCore/blob/master/src/Examples/NoEntityFrameworkExample/Services/InMemoryResourceService.cs#L83. But it gets populated from an MVC action filter, which executes after any middleware. It would be more appropriate to run these checks at a deeper level. If it runs from a resource service, it works for atomic:operations as well. Alternatively, an optimization would be to verify all scopes upfront in an atomic:operations request, similar to how ModelState validation runs. See https://github.com/json-api-dotnet/JsonApiDotNetCore/blob/master/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs. |
Very nice, thanks! I think you can close the issue once that's merged, it gives a good idea of how authorization could be implemented. |
Is your feature request related to a problem? Please describe.
I would like to add authorization to my JSON:API, especially scope-based authorization. For example the user needs to have the
user.read
scope to read user information.Describe the solution you'd like
It's probably already doable but I'm looking for the idiomatic way to do that and since it's a very common use-case, I think it would be great to add that to the documentation.
The text was updated successfully, but these errors were encountered: