Skip to content

Get the authenticated user profiles

LELEU Jérôme edited this page Sep 9, 2020 · 1 revision

When using Jersey or Resteasy as the JAX-RS runtime, it is possible to directly inject a pac4j profile or profile manager using method parameters injection. When using another JAX-RS runtime, see below for workarounds.

Using method parameters injection

You can get the profile of the authenticated user using the annotation @Pac4JProfile like so:

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Pac4JSecurity(authorizers = "isAuthenticated")
    public UserData getUserData(@Pac4JProfile CommonProfile profile) {
        // profile can't be null
        LOG.debug("Returning infos for {}", profile.getId());

        return new UserData(profile.getId(), profile.getDisplayName());
    }

It is also possible to inject a optional CommonProfile like so:

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public UserData getUserData(@Pac4JProfile Optional<CommonProfile> profile) {
        if (profile.isPresent()) {
            LOG.debug("Returning infos for {}", profile.getId());

            return new UserData(profile.getId(), profile.getDisplayName());
        } else {
            throw new WebApplicationExcpotion(401);
        }
    }

You can also get the profile manager (which gives access to more advanced information about the profile) using the annotation @Pac4JProfileManager like so:

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public UserData getUserData(@Pac4JProfileManager ProfileManager<CommonProfile> profileM) {

        final CommonProfile profile = profileM.get(true).get();

        LOG.debug("Returning infos for {}", profile.getId());

        return new UserData(profile.getId(), profile.getDisplayName());
    }

You can test if the user is authenticated using profileManager.isAuthenticated(). You can get all the profiles of the authenticated user (if ever multiple ones are kept) using profileManager.getAll(true).

The retrieved profile is at least a CommonProfile, from which you can retrieve the most common attributes that all profiles share. But you can also cast the user profile to the appropriate profile according to the provider used for authentication. For example, after a Facebook authentication:

FacebookProfile facebookProfile = (FacebookProfile) commonProfile;

or even:

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public UserData getUserData(@Pac4JProfile FacebookProfile profile) {
        LOG.debug("Returning infos for {}", profile.getId());

        return new UserData(profile.getId(), profile.getDisplayName());
    }

Without method parameters injection

Other solutions involves:

  • retrieving the SecurityContext and casting it to Pac4JSecurityContext to access the profiles.
  • retrieving the SecurityContext and casting it to Pac4JSecurityContext to access the JaxRsContext.
  • retrieving the JaxRsContext in order to instantiate a JaxRsProfileManager.

To retrieve the Pac4JSecurityContext or the JaxRsContext, see JerseyResource.java or RestEasyResource.java for examples.

Worst case scenario, when using a JAX-RS runtime running on top of a Servlet container, it is always possible to simply exploit the HttpServletRequest as explained there:

    @GET
    public void get(@Context HttpServletRequest request) {
        ProfileManager manager = new ProfileManager(new J2EContext(request, null));
        Optional<CommonProfile> profile = manager.get(true);
    }