Skip to content

Conversation

@michalvavrik
Copy link
Member

@michalvavrik michalvavrik commented Nov 27, 2025

  • part of the Provide a fluent API to set up Quarkus Security #16728 effort
  • in relation to the https://quarkus.io/guides/security-jpa there are only following use cases:
    • you have multiple mechanisms, like form and basic and you want them to use different persistence unit or even one of them not using JPA-based identity providers
    • you are creating your own mechanism like new CustomHttpAuthenticationMechanism() and you want it to only use JPA Providers while there are other UsernamepasswordRequest identity providers
    • you just insist on doing everything programmatically

@quarkus-bot

This comment has been minimized.

@michalvavrik michalvavrik force-pushed the feature/fluent-api-for-identity-provider-and-augmentor branch from 3d9f827 to 86e5b6a Compare November 28, 2025 00:29
@github-actions
Copy link

github-actions bot commented Nov 28, 2025

🎊 PR Preview 3f428b9 has been successfully built and deployed to https://quarkus-pr-main-51279-preview.surge.sh/version/main/guides/

  • Images of blog posts older than 3 months are not available.
  • Newsletters older than 3 months are not available.

@quarkus-bot
Copy link

quarkus-bot bot commented Nov 28, 2025

Status for workflow Quarkus Documentation CI

This is the status report for running Quarkus Documentation CI on commit 86e5b6a.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

Warning

There are other workflow runs running, you probably need to wait for their status before merging.

@quarkus-bot

This comment has been minimized.

* Registers given {@link HttpAuthenticationMechanism} in addition to all other global authentication mechanisms.
*
* @param mechanism {@link HttpAuthenticationMechanism}
* @param identityProviders {@link IdentityProvider}s that should be used for authentication instead
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is not clear to me is why these identity providers and augmentors must be used instead of CDI registered identity providers and augmentors, while the mechanism is not meant to be used instead of other mechanisms.

Copy link
Member Author

@michalvavrik michalvavrik Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before I answer, I would like to summarize so that we speak about the same thing:

  • this method adds a new mechanism (like new CustomAuthMechanism or any other mechanism at all) and allows you to use your own identity providers and augmentors
  • if you want to use global identity providers or augmentors, then don't use it
  • if you want to use global identity providers/augmentors and some other providers/augmentors, specific for only this mechanism, you can create collection with global identity providers/augmentors and your own, specific for only this mechanism; nothing stops you

What is not clear to me is why these identity providers and augmentors must be used instead of CDI registered identity providers and augmentors, while the mechanism is not meant to be used instead of other mechanisms.

  • how many times do you want to use both identity providers registered as CDI beans and dedicated ones for this mechanism? I'd say you usually need one or two
  • this methods facilitates programmatic setup for Quarkus Security JPA, if with httpSecurity.basic() we already use Quarkus Security JPA from CDI, then why would we need the programmatic setup at all? Only answer I could come with is flexibility - unlike CDI providers, which are there for every mechanism, here you can explicitly select which provider and augmentors you want to apply

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, CDI registered augmentor may be used with any mechanism.

I think it would make sense not to mix augmentors and identity providers in such methods.

I'd also consider providing a generic option for adding identity providers without focusing on JPA first, as part of the fluent API, where an option to add an identity provider becomes available only after a method registering a custom mechanism is chosen...

IMHO it should be a draft PR

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, CDI registered augmentor may be used with any mechanism.

I think it would make sense not to mix augmentors and identity providers in such methods.
I'd also consider providing a generic option for adding identity providers without focusing on JPA first, as part of the fluent API, where an option to add an identity provider becomes available only after a method registering a custom mechanism is chosen...

I wrote it based on this comment quarkusio/quarkus-security#76 (comment) which suggests this:

Mechanism -> Identity Provider(s) -> Augmentors(s) or Mechanism -> Augmentors(s)

and that is the hierarchy introduced here (except I chose one of tem - I don't order augmentors under identity providers, it would only bring work and no pros I know about).

whether we write it like:

httpSecurity.mechanism(form, jpa)

as my tests do, or we do something like:

httpSecurity.buildMechanism(form).identityProvider(jpa).augmentor(customAugmentor)

is just matter of finding the right name for that HttpSecurity method. I put it into one httpSecurity.mechanism method because I am not aware of a good name (we cannot do httpSecurity.mechanism(form).augmentor... because the return type is HttpSecurity). I don't mind rewriting it if you have a suggestion.

IMHO it should be a draft PR

I'll make it draft right now. Drafts make only sense when there is something to work on. Let's establish what is it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, CDI registered augmentor may be used with any mechanism.

Sure. What do you want to say? This PR gives you 3 options:

  • use CDI augmentors if you don't configure augmentors via HttpSecurity
  • use your own augmentors, whether you create instance or inject them
  • use your own augmentors and CDI augmentors. Nothing stops you to do new ArrayList<>() then addAll(cdiAugmentors) and addAll(customAugmentors)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @michalvavrik, right, so we have .mechanism(HttpAuthenticationMechanism) right now, so, perhaps we can, to start with, offer .mechanism(HttpAuthenticationMechanism, IdentityProvider), .mechanism(HttpAuthenticationMechanism, IdentityProvider, SecurityIdentityAugmentor), that are typical setup options for custom authentication mechanisms ?

As far as a JPA identity provider is concerned, you have a good point that it is already CDI registered, but I'm thinking it would a bit confusing to users the way it is offered in this PR, if they say want to add it to a custom mechanism dealing with a name and password, seeing a collection, references to CDI, etc.

Perhaps, when it comes to JPA, it, it should be offered in a typed fashion for existing typed basic or form methods or as a single IdentityProvider produced by a JPA IdentityProvider builder.

But what should be offered is a JPA setup, like a DB setup (persistence unit name), as the whole idea of the API is to let users avoid application.properties.

So for example,

.basic().jpa().persistence("orders")..., .form().jpa().persistence("orders")...,

and with the generic method added here,

.mechanism(new MyHttpMechanism(), JpaIdenityProvider().persistence("order").build())

Perhaps something like this...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey, okay, in principle I agree.

.basic().jpa().persistence("orders")..., .form().jpa().persistence("orders")...

that looks nice, but it means we cannot have the same httpSecurity.basic() as we did until now, because it allows you to just continue, e.g. httpSecurity.basic().path(...)... If httpSecurity.basic()....end() has to be ended, it will be bit clumsy. It is really just about lack of ideas how to nicely call it. That is why I kept it like:

httpSecurity.basic(jpa())
# which will allow us to do
httpSecurity.basic(jpa().persistence("abc"))

this way, we have extendability, because HttpSecurity doesn't know anything about JPA Security. I agree that httpSecurity.basic().jpa() looks nice though.

I'll try to produce something along these lines, though unless you suggest some names, we need to have basic(jpa()..).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

basic(jpa().persistence("abc")) looks ok too, so the basic override will take IdentityProvider ? That should be fine and perhaps we can fail early if the identity provider's request type is not UsernamePasswordAuthenticationRequest

Copy link
Member Author

@michalvavrik michalvavrik Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

basic(jpa().persistence("abc")) looks ok too, so the basic override will take IdentityProvider ? That should be fine and perhaps we can fail early if the identity provider's request type is not UsernamePasswordAuthenticationRequest

I think it will take some other trick, it doesn't make sense to have different jpa() static method for form and different for basic auth mechanism. I am starting working on this right now.

@michalvavrik
Copy link
Member Author

I run the OIDC wiremock IT Module tests and they are passing for me locally.

@quarkus-bot
Copy link

quarkus-bot bot commented Nov 28, 2025

Status for workflow Quarkus CI

This is the status report for running Quarkus CI on commit 86e5b6a.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

You can consult the Develocity build scans.

@michalvavrik michalvavrik marked this pull request as draft November 30, 2025 09:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants