Context injected SecurityContext is null

10,009

As stated in my comment

SecurityContext is a JAX-RS component and can only be injected into other JAX-RS component. All you have is a CDI bean. You can try to make it an EJB and inject SessionContext. See Securing an Enterprise Bean Programmatically

Haven't tested but seems to work for the OP. This is a EE stack solution.

Another JAX-RS (Resteasy specific) way to allow for injection is with the help of the ResteasyProviderFactory (found with help from this answer). You could use this in a ContainerRequestFilter, which has access to the SecurityContext. We can use the RESTeasy utility class to push the User into the context. This allows for injection with the @Context annotation. Not sure how/if it would work with a custom annotation though. Here's an example

@Provider
public class UserContextFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext context) throws IOException {
        SecurityContext securityContext = context.getSecurityContext();
        String username = securityContext.getUserPrincipal().getName();

        ResteasyProviderFactory.pushContext(User.class, new User(username));
    }  
}

Note: this is a JAX-RS 2.0 solution (i.e. RESTeasy 3.x.x). Prior to 2.0, there is no ContainerRequestFilter

Share:
10,009
dermoritz
Author by

dermoritz

Updated on June 04, 2022

Comments

  • dermoritz
    dermoritz almost 2 years

    I have created a Javae EE app using JAX-RS 2.0 and JPA. I created a special provider of my User entity (using Qualifiers) to provide the current user (logged in) as entity from applications user database. To get current user i use

    @Context
    private SecurityContext secContext;
    

    The problem is that this is null. The security is setup fine (Wildfly 8.2) - the app asks for Authentication (basic) but SecurityContext is null. Here is the code:

    @RequestScoped
    public class CurrentUserProducer implements Serializable {
    
        /**
         * Default
         */
        private static final long serialVersionUID = 1L;
    
        @Context
        private SecurityContext secContext;
    
        /**
         * Tries to find logged in user in user db (by name) and returns it. If not
         * found a new user with role {@link UserRole#USER} is created.
         * 
         * @return found user a new user with role user
         */
        @Produces
        @CurrentUser
        public User getCurrentUser() {
            if (secContext == null) {
                throw new IllegalStateException("Can't inject security context - security context is null.");
            //... code to retrieve or create new user
            return user;
        }
    
    }
    

    As you see I check secContext for null and i see my exception as soon as i try to reach a resource that injects @CurrentUser.

    So how to fix this? Why is SecurityContext null.