3 Replies Latest reply on Nov 1, 2016 4:00 AM by mkouba

    Inject custom security principal (via login module)

    mimra

      Hello

       

      I am part of a team developing a thin framework to provide some basic JavaEE features for you applications (web & ejb).

      Part of this framework includes a custom Wildfly login module, which createa a custom implementation of the java.security.Principal class.

      This principal is made available in the container for applications to access once authenticated.

       

      Inside the application code, I would like to be able to do:

       

      @Inject

      java.security.Principal principal;

       

      which would inject the principal set by our custom login module.

       

      Now this all works very well, except that the class injected by the CDI container is off course a proxy.

       

      Despite all Google suggestions, I have found no way to access the actual class instance (the custom Principal implementation) behind the bean proxy.

      I need this to access a custom getter method.

       

      Is there anyway to either access the underlying instance or invoke a method, not part of the exposed interface - portable or even Weld specific?

       

      I have looked at:

       

      https://issues.jboss.org/browse/CDI-10?page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel&showAll=true&_sscc=t

       

      There is a comment from Mark Struberg on how to do this using the BeanManager. I have tried this using:

       

      Context ctx = beanManager.getContext(RequestScoped.class);

      Set beans = beanManager.getBeans(Principal.class, new AnnotationLiteral<Default>(){});

      Bean bean = beanManager.resolve(beans);

      Object instance =  ctx.get(bean);

       

      However, ctx.get(bean) returns null.

       

      The custom login module works - I can do:

       

      Principal principalFromHttpServletRequest = httpServletRequest.getUserPrincipal();

       

      which returns the actual custom principal implementation.

       

      I would however like to have the principal injetced without having to call getUserPrincipal / getCallerPrincipal.

       

      Any help is very welcome.

       

      Thanks

      Michael

        • 1. Re: Inject custom security principal (via login module)
          mkouba

          Hi Michael,

          the built-in Principal bean is @Dependent in Weld, that's why ctx.get(bean) from your sample returns null. Also note that the injected reference is not a "normal" client proxy, but an "EE component proxy". So even if you get the context object for @Dependent and call get() you'll get the proxy. AFAIK there is no way to obtain the instance behind an "EE component proxy". The only thing you could probably do is to register a custom bean for your principal, i.e. with some special qualifier. This bean's create() method could delegate to the Weld specific org.jboss.weld.security.spi.SecurityServices.getPrincipal() or directly to some WildFly internals.

          • 2. Re: Inject custom security principal (via login module)
            mimra

            Hi Martin

             

            First of all - thank you for your time.

            I had a feeling this could be a problem :-)

            The only way we have found, is to access the service registry from the bean manager, then get the SecurityService and then call getPrincipal() - just like you describe.

             

            This does however become very JBoss / Weld specific. I don't know what the SecurityService does.

            Would the same approach work inside an EJB, for example?

             

            Thank.

            Michael

            • 3. Re: Inject custom security principal (via login module)
              mkouba

              SecurityServices is a Weld SPI that allows integrators (WildFly in this case) to provide the Principal representing the current caller identity. FYI there is already a spec issue for this problem: CDI-597. Feel free to add comments.