1 Reply Latest reply on Oct 8, 2013 9:37 AM by nmoelholm

    How to login programmatically from inside the JBoss 7 server?

    nmoelholm

      Hi guys,

       

      I have some code that needs to login programmatically.

       

      The code is running inside the application server in a thread that isn't managed by JBoss AS. It is neither a Web container thread, an EJB thread etc...And it isn't a remote client either...

       

      From this unmanaged thread, I need to authenticate (login) to the server, just before an EJB method is invoked. And then logout immediately after again. <-- How can I do that?

       

      Pseudo code:

      class UnmanagedThread {
      
          public void invokeEjb() {
      
               // <Code here> :: Authenticate with usr+password
      
                Ejb e = grabMyEjb();
      
                e.printUserPrincipalToStdout();
      
          }
      
      }
      
      

       

      To be precise: I would loove to find something similar to HttpServletRequest.login( userName , userPassword ) .... does that exist in JBoss AS 7.2 ?

       

      -- I need to present a userName and a password to the login mechanism. So that the container will run the LoginModules authentication process appropriately )

       

      ( I am upgrading JBoss 5 code to JBoss 7.2 code. The old code used a "new InitialContext()" approach with the org.jboss.security.jndi.JndiLoginInitialContextFactory class as factory value. This trick doesn't seem to work anymore.  )

      ( Oh - I tried google before writing this entry .... but this time it didn't help much unfortunately )

       

      Looking forward to get some input here

       

      /Nicky

        • 1. Re: How to login programmatically from inside the JBoss 7 server?
          nmoelholm

          I have something working now.

           

          Not quite sure if it is "best practice". What do you say (broadcast question ) ?

           

          So ... this is how I run an EJB method under another principal:

           

            
                  runAs("other", "duke", "duke123!", new PrivilegedAction<Void>() {
                      @Override
                      public Void run() {
                          friendService.ping(); // EJB invocation ( Inside it it knows about the correct duke principal )
                          return null;
                      }
          
                  });
          

           

          The ping() method is secured with @RolesAllowed("ONLY_JAVA_LOVERS"). It ensures that the EJB cannot be invoked with the anonymous principal etc.

           

          …and a peak into the runAs method:

           

                private void runAs( String securityDomain, String userName, String password, PrivilegedAction<Void> action) {
                  SecurityContext originalSecurityContext = SecurityContextAssociation.getSecurityContext();
                  try {
                      // Perform programmatic login
                      LoginContext ctx = new LoginContext(securityDomain, new UsernamePasswordHandler(userName, password.toCharArray()));
                      ctx.login();
          
                      // Bind principal/subject to the current thread
                      SecurityContext sc = SecurityContextFactory.createSecurityContext(securityDomain);
                      sc.getUtil().createSubjectInfo(ctx.getSubject().getPrincipals().iterator().next(), password, ctx.getSubject());
                      SecurityContextAssociation.setSecurityContext(sc);
          
                      // Run the action with the new login details
                      Subject.doAs(ctx.getSubject(), action);
                  } catch (Exception e) {
                      throw new RuntimeException(e);
                  } finally {
                      SecurityContextAssociation.setSecurityContext(originalSecurityContext);
                  }
          
              }
          

           

          The code doesn't work without lines 9+10+11. So this is the nasty part I guess: manually binding stuff to the thread. Lines 02+18 is there just to compensate.....

          Also, without Subject.doAs (line 14) the EJB container rejects to invoke the method due to authorization issues.

           

          Community - let me know if this can be done better,

           

          Thanks,

          Nicky