-
Notifications
You must be signed in to change notification settings - Fork 113
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
Add middleware for automatic authorization based on request endpoint #55
base: main
Are you sure you want to change the base?
Add middleware for automatic authorization based on request endpoint #55
Conversation
@wanderzirkus We could create something like Keycloak.AuthServices.Contrib project and put it there |
This could be interesting, could you please consider adding some attributes that provide metadata regarding Resouce and Scope? Also, how do we validate based on entity Id? E.g: we have a rule for specific entities to be protected. The default path convention is interesting, but it requires certain conventions on the side of the authorization server, which is not always true. I think we need to be able to adapt C# code |
Hey thanks for your interest, glad to here that! :) The idea is that the authorization server has appropriate resources prepared: Let me know if I understood you correctly and what you think about my thoughts. |
I would like to suggest you have a quick call to discuss this functionality. Could you please write me an email so we continue discussing time slots? |
… working example for URI based keycloak authorization
…tor Middleware; Extend example app
…essful auth in middleware
… working example for URI based keycloak authorization
…tor Middleware; Extend example app
…essful auth in middleware
…thub.com/wanderzirkus/keycloak-authorization-services-dotnet into feature/auto-protect-resource-middleware
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.
Thank you for the PR, I left some comments. We might need to have a call to resolve them to save your time
[HttpGet] | ||
[Route("/api/explicit-auth")] | ||
[ProducesResponseType(statusCode: 200, type: typeof(string))] | ||
[ExplicitResourceProtection("/api/auto-auth", "GET")] |
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.
I think we can rename it to something simple:
ProtectedResource(string resource, string scope)
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.
Ok edit: after giving it a second thought, I don't like ProtectedResource as much, because it implies, that all methods, that dont have the attribute are not protected. Thats why I put in "explicit" as a prefix.
[HttpGet] | ||
[Route("/api/no-auth")] | ||
[ProducesResponseType(statusCode: 200, type: typeof(string))] | ||
[DisableUriBasedResourceProtection] |
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.
I suggest not focus on URI based, but on the general one, so it could be [ProtectedResouce(Disable = true)]
Let me know what you think about this design. I like it because you don't need to remember a lot of other attributes.
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.
Good idea :)
{ | ||
services.AddKeycloakAuthentication(configuration); | ||
|
||
services.AddAuthorization(authorizationOptions => authorizationOptions.FallbackPolicy = new AuthorizationPolicyBuilder() |
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.
There is a new helpful time called, please consider using it:
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.
What do you mean exactly?
{ | ||
public static IServiceCollection AddAuth(this IServiceCollection services, IConfiguration configuration) | ||
{ | ||
services.AddKeycloakAuthentication(configuration); |
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.
Migrate to 2.0.0. Basically, you need to rebase on the main branch to see the latest changes. We can setup a call to migrate to 2.0.0 together if needed
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.
How much trouble would it be for you to do the migration? I don't know if I have the time to do this currently, depending how much it is.
/// b) annotate controller methods with the "[Authorize]" attribute | ||
/// It is possible to exclude methods from the policy enforcement by annotate them with the "[AllowAnonymous]" attribute, however. | ||
/// </summary> | ||
public class UriBasedResourceProtectionMiddleware |
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.
Can we add some tests? We can discuss what types of tests are needed for this one.
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.
There is a collection of unittest. Which additional tets do you have in mind?
using Moq; | ||
|
||
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. | ||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "<Pending>")] |
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.
Inline suppression should be avoided, let's configure it via .editorconfig for test project.
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.
Sure thing. I didn't want to change it, because its your project after all and you are making the style rules :)
var requestDelegateMock = new Mock<RequestDelegate>(); | ||
|
||
// Act & Assert | ||
Assert.Throws<ArgumentNullException>(() => _ = new UriBasedResourceProtectionMiddleware(requestDelegateMock.Object, null)); |
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.
Consider Fluent Assertions
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.
Okay
Also, I think this case is partially covered by |
This is a very niche functionality, We should consider creating |
…rceProtectionAttribute; adapted tests; adapted samples; disable to rules by test specific .editorconfig
… working example for URI based keycloak authorization
…tor Middleware; Extend example app
…essful auth in middleware
… working example for URI based keycloak authorization
…tor Middleware; Extend example app
…rceProtectionAttribute; adapted tests; adapted samples; disable to rules by test specific .editorconfig
…thub.com/wanderzirkus/keycloak-authorization-services-dotnet into feature/auto-protect-resource-middleware
rename AutoProtectResource to UriBasedResourceProtection; add minimal working example for URI based keycloak authorization introduce DisableAutoProtection and ExplicitResourceProtection; Refactor Middleware; Extend example app add testclass for middleware; fix bug where status set to 401 on successful auth in middleware add middleware and builder extension method for usage rename AutoProtectResource to UriBasedResourceProtection; add minimal working example for URI based keycloak authorization introduce DisableAutoProtection and ExplicitResourceProtection; Refactor Middleware; Extend example app merged DisableUriBasedResourceProtection attribute into ExplicitResourceProtectionAttribute; adapted tests; adapted samples; disable to rules by test specific .editorconfig add middleware and builder extension method for usage rename AutoProtectResource to UriBasedResourceProtection; add minimal working example for URI based keycloak authorization introduce DisableAutoProtection and ExplicitResourceProtection; Refactor Middleware; Extend example app add testclass for middleware; fix bug where status set to 401 on successful auth in middleware add middleware and builder extension method for usage rename AutoProtectResource to UriBasedResourceProtection; add minimal working example for URI based keycloak authorization introduce DisableAutoProtection and ExplicitResourceProtection; Refactor Middleware; Extend example app merged DisableUriBasedResourceProtection attribute into ExplicitResourceProtectionAttribute; adapted tests; adapted samples; disable to rules by test specific .editorconfig
…thub.com/wanderzirkus/keycloak-authorization-services-dotnet into feature/auto-protect-resource-middleware
…t-resource-middleware
Alright, I think I got the latest version of main merged into my feature branch now. I forgot to fetch the latest version from remote before rebasing/merging *facepalm |
Well if you don't want this feature at all feel free to just close the PR. I find it most useful and thought I could give s.th. back, but I am not upset, if you say its to niche to be considered valuable enough for the repo. :) |
@wanderzirkus let's discuss the feature in discord. Do you have time for that? |
|
Hi there.
First things first: Thanks for this repo and the good work! :) This is also my first PR on GitHub ever, so I hope I didn't violate any policies with my PR.
Lets get to the topic: I like using the Keycloak authorization services in a way, that I don't have to recompile if any thing about authorization changes (users, roles, permissions or even policies). More over I want a clean separation of concerns and that for I don't want to annotate the request endpoints in the controllers with authorization specific information (except "AllowAnonymous" of course).
To achieve this, I'd like to have a middleware, which takes path and method of the request, pass them to the "IKeycloakProtectionClient.VerifyAccessToResource()"-method and proceed with the request depending on the result.
What do you think about it?
Please let me know if I should any unittests for this, too.