-
Notifications
You must be signed in to change notification settings - Fork 19
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
Authorization deep dive amendments #428
Conversation
No New Or Fixed Issues Found |
Deploying contributing-docs with Cloudflare Pages
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a guidance perspective I know we have gone back and forth on this one, so is the right answer that it's case-by-case? @mzieniukbw has bitwarden/server#4741 which is pretty clean. Is the callout then to shift the logic when command-chaining comes up? I mostly understand your numbered points but it focuses on being API-centric and that might not be the case for us.
Separately, we should discuss AuthorizeOrThrowAsync
-- can you elaborate what you think it's obscuring? Is it simply the exception? For something so heavily used I think not repeating the success check is a positive.
The main question here is how tightly coupled authorization and C/Qs should be. In very simple situations, they can be totally decoupled. e.g. See SecretsController.CreateAsync. It's the endpoint for creating a secret, you call In more complex situations, the command does multiple things, all of which need to be authorized, and that may not be clear from the controller. In this case I'm going to explore an interface where the command can return a list of its authorization requirements, without making the authz call itself. This is a loose coupling where the controller can still handle authorization without having to know the inner workings of the command; and the command doesn't need to know how authorization works. I want to try it before documenting it but I think this is a better level of abstraction. (It was Gibson's suggestion initially, I can't take too much credit.) The current guide has the tightest coupling, where the C/Q must call AuthorizationService directly. I suggested it to try to simplify things but I think it's undesirable for the reasons in my first post. I would prefer to have a clear rule about where we do authorization checks, so that they are less likely to be overlooked or missed. (e.g. assuming it's handled by the C/Q class when it's not.) However if it's something that we need to work over more in practice before documenting here then we can do that. I'm a bit wary about over-documenting or documenting prematurely if individual teams want to experiment.
|
After considering our approach further, I have:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solid middle ground I'd say.
🎟️ Tracking
N/A
📔 Objective
Some follow-up changes to the authorization deep dive based on some recent discussions and experience.
The main change is to state that
AuthorizationService
should be called from the controller, rather than in the core layer (the query/command class). There are several reasons for this:ClaimsPrincipal
into the core layer. On the controller it's always available asUser
.I have additional ideas around how to handle commands with complex authorization requirements, however I'd rather this guide follow our practice rather than vice versa. I don't want to overspecify here and keep having to amend it. We'll continue to iterate on it.
Other minor changes:
Bit.Core.Exceptions.NotFoundException
rather thanNotFoundError
(typo)AuthorizeOrThrowAsync
. I never added this overload and in retrospect I think it obscures things.⏰ Reminders before review
team
🦮 Reviewer guidelines
:+1:
) or similar for great changes:memo:
) or ℹ️ (:information_source:
) for notes or general info:question:
) for questions:thinking:
) or 💭 (:thought_balloon:
) for more open inquiry that's not quite a confirmedissue and could potentially benefit from discussion
:art:
) for suggestions / improvements:x:
) or:warning:
) for more significant problems or concerns needing attention:seedling:
) or ♻️ (:recycle:
) for future improvements or indications of technical debt:pick:
) for minor or nitpick changes