Closed lorenzobenvenuti closed 9 months ago
/cc @sberyozkin
Hi @lorenzobenvenuti Sure, please do it
It turns out that implementing this feature is harder than I thought: I didn't notice that X509IdentityProvider
is defined in the quarkus-security
module and it doesn't have access to RoutingContext
and HttpSecurityUtils
. I thought I could move attribute handling to HttpAuthenticator
(that way RoutingContext
will be added to SecurityIdentity
attributes for all the HTTP-based authentication mechanism) but since the augmentors are invoked at the IdentityProvider
level, it won't solve my issue.
I can think of different solutions, but TBH I don't like any of them.
Option 1: define the mappings between AuthenticationRequest
and SecurityIdentity
somewhere; for example, introducing an AttributeMapper
interface that declares a Map<String, String> getAttributeMappings()
method. X509IdentityProvider
could inject a Instance<AttributeMapper>
and, if present, copy all the attributes defined in the mappings. Then, the HTTP extension could add an AttributeMapper
implementation to the context, mapping quarkus.http.routing.context
to RoutingContext.class.getName()
.
Option 2: same as above, but passing the mappings in an attribute. MtlsAuthenticationMechanism
can add a quarkus.security.attributes
attribute to the AuthenticationRequest
, containing a Map<String,String>, and
X509IdentityProvidercan read that attribute and copy the other attributes to the
SecurityIdentity` instance
Option 3, really ugly hack: read/write the attribute using strings to avoid requiring an explicit dependency, i.e.
/* In X509IdentityProvider */
QuarkusSecurityIdentity.builder()
/* ... */
.addAttribute(
"io.vertx.ext.web.RoutingContext",
request.getAttribute("quarkus.http.routing.context")
)
/* ... */
Just kidding, I refuse to write this code :-D
For options 1 and 2, attributes could also be copied in IdentityProviderManager
to share the logic across all the identity providers.
Thoughts?
Thanks,
lorenzo
Another (hack-ish) option: add this bean to the vertx-http
module
@Priority(1000)
public class RoutingContextAwareX509IdentityProvider extends X509IdentityProvider {
@Override
public Uni<SecurityIdentity> authenticate(CertificateAuthenticationRequest request, AuthenticationRequestContext context) {
final Uni<SecurityIdentity> authenticate = super.authenticate(request, context);
return authenticate.onItem().transform(
it -> QuarkusSecurityIdentity.builder(it)
.addAttribute(RoutingContext.class.getName(), HttpSecurityUtils.getRoutingContextAttribute(request))
.build()
);
}
}
This is an HTTP-oriented implementation of X509IdentityProvider
that will be invoked before X509IdentityProvider
because of the highest priority.
@lorenzobenvenuti Hi, sorry for a delay, so may be the simplest is for your application to ship such a custom provider ?
Hi @sberyozkin yes, actually that's what we're doing right now. I was just wondering if someone else could benefit from moving this class to the framework, but probably it's a pretty unique use case (mTLS + need to access an header) and it's not worth the effort: if someone else needs something similar they can just write their own IdentityProvider
.
Thanks,
lorenzo
Description
Hi,
I'm trying to access the current request in a
SecurityIdentityAugmentor
. Since injectingRoutingContext
doesn't seem to work (I tried with and without@ActivateRequestContext
), I'm wondering ifRoutingContext
can be passed in aSecurityIdentity
attribute. I see it's already done inOidcIdentityProvider
(here) andMpJwtValidator
(here). For my use case, I'd like to have the same behavior for mTLS authentication (X509IdentityProvider
). If you think it's valuable, I can try to put an MR together.Thanks,
lorenzo
Implementation ideas
MtlsAuthenticationMechanism
is already adding theRequestContext
to theAuthenticationRequest
attributes, I think it only needs to be forwarded to theSecurityIdentity
attributes inX509IdentityProvider
: