quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.56k stars 2.62k forks source link

[Extension Proposal] Zenei authentication extension #42640

Closed zZHorizonZz closed 4 days ago

zZHorizonZz commented 3 weeks ago

Description

Interested in this extension, please +1 via the emoji/reaction feature of GitHub (top right).

Hey there! Recently, I have found myself deciding on what to use for my projects for authorization. Quarkus has a basic extensions, like elytron security extension that gives you free rein, but this can get quite tedious after some time. On the flip side, there are full-blown auth services like Clerk or Supabase, or auth apps like Keycloak. My apps are mostly on the smaller side, so I'm not keen on adding another service or creating dependencies. And since I couldn't find an extension that would fit my needs, I built my own. It handles basic credentials or OAuth with some basic providers (Discord, Github, Google, with more coming in the future), and if you're authorized, you get access and refresh tokens. Down the line, I'm thinking of adding organizations, API keys, webhooks, and maybe some other handy features.

Currently, the repository consists of the following extensions:

Repository name

quarkus-zenei

Short description

Quarkus extensions for user authentication and authorization.

Repository Homepage URL

https://github.com/Cloudeko/cloudeko-zenei/tree/master/extensions

Repository Topics

Team Members

Additional context

The extension is currently under heavy development as I initially made an app, but now I'm moving most of the functionality to the extensions.

Also, this extension currently uses MapStruct and Lombok, which I didn't find any information on the Quarkus team's posture on these depedencies. I don't mind removing dependency on these if necessary.

quarkus-bot[bot] commented 3 weeks ago

/cc @aloubyansky (extension-proposal), @gastaldi (extension-proposal), @gsmet (extension-proposal), @maxandersen (extension-proposal)

aloubyansky commented 3 weeks ago

@sberyozkin fyi

sberyozkin commented 3 weeks ago

Thanks, looks like an interesting project, though it appears to build some kind of alternative security architecture, with specific support for selected OAuth2 providers (FYI, all of those mentioned are supported in Quarkus indirectly via a collection of general OIDC properties, for example, quarkus.oidc.provider=discord, etc), and with the IAM ideas like organization which is what Keycloak is doing.

But let's see how it evolves. Thanks

zZHorizonZz commented 3 weeks ago

though it appears to build some kind of alternative security architecture

Could you explain what you mean by "alternative security architecture"? If there is something wrong or non-standard, I appreciate any feedback.

with specific support for selected OAuth2 providers

Yes, basically the problem with some providers is that they have their own unique responses when you want to retrieve data for a specific user. For example, GitHub has an endpoint for user information, but then you also need to call the emails endpoint to get information about the user's emails.

But let's see how it evolves.

I will give you a heads up when it's completely migrated to extensions, as currently, the actual endpoints still need to be converted to the their own rest extension.

Also, I have two questions related to extensions:

  1. This extension currently uses MapStruct and Lombok, which I didn't find any information on the Quarkus team's posture on these dependencies. I don't mind removing dependencies on these if necessary.

  2. Is this type of extension within the goals of Quarkiverse extensions? As it's at least partly opinionated on data models.

sberyozkin commented 3 weeks ago

@zZHorizonZz

Could you explain what you mean by "alternative security architecture"? If there is something wrong or non-standard, I appreciate any feedback.

There is nothing wrong with what you try to innovate with, it is just that all of it seems to be already supported in Quarkus, with its own security architecture, where users can for ex, combine Basic and OIDC authentication, etc. This is why I mentioned alternative, but not in a negative way

Yes, basically the problem with some providers is that they have their own unique responses when you want to retrieve data for a specific user. For example, GitHub has an endpoint for user information, but then you also need to call the emails endpoint to get information about the user's emails.

This is all taken care of easily on Quarkus as we speak, out of the box: https://quarkus.io/guides/security-openid-connect-providers, you get most of the required info in the injected UserInfo object with providers like GitHub, and can customize things easily and use OIDC token propagation to fetch more user specific content. But again, I'm not about to try to prove what you do is not necessarily, you have own vision how you want to do it, so please keep experimenting, which is what I meant by let's see how it evolves

zZHorizonZz commented 3 weeks ago

but not in a negative way

I didn't take it in a negative way at all. I genuinely didn't understand how you meant it 😄, that's all. Anyway, I'm all in for any and all feedback. 👍

This is all taken care of easily on Quarkus as we speak, out of the box: https://quarkus.io/guides/security-openid-connect-providers, you get most of the required info in the injected UserInfo object with providers like GitHub, and can customize things easily and use OIDC token propagation to fetch more user specific content.

I didn't think of this extension at all, to be honest, I forgot about it. Anyway, I think I will stay with the extension I wrote for now and see what comes out of it.

gbourant commented 3 weeks ago

That's an interesting project, i'm building something similar with Quarkus + Renarde inspired by https://bullettrain.co/ which support organizations/teams https://blog.bullettrain.co/teams-should-be-an-mvp-feature/

sberyozkin commented 3 weeks ago

@gbourant Organizations are supported at the Keycloak level as well: https://www.keycloak.org/2024/06/announcement-keycloak-organizations

zZHorizonZz commented 2 weeks ago

@sberyozkin I'm thinking that I could separate the token creation and storage into its separate extension(s). The idea is you'd call something like createToken, and it would return a Token object containing all the important details (I would like to also provide some other methods like revokeToken, swapToken, etc, the idea is to provide a possibility to create a jwt access token which you wouldn't be obviously able to revoke, but if there was any other type of token which is for example stored somewhere you would be able to do that)

public class Token {
    private String accessToken;
    private String tokenType;
    private int expiresIn;
    private String refreshToken;

   /* REST OF THE CODE */
}

I'm thinking this could be a standalone extension since I haven't found one that handles token management directly within the application. I did come across the OAuth Elytron extension, but it needs an external auth server.

My plan is to create two extensions:

  1. One handling the core logic and providing a TokenStorageProvider interface for storage like implementations like database implementation, etc.
  2. Another implementing the database part for SQL databases for now, similar to how the oidc-db-token-state-manager-extension does it.

Hopefully, I explained it in the way it makes sense. I just wanted to check if you know, if there's an existing extension that does something similar, so I don't end up reinventing the wheel.

sberyozkin commented 2 weeks ago

@zZHorizonZz As I said, you are welcome to experiment, it is that right now I'm not certain what your proposed extension can do which can not already be done in Quarkus. We have tools for managing tokens using various grants with OIDC and OIDC client extensions. But really, it does not matter, please proceed with your Quarkiverse extension plan, experiment, let's see how it evolves, good luck. Thanks

zZHorizonZz commented 4 days ago

As I go further through it, I'm figuring out stuff which I didn't think of when I started writing this extension. For example, I have found out that there is an Elytron extension for access tokens, and, like you mentioned, there is already an OIDC extension for auth providers. But at the same time, I don't find any extension which would provide the type of authentication I would like to use, e.g., a combination of access and refresh tokens where the access token is a JWT and the refresh token is stored in the database and can be revoked. I will probably back away (for now) from the plan of creating the extension I described in the issue as I first and foremost need to figure out the best way of how to combine/create the extension which would handle oauth the way I want. I might reopen this issue in the future, or I will create new one if I come up with the oauth extension I described.