I havea Quarkus Java application. It serves my GraphQL API.
I would like to authenticate requests with JsonWebTokens (JWT). I know that smallrye-graphql already has some built-in JWT functionality. But I need to extend that. I need to add a custom role to authenticated users and other customizations.
How can I tap into that? According to this Quarksu-Security documentation I tried to implement my own HttpAuthenticationMechanism
.
I have questions. See comments in code:
@Alternative
@Priority(1) // <======= io.quarkus.arc.Priority or javax.annotation.Priority ???????
@ApplicationScoped
public class MyCustomAuthMechanism implements HttpAuthenticationMechanism {
@Override
public Uni<SecurityIdentity> authenticate(RoutingContext context, IdentityProviderManager identityProviderManager) {
// ==========================
// This is what i am trying to archive. But this whole method is never called ???
// ==========================
QuarkusSecurityIdentity user = QuarkusSecurityIdentity.builder().addRole("CUSTOM_USER").build();
// This would be nice if it would be possible to access the JWT directly
//context.request().getHeader(HttpHeaderNames.AUTHORIZATION);
return Uni.createFrom().item(user);
}
@Override
public Uni<ChallengeData> getChallenge(RoutingContext context) {
return Uni.createFrom().item(new ChallengeData(HttpResponseStatus.UNAUTHORIZED.code(), HttpHeaderNames.AUTHORIZATION, null)); // <====== is this correct? What to return here?
}
@Override
public Set<Class<? extends AuthenticationRequest>> getCredentialTypes() {
// This is called, but this seems to be the problem? What to return here?????
return Collections.singleton(TokenAuthenticationRequest.class);
}
}
Thank you very much for any advice or even better example code. (ChatGPT has some, but very old outdated versions :-)
Or to phrase my question in a more general way: My client will send HTTP reqests with a "Authorization: Bearer ...JWT...data..." header. That JWT is signed and contains information that I need in the backend. What's the easiest way to fetch that information in Quarkus GraphQL ?
Update 1
Tried another way. Without any custom class or anythign. Just default as described by Quarkus docs.
application.properties
Do I need to set only one or both of these properties???
smallrye.jwt.sign.key.location=META-INF/resources/jwtKey.json
smallrye.jwt.verify.key.location=META-INF/resources/jwtKey.json
META-INF/resources/jwtKey.json
{
"keys": [
{
"kty":"oct",
"kid":"secretKey",
"k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0ga............Zr1Z9CAow"
}
]
}
And I create my JWT like this:
String JWT = Jwt.issuer("my_site")
.subject("TestUser11@liquido.vote")
.upn("upn@liquido.vote")
.groups(Collections.singleton("LIQUIDO_USER"))
.sign()
My GraphQL @Query
is simply annotated with @Authenticated
. But I get the error:
ERROR [io.sma.graphql] (vert.x-eventloop-thread-1) SRGQL012000: Data Fetching Error: io.quarkus.security.UnauthorizedException
Thanks for any hints or suggestions.