6 Replies Latest reply on May 19, 2014 9:31 AM by dward

    Providing getCallerPrincipal() and isCallerInRole(String)


      SWITCHYARD-2031 requests the ability to offer high-level security context information to applications via the public SY api.

      I wanted to have a little fun tonight, so I took a quick stab at it, and would like some feedback.


      First thing I did was think about what other APIs do this, and what they provide.   Luckily, there are 2 very similar, and very popular examples out there:


      HttpServletRequest provides the 2 methods: getUserPrincipal():Principal and isUserInRole(String):boolean.

      EJBContext provides the 2 methods: getCallerPrincipal():Principal and isCallerInRole(String):boolean.


      So, I figured let's do the same thing in SwitchYard, and I chose "Caller" vs. "User" in the method names, and placed them right on org.switchyard.Exchange.


      Here is the code in core that had to be added (very little):



      And here is an example of using that information in an application (very easy):



      Running the above quickstart gives this output (trimmed slightly for this discussion):

      INFO  [WorkServiceBean] :: WorkService :: Received work command => CMD-1396416779778

      INFO  [WorkServiceBean] :: WorkService :: from CallerPrincipal => kermit

      INFO  [WorkServiceBean] :: WorkService :: with role "friend"? => true

      INFO  [WorkServiceBean] :: WorkService :: with role "enemy"? => false


      What do people think of the 2 new methods being right on the org.switchyard.Exchange?  I hesitate to add a new "SecurityContext" interface into that api package, as we already have one in the org.switchyard.security.context, albeit not for public use.  At the moment, I can't see anything more than those 2 methods needed to be added to the public API.  I mean, it was good enough for the Servlet and EJB specs.... Aren't those 2 methods good enough for us too?




        • 1. Re: Providing getCallerPrincipal() and isCallerInRole(String)

          These two methods would be ideal for RTGov, so they get my vote

          • 2. Re: Providing getCallerPrincipal() and isCallerInRole(String)

            Thanks David for taking this one :-D

            It seems fine, and should be enough.


            Just two comments:

            1. Providing that I do not know much about JAAS :-D will this mechanism be able to provide for "Unauthenticated users" as well as for other login mechanisms such as ip based authentication? I suppose and can guess that answer is yes, but wanted to confirm.
            2. I have looked at the core, and I don not understand getCalledPrincipal in DefaultSecurityContext. Probably due to my lack of knowledge on JAAS. (Lines 8-10 below)
                public Principal getCallerPrincipal(String securityDomain) {
                    for (Principal principal : getSubject(securityDomain).getPrincipals()) {
                        if (principal instanceof Group) {
                            Group group = (Group)principal;
                            if (group.getName().equalsIgnoreCase(CALLER_PRINCIPAL)) {
                                Enumeration<? extends Principal> roles = group.members();
                                while (roles.hasMoreElements()) {
                                    return roles.nextElement();
                    return null;
            • 3. Re: Providing getCallerPrincipal() and isCallerInRole(String)

              Thanks for the feedback, Jorge.


              1. SY security depends on JAAS for all types of authentication and authorization. Luckily there are several LoginModules that are provided by Picketbox and PicketLink (in JBoss EAP) that can be used which do more than your normal username/password processing.  For example, ones for certificates and SAML assertions.  When you say "Unauthenticated users", what do you mean exactly?  If you are just asking what happens if you use those methods when the caller is not authenticated, the way the proposed code is now will return null for getCallerPrincipal(), and false for isCallerInRole().
              2. I happened across the CallerPrincipal jaas group just last night while I was playing with this, so I jumped on it as being the right way to get this information.  That group is added by Picketbox, so I will look there to verify if it will work in all cases.


              Please note that I threw all this together rather quickly last night so people had something to give me feedback on. Obviously I would need to test how it works across all our security-related quickstarts, as well as sucess+failure paths in JUnit tests.

              • 4. Re: Providing getCallerPrincipal() and isCallerInRole(String)

                Hi David,


                This is awesome-- thanks for this work and especially thanks for highlighting the code deltas and usage example.  Very handy.

                I especially like that you considered the existing similar implementations in Servlet and EJB.  (Why didn't whoever did the second of those consider the first?  <HeadSlap>)  Great work, sticking close to the established JEE path.

                I can't think of any reason why we'd need something different, our use cases should be similar to the ones our predecessors used.

                This looks good to me.  Thanks again!


                • 5. Re: Providing getCallerPrincipal() and isCallerInRole(String)

                  Okay, I went a slightly different approach and have submitted pull requests:






                  Instead of putting getCallerPrincipal() and isCallerInRole(String) directly on the Exchange interface, I added a new interface: org.switchyard.ExchangeSecurity.  So now Exchange only has one added method, getSecurity():ExchangeSecurity.  The naming is right in line with other similar methods, like getPattern():ExchangePattern, getPhase():ExchangePhase.


                  The ExchangeSecurity interface now has 3 methods: getSecurityDomain():String, getCallerPrincipal():Principal, and isCallerInRole(String):boolean.  In the future, based on requirements, we might add more methods, like getSubject():Subject or maybe even getCredentials():Set<Credential>.  I moved the original 2 security methods into this interface so we can add more methods without cluttering up the primary Exchange interface itself.  I think this is a smart move.


                  Comments are welcome, but honestly if you don't like this, you better speak up, 'cause I'd like to see this branch move asap.




                  • 6. Re: Providing getCallerPrincipal() and isCallerInRole(String)

                    FYI, this has been merged into master and will be included in SY 2.0.