Ability to disable quarkus.http.auth.proactive for select paths.
Description
We are building a small proxy endpoint to extract userinfo from a 3rd party oauth identify provider using keycloak. This requires the ability to forward a JWT token (for the 3rd party provider) through our endpoint to their graphql api.
With quarkus.http.auth.proactive = true the JWT token passed to the proxy endpoint gets validated as if it came from our application which causes an authentication failure. Disabling this flag solves the issue, but leaves our other endpoints without the proactive check. There does not appear to be any method to allow quarkus.http.auth.proactive=true style behavior everywhere except this singular proxy endpoint.
An option like quarkus.http.auth.proactive.excluded-path would be a big help. Thanks!
Implementation ideas
No response
/cc @pedroigor (bearer-token)
@Grantismo Why is it important to have proactive checks for non proxy requests? It would only make a difference for public endpoints
@Grantismo Why is it important to have proactive checks for non proxy requests? It would only make a difference for public endpoints
- Presumably the security folks who decided to make
quarkus.http.auth.proactive = truethe default setting thought that it confers meaningful security benefits. Protecting public endpoints is one such meaningful benefit. - Per https://quarkus.io/guides/security-proactive-authentication there are substantive differences requiring workarounds in the blocking vs. non blocking access of SecurityIdentity and standard security annotations. For a task as small as this proxy endpoint, disabling
quarkus.http.auth.proactivethen introduces a risk of application wide changes/breakages outside of the scope of that change.
@Grantismo
Presumably the security folks who decided to make quarkus.http.auth.proactive = true the default setting thought that it confers meaningful security benefits. Protecting public endpoints is one such meaningful benefit.
AFAIK, in context of accessing the public endpoint, it is only useful if one expects to access a credential such as the incoming JWT token, in the public method, do you have such a requirement ? Otherwise, keeping the proactive authentication might indeed cause 401 when someone with an invalid token tries to access a public endpoint, but the public access is about letting anyone to access it, so having a proactive authentication on in such cases can only cause unexpected side-effects for users.
Per https://quarkus.io/guides/security-proactive-authentication there are substantive differences requiring workarounds in the blocking vs. non blocking access of SecurityIdentity and standard security annotations. For a task as small as this proxy endpoint, disabling quarkus.http.auth.proactive then introduces a risk of application wide changes/breakages outside of the scope of that change.
Well, this sounds somewhat theoretical, what breaking changes, do you expect them ? In many cases the application code will not see any differences. In fact many annotation based security features in Quarkus require disabling it.
CC @michalvavrik
I wonder if this is not misunderstanding, because comments like:
leaves our other endpoints without the proactive check Protecting public endpoints is one such meaningful benefit.
Sounds like proactive authentication enforces authentication, or gives you any security benefits. However, proactive authentication is basically: if there are credentials, we authenticate early in IO thread in case you need to know who send this request much later in your code. It can bring some unnecessary processing if you are sending credentials to public endpoints, I think that is what you mean.
In everything else, I agree with @sberyozkin . There shouldn't be risk disabling proactive authentication, but if you find one, we should address that.
Is the claim then that quarkus.http.auth.proactive=true offers negligible benefits? If so, then why is it the default behavior?
From a configuration design perspective it is unexpected to have a setting which alters request scoped behavior which is only configurable at a global level and not configurable/overridable at the request scope.
Is the claim then that
quarkus.http.auth.proactive=trueoffers negligible benefits?
Benefits depends on each application. If you need access to the security identity, you will benefit. If you don't need it, disable proactive authentication.
From a configuration design perspective it is unexpected to have a setting which alters request scoped behavior which is only configurable at a global level and not configurable/overridable at the request scope.
Personally, I prefer to add configuration option when users need it as having many configuration options makes configuration more complex, it is easy to get lost in many properties. Can we focus on your specific use case, please? We need to understand what you are trying to solve.
@Grantismo
Is the claim then that quarkus.http.auth.proactive=true offers negligible benefits? If so, then why is it the default behavior?
It is a more restrictive policy that is designed to prevent users accessing invalid tokens or other credential types in public methods and making some application level decisions based on the invalid' token content.
It also introduces a clearer separator between the authentication and authorization.
I agree with @michalvavrik that it has to be evaluated, which policy works best for what application, though perhaps I'd not recommend deciding which policy to use depending on how easy or not it is to get to the identity instance...
Personally, I prefer to add configuration option when users need it as having many configuration options makes configuration more complex, it is easy to get lost in many properties. Can we focus on your specific use case, please? We need to understand what you are trying to solve.
+1. I believe that @Grantismo's concern was that the application would lose some advantages of the proactive authentication, since only its very narrow URI (proxy) space requires disabling the proactive authentication.
Thinking more about it... Don't we already have it working ?
So the method that acts as a proxy is currently impacted because when the token arrives it is verified too early, with the proxy the authentication decision is made later after some work with Keycloak.
I.e, effectively, from the Quarkus Security perspective, the method that does proxying is public.
@Grantismo Is it correct ? If so, you could use HTTP security policy configuration to restrict the authentication to all but this proxy method...
Let us know please
Thinking more about it... Don't we already have it working ?
So the method that acts as a proxy is currently impacted because when the token arrives it is verified too early, with the proxy the authentication decision is made later after some work with Keycloak.
I.e, effectively, from the Quarkus Security perspective, the method that does proxying is
public.@Grantismo Is it correct ? If so, you could use HTTP security policy configuration to restrict the authentication to all but this proxy method...
HTTP Permissions were the first thing I thought about, but the key difference is that proactive authentication accepts anonymous identity while the authenticated policy will not and return 401. I'd say you need tiny little bit more, e.g.:
quarkus.http.auth.proactive=false
quarkus.http.auth.permission.proactive-auth.policy=custom
quarkus.http.auth.permission.proactive-auth.paths=*
quarkus.http.auth.permission.public.policy=permit
quarkus.http.auth.permission.public.paths=/public/*
and https://quarkus.io/guides/security-authorize-web-endpoints-reference#custom-http-security-policy.
Idea: proactive auth policy :-)
@michalvavrik Sorry, I meant
quarkus.http.auth.permission.secured.policy=authenticated
quarkus.http.auth.permission.secured.paths=/some-paths-that-must-be-secured/*,/more-paths-that-must-be-secured/*
that that should be all that is needed.
I'm not sure your example works, I mean, it gives users an option to implement a custom policy but it is not what @Grantismo is after if I understand it correctly... The ask is to make an endpoint that does some internal proxying effectively public since it will do some internal verification, but let the rest of the application be secured using whatever authentication mechanism that is required by that application
I'm not sure your example works, I mean, it gives users an option to implement a custom policy but it is not what @Grantismo is after if I understand it correctly... The ask is to make an endpoint that does some internal proxying effectively public since it will do some internal verification, but let the rest of the application be secured using whatever authentication mechanism that is required by that application
In that case your proposal works. And I can't see any relation to proactive authentication at all. I think this is misunderstanding of what proactive auth is.
Hi @michalvavrik, sure, I guess it is assuming I understood the use case correctly myself.
I think we can close this issue as not planned,
@Grantismo Can you please let us know if a proposed HTTP policy configuration above solves the problem ?
I'll try the HTTP policy config approach and report back (may be a week or so before I get a chance). Thanks for the help