Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add authentication mechanism for JWT #255

Open
hantsy opened this issue Jul 24, 2022 · 12 comments
Open

Add authentication mechanism for JWT #255

hantsy opened this issue Jul 24, 2022 · 12 comments

Comments

@hantsy
Copy link

hantsy commented Jul 24, 2022

Combine the effort of Microprofile JWT, and provides a standard JWT authentication mechanism for Http, WebSocket.

Mainly used in a ResoruceServer oauth2 role, provides one of the following config to decode JWT.

  • issuerUri
  • jwksUri
  • publicKey location or value
@arjantijms
Copy link
Contributor

This was in scope for Jakarta Security 3.0, but we didn't had time to look at this. Note that quite a few servers do actually implement MicroProfile JWT using Jakarta Security. See e.g. https://github.com/omnifaces/jwt

I brought up this topic a couple of times, but despite EE & MP alignments, it's still not 100% clear how to go about doing this. There is a vague notion about this in the MP specs already, but I personally feel it's not clear enough.

I would like some wording such as the following in the MP JWT spec:

"In a Jakarta EE environment, the runtime MUST make the JWT functionality available via an HTTPAuthenticationMechanism, and it MUST use the LoginConfig annotation to make this HTTPAuthenticationMechanism available as an enabled CDI bean"

From the reverse side, I'm not yet sure what wording or process to use for EE to "import" the actual MP JWT spec.

@hantsy
Copy link
Author

hantsy commented Jul 25, 2022

I would like use the OAuth 2 role name to define the spec, it is easy to apply them in different scenes. For example.

  • OAuth2Client or OidcClient, support OAuth 2.1 spec, support basic authorization code, client credentials, device code flow, (ignore resource owner password and implicit flow which are not recommended due to security issues). This mechanism is used in a general web application(eg. Faces, MVC, Servlet), gateway application or API client in an application( manually use client credentials to communicate with other APIs).
  • ResourceServer, supports both JwtToken and OpaqueToken, mainly used in a backend API application to protect APIs.
  • AuthenticationServer, for Jakarta EE specs, we do not need to implement an AuthenticationServer role, the existing IDP providers fill the blank.

@arjantijms
Copy link
Contributor

We should start the discussion and some prototyping of this soon. But as mentioned, if we want/need to directly import the MP spec into EE we probably have to do some cross platform discussion between EE and MP.

@amoscatelli
Copy link

So, the JWT authentication mechanism would simply validate a json web token, did I get it correctly ?

Like the OpenIdAuthenticationDefinition without the redirect behaviour ?

@keilw
Copy link
Member

keilw commented Nov 30, 2022

@arjantijms The above discussion already happens, but the question is, would we need anything JWT specific HERE (in the Security Spec / API) or would Soteria be suffient?
There something along the lines of omni-jwt sounds reasonable and there is no big issue to use e.g. Microprofile-JWT while using the MP API here bares the risk of cyclic dependencies which must be avoided.

@amoscatelli
Copy link

@keilw I believe a @JWTAuthenticationMechanismDefinition would be a good addition to the spec, independently from the already working implementations based on the current API.

Similarly to the OpenIdAuthenticationDefinition, it should also have a property for extracting the principal name from the decoded jwt.

@keilw
Copy link
Member

keilw commented Nov 30, 2022

@amoscatelli If we added an annotation like that it would make using MP JWT especially for its @Claim annotation pretty useless. The Claims enumeration has a very similar purpose to the OpenIdConstant collection here, so we could have something along the lines of JwtConstant or similar. With that only the actual JWT would be missing, which could either be done in the implementation or by using the CallerPrincipal because MP JWT's JsonWebToken is merely an extension to the standard JDK Principal as well.

@hantsy
Copy link
Author

hantsy commented Dec 1, 2022

I am little confused about the annotation naming of OpenIdAuthenticationDefinition, OpenId is an old protocol and deprecated now, OpenIdConnect is the exact feature defined in OpenIdAuthenticationDefinition.

I would like add the OAuth2 role to recognize this annotation naming.

  • OAuth2ClientAuthenticationDefinition(support both OpenIdConnect and the raw OAuth 2.1)
  • OAuth2ResourceServerAuthenticationDefinition(support both JWT and Opaque Token introspection )

@amoscatelli
Copy link

@amoscatelli If we added an annotation like that it would make using MP JWT especially for its @Claim annotation pretty useless. The Claims enumeration has a very similar purpose to the OpenIdConstant collection here, so we could have something along the lines of JwtConstant or similar. With that only the actual JWT would be missing, which could either be done in the implementation or by using the CallerPrincipal because MP JWT's JsonWebToken is merely an extension to the standard JDK Principal as well.

Thank you, I missed MP JWT.

Does MP JWT work for Servlet/SOAP/WebSocket too ?

@amoscatelli
Copy link

It seems so, it should provide an authentication mechanism ! good to know

@arjantijms
Copy link
Contributor

See: https://docs.google.com/document/d/1YEcAQLvGLqATJhnARbi6lKoBS1B0K2Ma_ogYgq2C-eI/edit#

@hantsy
Copy link
Author

hantsy commented Mar 16, 2023

I would like move MP JWT to Jakarta Security, and refactor it with Jakarta Security APIs, and deprecated MP JWT at the same time.

And in the existing MP JWT, I do not think upn and groups is required.

  • sub is a good placement of upn.

  • Use a custom claimsDefinition = @ClaimsDefinition(callerGroupsClaim = "http://www.jakarta.ee/roles")(existed in the OpenIDConnect authentication) to map custom claims to groups directly.

  • Additionally I hope provide an alternative converter bean @ClaimsDefinition(callerGroupsClaimConverter = "${myConverter}") to convert claims to security context groups.

    @ApplicationScope
    @Named("myConverter")
    class MyConverter implements Converter<Claims, Set<String>>{
        public Set<String> convert(Claims claims){
            // Jakarta Security apply the converters and 
            // set groups to the current pricipal
        }  
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants