Quarkus Security - Use a database for authentication

129 views
Skip to first unread message

Daniel PETISME

unread,
Aug 19, 2019, 8:40:19 AM8/19/19
to Quarkus Development mailing list
Hello folks,

In order to explore Quarkus I'm trying to migrate JHipster Sample App to Quarkus.
For those who don't know JHipster, it's a code generator to produce a Java/Spring Boot Backend and the corresponding Angular/React Web Front.
The Sample App is a classic small/medium CRUD application (nothing fancy). It covers:
- Persistence (and data migration)
- REST API
- Authentication(Database) /Authorization (JWT)
- Log
- Audit
- Application Metrics
- Mailing
- Testing

It's very interesting and useful to spot Quarkus actual limits and difference with Spring Boot.

I'm currently facing a very basic issue: Authentication with a Database.
From I understood currently Keycloack extension permits to delegates Authentication and JWT RBAC extension covers authorization.
This architecture makes sense but looks very limiting. I lover keycloack but not all the application needs/wants to rely the auth. to a 3rd party. A good old fashioned database authentication makes sens in may contexts.

After reading the Quarkus Security Guide, I understand that if I want to rely on a DB for authentication I have to augment the Elytron Security Extension with a Database Realm.

Regarding Quarkus philosophy (microservices/serveless rather than plain old monolith), does it make sense to ask for a Database base security extension?
Is augmenting the Elytron Extension the good way to do it, do you see any road blocker?

Note: JHipster proposes a Keycloack integration (actually I did the first version) so it's more an open question than a blocker.

Loïc MATHIEU

unread,
Aug 19, 2019, 9:22:17 AM8/19/19
to daniel....@gmail.com, Quarkus Development mailing list
Hello,

Elytron supports a database identity manager (https://docs.wildfly.org/14/WildFly_Elytron_Security.html#configure-authentication-with-a-database-identity-store), so yes, in order to do authentication based on a database you must create a new extension that leverage this identity manager.

This should be very close to the extension I made a few weeks ago for bearer token (OAuth2 opaque tokens), so the code should be closed to https://github.com/quarkusio/quarkus/tree/master/extensions/elytron-security-oauth2, you should open an issue if you think it should exist on Quarkus.

In your mail you split authentication (database) and authorization (JWT), in Quarkus I don't think we can authenticate on some way and authorize on an other one ...

Regards,

Loïc

--
You received this message because you are subscribed to the Google Groups "Quarkus Development mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to quarkus-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/33f02323-1112-4233-96a8-c28f39c508f7%40googlegroups.com.

Sergey Beryozkin

unread,
Aug 19, 2019, 9:24:12 AM8/19/19
to daniel....@gmail.com, Quarkus Development mailing list
Hi

At the moment the Keycloak and JWT extensions are two orthogonal options for the users to work with, one can either use KC to authenticate (and authorize AFAIK) or JWT.

The JWT extension is not a complete OIDC/OAuth2 RS adapter, it does not redirect to IDP for example in case of the authentication failures,  it only takes a token from the header, gets it validated (=> authentecation), and (in cooperation with the elytron extension) makes an authorization decision (and AFAIK these mechanics are all going to change somehow, may be someone else can clarify). 
I do plan to take on the issue where the tokens created by the KC adapter are accessible via JWT Api, but it is the most, at least as far as I understand it, what the 'cooperation' between KC and smallrye-jwt can achieve.
Then there is also an Oauth2 extension created by Loic
Sergey


--

Sergey Beryozkin

unread,
Aug 19, 2019, 9:30:01 AM8/19/19
to Loïc MATHIEU, daniel....@gmail.com, Quarkus Development mailing list
Hi Loic,
May be the elytron extension can be enhanced ? The DB storage of the user credentials doe snot in itself introduces a new concept of how the authentication is done, while your extension did (there were some parallels with KC but as well all agreed it was justified)

Thanks, Sergey

Loïc MATHIEU

unread,
Aug 19, 2019, 9:35:01 AM8/19/19
to Sergey Beryozkin, daniel....@gmail.com, Quarkus Development mailing list
@Sergey Beryozkin yes, you are right, I think that it more fits directly inside the elytron-security extension as an alternate identity store in addition witth the existing one from user file and property file ...

So it's a small new feature on the elytron security extension :)

Daniel Petisme

unread,
Aug 19, 2019, 9:53:10 AM8/19/19
to Loïc MATHIEU, Sergey Beryozkin, Quarkus Development mailing list
Hello

Thanks for the fast replies!!

+1 to extend the existing elytron-security. I will create the issue. I'm not (yet) familiar with Elytron but if I can I'll try to propose a PR (except if you think its urgent).

@Loic In the sample app I mention, there is a `/authenticate` endpoint where you provide your credentials and then thanks to Spring Security+a bit of configuration your check if the password of the user matches what is in the database.
If the authentication succeed then a JWT with the user's roles is returned. 

Regarding the authorization, server side, a Filter intercept the incoming requests and convert the token into a Spring Authentication structure (ie. Principal+Roles) finally its set to the current security context (to trigger the annotation mechanism). 
That means the Database is only used for the first authentication/token creation.

From what I saw, we could imagine to extend the Elytron extension with a Database authentication then the developer would be free to do whatever he/she wants like generating a MP-JWT compliant token and then use it as explained in the JWT RBAC guide.

Does it makes sense ?

Loïc MATHIEU

unread,
Aug 19, 2019, 10:19:55 AM8/19/19
to Daniel Petisme, Sergey Beryozkin, Quarkus Development mailing list
@daniel....@gmail.com this is a bit strange but as I understand it you offers an endpoint to generate a JWT token based on a username/password, so you mock an OAuth2 server ... And you configure Spring Security to handle security via JWT but use directly the low level components of Spring Security to "log" a user based on it's login/password in the database. IMHO you should rather use the spring-security-oauth2-server for this ...

The current elytron extension will works with basic authentication OOTB, I think it'll be more easy to use this. Because currently Quarkus doens't support multiple authentication schemes so if you active elytron-security with database authentication you will not be able to use JWT RBAC.

Sergey Beryozkin

unread,
Aug 19, 2019, 10:22:36 AM8/19/19
to Loïc MATHIEU, Daniel Petisme, Quarkus Development mailing list
So JHiptster effectively uses a cookie-based authentication with a cookie being a JWT instance ?

But can the elytron extension deal with the cookie based authentication in general, haven't checked yet (the cookie format can indeed be customized I guess), if yes then it will work with all types of the storage

Thanks, Sergey

Daniel Petisme

unread,
Aug 19, 2019, 10:57:10 AM8/19/19
to Sergey Beryozkin, Loïc MATHIEU, Quarkus Development mailing list
@Loic put it that way it indeed looks like a self-hosted Oauth2 mechanism...

@Sergei client-side the JWT is stored into the local storage and added in the Authorization Header for each request so, is not a pure cookie (despite the persistence aspect).

From what I understand once a identity provider define, either the authentication and the authorization relies on it?

Sergey Beryozkin

unread,
Aug 19, 2019, 11:35:35 AM8/19/19
to Daniel Petisme, Loïc MATHIEU, Quarkus Development mailing list
Hi Daniel

The elytron-security extension does some authentication and the complementing extensions such as the oauth2 or smallrye-jwt one cooperate by helping it to prepare a Principal.
I thought for a second you were expecting the elytron-security to do what JHipster does, prepare a time scoped cookie (as JWT, and on the server), but if JHipster will do it yourself, then
1) enhancing elytron-security to recognize the DB provider
and
2) using the smallrye-jwt extension to validate the token (it will feed the principal info back to the elytron-security once the token has been validated)

is all what you may need to do.

Can JHipster be configured to use the same type of stores which are already supported by elytron-security, just so that you can have a faster POC time ?
The 2) will not work immediately as well - smallrye-jwt does not like the symmetric algorithms as the secret key distribution would be a real issue in the flows it it is trying to address but for cases like this one, may be we can relax it and support the HS algorithms optionally.
Let me us know please If you think that idea of working with smallrye-jwt will work in principle, if yes then I'll try to make sure HS* are supported
The other question, where is the role info in the JWT created by JHipster ?
Cheers, Sergey

Daniel Petisme

unread,
Aug 19, 2019, 2:55:54 PM8/19/19
to Sergey Beryozkin, Loïc MATHIEU, Quarkus Development mailing list
On Mon, Aug 19, 2019 at 5:35 PM Sergey Beryozkin <sbia...@redhat.com> wrote:
Hi Daniel

The elytron-security extension does some authentication and the complementing extensions such as the oauth2 or smallrye-jwt one cooperate by helping it to prepare a Principal.
I thought for a second you were expecting the elytron-security to do what JHipster does, prepare a time scoped cookie (as JWT, and on the server), but if JHipster will do it yourself, then
1) enhancing elytron-security to recognize the DB provider
and
2) using the smallrye-jwt extension to validate the token (it will feed the principal info back to the elytron-security once the token has been validated)

is all what you may need to do.

It's exactly what I want to try. I don't like comparision but Elytron-security is replacing Spring security in this context what is currently made in the sample app will continue to belongs to an end-user application.

Can JHipster be configured to use the same type of stores which are already supported by elytron-security, just so that you can have a faster POC time ?
The 2) will not work immediately as well - smallrye-jwt does not like the symmetric algorithms as the secret key distribution would be a real issue in the flows it it is trying to address but for cases like this one, may be we can relax it and support the HS algorithms optionally.
Not sure to understand this point. Your talking about the JWT key signature? In JHipster is a secret provided to the app, from what I have tested smallrye-jwt relies on an public/private key pair. IMHO, for a POC I can provide a dummy private key for a prod app I don't know yet how to manage that but I think I can figure it out later.
Let me us know please If you think that idea of working with smallrye-jwt will work in principle, if yes then I'll try to make sure HS* are supported
The other question, where is the role info in the JWT created by JHipster ?
JHipster use uses a custom "auth" claim to store a comma-joined list of role
MP-JWT is asking for a specific "groups" claim
The easiest way to deal with this point is to merge JHipster and MP-JWT constraints (having both "groups" and "auth" claim). Another way would be to transform the claim on-the-fly (via a filter, it's what I do with a Asp.Net Core Identity, yes... in .Net ;-D) expose "auth" to be compliant with Jhipster generated front-end and translate it into "groups" before MP-JWT needs it.

I think both of you answered the original question. I will create the "elytron-security  DB provider" feature request to continue the discussion.

Thank you!

Sergey Beryozkin

unread,
Aug 19, 2019, 5:35:59 PM8/19/19
to Daniel Petisme, Loïc MATHIEU, Quarkus Development mailing list
Hi,

On Mon, Aug 19, 2019 at 7:55 PM Daniel Petisme <daniel....@gmail.com> wrote:

On Mon, Aug 19, 2019 at 5:35 PM Sergey Beryozkin <sbia...@redhat.com> wrote:
Hi Daniel

The elytron-security extension does some authentication and the complementing extensions such as the oauth2 or smallrye-jwt one cooperate by helping it to prepare a Principal.
I thought for a second you were expecting the elytron-security to do what JHipster does, prepare a time scoped cookie (as JWT, and on the server), but if JHipster will do it yourself, then
1) enhancing elytron-security to recognize the DB provider
and
2) using the smallrye-jwt extension to validate the token (it will feed the principal info back to the elytron-security once the token has been validated)

is all what you may need to do.

It's exactly what I want to try. I don't like comparision but Elytron-security is replacing Spring security in this context what is currently made in the sample app will continue to belongs to an end-user application.

Can JHipster be configured to use the same type of stores which are already supported by elytron-security, just so that you can have a faster POC time ?
The 2) will not work immediately as well - smallrye-jwt does not like the symmetric algorithms as the secret key distribution would be a real issue in the flows it it is trying to address but for cases like this one, may be we can relax it and support the HS algorithms optionally.
Not sure to understand this point. Your talking about the JWT key signature? In JHipster is a secret provided to the app, from what I have tested smallrye-jwt relies on an public/private key pair. IMHO, for a POC I can provide a dummy private key for a prod app I don't know yet how to manage that but I think I can figure it out later.
The code I looked at earlier uses HS256 as far as I recall; smallrye-jwt only allows asymmetric RS and lately - ES signature algorithms. So unless I'm missing something it needs a bit of work to allow working with the HS* algorithms, but we can sort it out if it will be required 
 
Let me us know please If you think that idea of working with smallrye-jwt will work in principle, if yes then I'll try to make sure HS* are supported
The other question, where is the role info in the JWT created by JHipster ?
JHipster use uses a custom "auth" claim to store a comma-joined list of role
MP-JWT is asking for a specific "groups" claim
The easiest way to deal with this point is to merge JHipster and MP-JWT constraints (having both "groups" and "auth" claim). Another way would be to transform the claim on-the-fly (via a filter, it's what I do with a Asp.Net Core Identity, yes... in .Net ;-D) expose "auth" to be compliant with Jhipster generated front-end and translate it into "groups" before MP-JWT needs it.

Right, Loic did it right and in the OAuth2 extension, when dealing with the 'scope' which has the similar structure, it is not tied to the name of the claim, smallrye-jwt can map from the structurally equivalent custom claim containing the roles and 'groups', but for the 'scope' I took a shortcut and extract the roles from a comma-separated value only if it is 'scope', but it can be easily tweaked.
I think both of you answered the original question. I will create the "elytron-security  DB provider" feature request to continue the discussion.

Thanks, Sergey
Reply all
Reply to author
Forward
0 new messages