tlegrand
tlegrand

Reputation: 806

Use of @RolesAllowed and Pac4J

My application is currently protected by BASIC authentication configured by the web.xml descriptor. It contains a REST API with resources protected by the annotation @RolesAllowed. The users are stored in a simple SQL database which is used in a Realm configured on Payara.

My goal is to try to reimplement this authentication part with pac4j.

For the moment, I configured a DirectBasicAuthClient with my custom Authenticator which lookup for a IdentityStoreHandler to validate the credentials:

@Dependent
public class SecurityConfig {

    @Produces @ApplicationScoped
    private Config buildConfiguration() {
        final DirectBasicAuthClient directBasicAuthClient = new DirectBasicAuthClient(new MyAuthenticator());
        directBasicAuthClient.setRealmName("MyRealm");
        final Clients clients = new Clients(directBasicAuthClient);

        return new Config(clients);
    }

    public static final class MyAuthenticator implements Authenticator {
        @Override
        public void validate(Credentials credentials, WebContext context, SessionStore sessionStore) {
            var userNamePasswordCredentials = (UsernamePasswordCredentials) credentials;
            var identityStoreHandler = CDI.current().select(IdentityStoreHandler.class, new Annotation[0]).get();
            CredentialValidationResult result = identityStoreHandler.validate(new UsernamePasswordCredential(userNamePasswordCredentials.getUsername(), userNamePasswordCredentials.getPassword()));
            if (result.getStatus() == CredentialValidationResult.Status.INVALID) {
                throw new CredentialsException("Nope nope nope.");
            }

            BasicUserProfile userProfile = new BasicUserProfile();
            userProfile.setId(result.getCallerPrincipal().getName());
            var roles = new HashSet<>(result.getCallerGroups());
            roles.add("ADMIN"); // temporary for test purpose
            userProfile.setRoles(roles);
            credentials.setUserProfile(userProfile);
        }
    }
}

In debug mode, when I access to my protected REST API resource, the validation of the credentials works (MyAuthenticator#validate) but I receive a 401 Unauthorized. I suspect it is because pac4j does not update the security context. And I fail to see how I could make it do it in order to make the @RolesAllowed annotation work when I try to access to my protected REST resource.

The dependencies I use are:

My questions:

Upvotes: 1

Views: 245

Answers (1)

jleleu
jleleu

Reputation: 2699

I was expected it to work.

When using the pac4j SecurityFilter, the authenticated user is saved: https://github.com/pac4j/jee-pac4j/blob/master/javaee-pac4j/src/main/java/org/pac4j/jee/filter/SecurityFilter.java#L84 as the JEE principal: https://github.com/pac4j/jee-pac4j/blob/master/javaee-pac4j/src/main/java/org/pac4j/jee/util/Pac4JHttpServletRequestWrapper.java

I haven't tested, but I thought that the isUserInRole method was used by the @RolesAllowed annotation.

Can you debug what is tested by the @RolesAllowed annotation? Thanks

Upvotes: 1

Related Questions