Search code examples
quarkusquarkus-jpa

Using a custom identity provider in Quarkus


In my current project, we store user login info inside a MongoDB collection. We would like to implement an authentication mechanism that checks the credentials from a request against the information stored in said MongoDB. There is a tutorial for doing this with JPA + Postgres but there is no information on using MongoDB in the same capacity. I suspect that I would need to write a custom IdentityProvider for this case. I tried using the JPA identity provider as a base, but it looks like the security-jpa source code contains only an abstract identity provider, while the actual provider is generated automatically using black magic. Has anyone ever had success adapting the existing Quarkus security architecture to MongoDB or anything else that is not covered by security-jpa?


Solution

  • After some research, I was able to get a custom IdentityProvider to work. Here's a very simple demo (without any MongoDB logic):

    @ApplicationScoped
    public class DemoIdentityProvider implements IdentityProvider<UsernamePasswordAuthenticationRequest> {
        private static final Map<String, String> CREDENTIALS = Map.of("bob", "password124", "alice", "hunter2");
    
        @Override
        public Class<UsernamePasswordAuthenticationRequest> getRequestType() {
            return UsernamePasswordAuthenticationRequest.class;
        }
    
        @Override
        public Uni<SecurityIdentity> authenticate(UsernamePasswordAuthenticationRequest request,
                                                  AuthenticationRequestContext authenticationRequestContext) {
            if (new String(request.getPassword().getPassword()).equals(CREDENTIALS.get(request.getUsername()))) {
                return Uni.createFrom().item(QuarkusSecurityIdentity.builder()
                    .setPrincipal(new QuarkusPrincipal(request.getUsername()))
                    .addCredential(request.getPassword())
                    .setAnonymous(false)
                    .addRole("admin")
                    .build());
            }
            throw new AuthenticationFailedException("password invalid or user not found");
        }
    }
    

    Note that in order to access QuarkusSecurityIdentity, the quarkus-security extension needs to be included as dependency in pom.xml:

    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-security</artifactId>
    </dependency>
    

    Furthermore, quarkus.http.auth.basic=true needs to be added to application.properties for the identity provider be used with basic auth.