14 Replies Latest reply on Feb 18, 2007 5:27 AM by tom.baeyens

    commands & EJB 3

    camunda

      Hi!

      For the jbpm commands there is a CommandService-Implementation as EJB 2.1 SessionBean: org.jbpm.ejb.impl.CommandServiceBean

      First of all: There is no EJB 3 SessionBean available, right? And because the Java 1.4 compability is still required we only can build a EJB 3 SessionBean in our own toolkit for jBPM, not the jbpm core, right?

      Also we use JAAS to autheticate users (to have different groups for deploying processes, signalling, cancelling, ...). We have annotated this in our EJB 3 Bean (e.g. @RolesAllowed( {"jbpm-admin-write"}) ). How can we do that with the commands?

      One really generic and easy solution which came into my mind, is just to have the Command-Class-names as roles in JAAS (ok, not so nice for the administration) and then check, if the JAAS user is in the role in the SessionBean, so the JAAS-Logic is only in the SessionBean, nowhere else.

      What do you think?

      Or hardcode 3 or 4 roles in the commands and check for them? So everybody which needs different roles has to overwrite the commands?

      Or any complete different approaches (like configuring that in a external configuration)?

      Regards
      Bernd

        • 1. Re: commands & EJB 3
          tom.baeyens

           

          "camunda" wrote:
          First of all: There is no EJB 3 SessionBean available, right? And because the Java 1.4 compability is still required we only can build a EJB 3 SessionBean in our own toolkit for jBPM, not the jbpm core, right?


          no. you could include them into the jbpm sources. you just have to be very carefull not to introduce dependencies to java 5 in the current codebase.

          best way to do that is to make sure that the ejb3 part is in a separate source directory. probably in a separate sub project project.

          maybe an ejb3 subproject, right underneith the jbpm.3 root ? what do you think. if you can give that the same layout/build structure as the other subprojects (e.g. by starting from a copy of the enterprise project), you can just go ahead and try that. you can't do any harm by trying in a separate project ;-)

          "camunda" wrote:
          Also we use JAAS to autheticate users (to have different groups for deploying processes, signalling, cancelling, ...). We have annotated this in our EJB 3 Bean (e.g. @RolesAllowed( {"jbpm-admin-write"}) ). How can we do that with the commands?


          with commands, you definitely cannot use the annotations based security. i think you could do it with JACC based authorization checks. i'll have to give that a second look if that would work out.

          "camunda" wrote:

          One really generic and easy solution which came into my mind, is just to have the Command-Class-names as roles in JAAS (ok, not so nice for the administration) and then check, if the JAAS user is in the role in the SessionBean, so the JAAS-Logic is only in the SessionBean, nowhere else.


          i think we should try to see of we can embed the JACC based authorization inside of the commands.

          • 2. Re: commands & EJB 3
            camunda

            For the Authorization:

            My idea was much easier, just to have a, let's say

             String[] getAllowedRoles
            


            method in the Command. This returns the possible roles for the user. jBPM than can leave it up to the CommandService to do something with it, for example:
            - use JACC
            - use JAAS in the EJB-SessionBean
            - own implementation...

            With that you have it decoupled from the realization. Or what do you think?

            • 3. Re: commands & EJB 3
              tom.baeyens

              just checked JACC. this is my current line of thinking:

              a AuthorizationService should be configurable. this service knows how to check permissions. there is already such service in the core sources. not currently used though :-)

              now when a command is presented to the command execution service, it should check the jbpmContext for the presence of a AuthorizationService. If such a service is present, the command execution service creates a CommandPermission and passes the command-to-be-executed in the constructor of the CommandPermission. Then, the authorization service is asked to check this permission.

              Now, the authorization service can still decide to map the command to specific permissions. e.g. One impl of the authorization service could map the commands to a set of roles and use jacc EJBRoleRefPermission's or WebRoleRefPermission's before it delegates the authorization check to AccessControlContext or SecurityManager.

              makes sense ?

              this approach also allows for the default set up to be without any authorization service and hence without any authorization. easy to get going. but it also allows for flexible authorization based on the current java standards if desired.

              • 4. Re: commands & EJB 3
                starksm64

                Yes. The JBAS JACC implementation does allow for custom permissions outside of the standard javax.* permissions defined in the spec.

                • 5. Re: commands & EJB 3
                  camunda

                  Hi Tom,

                  okay, the idea sounds nice. As a Java-EE guy JACC is new to me, but no problem :-)

                  Okay, I found the AuthorizationService (-Interface). I haven't found any good informations on the "EJBRoleRefPermission", not even with Google! But okay, to get it working with JAAS should not be a big deal. I will try that and come back, if there are any problems.

                  One problem I just want to pass to you Tom: Can you add the AuthorizationService to the jbpmContext? Or shall I try to do that by myself?

                  And one problem remains: How we do the mapping between commands and roles? Going by Command-Name is not the best idea, I think. 2 other ideas:
                  - introduce a mapping-file (CommandName, required-roles)
                  - add the method to the CommandInterface as suggested

                  The first one is maybe more flexible, but to have everything in java more handy. And special solutions (like "this guy is only allowed for processes of that organizational unit") has to be implemented by hand anyway. So I would prefer the second way, but what do you prefer for that?

                  • 6. Re: commands & EJB 3
                    tom.baeyens

                     

                    "camunda" wrote:
                    Hi Tom,

                    okay, the idea sounds nice. As a Java-EE guy JACC is new to me, but no problem :-)

                    don't try to read the spec. it's really unreadable. if you give me some time and push me with your questions, i should be able to handle the JACC stuff.

                    "camunda" wrote:

                    Okay, I found the AuthorizationService (-Interface). I haven't found any good informations on the "EJBRoleRefPermission", not even with Google! But okay, to get it working with JAAS should not be a big deal. I will try that and come back, if there are any problems.


                    "camunda" wrote:


                    One problem I just want to pass to you Tom: Can you add the AuthorizationService to the jbpmContext? Or shall I try to do that by myself?


                    fetch it from the thread local. JbpmContext.getCurrentContext() or something like that. See how the other services get the jbpmContext. I know there are a few services that do that (not all, though).

                    "camunda" wrote:

                    And one problem remains: How we do the mapping between commands and roles? Going by Command-Name is not the best idea, I think. 2 other ideas:
                    - introduce a mapping-file (CommandName, required-roles)
                    - add the method to the CommandInterface as suggested


                    mapping between commands and roles will be hard coded (or later maybe in a configuration file) in the AuthorizationService implementation.

                    "camunda" wrote:


                    The first one is maybe more flexible, but to have everything in java more handy. And special solutions (like "this guy is only allowed for processes of that organizational unit") has to be implemented by hand anyway. So I would prefer the second way, but what do you prefer for that?


                    adding a method in the command interface is not good. it should be in self contained in the Authorization service. But in there, you have the option of using a configuration file or hard coded approach. i would suggest to start with the hard coded approach.

                    • 7. Re: commands & EJB 3
                      camunda

                      For the AUthorizationService:

                      fetch it from the thread local. JbpmContext.getCurrentContext() or something like that. See how the other services get the jbpmContext. I know there are a few services that do that (not all, though).

                      And how? I didn't find any
                      jbpmContext.getAuthorizationService()
                      

                      or something similar.


                      • 8. Re: commands & EJB 3
                        kukeltje

                        the A and A are not a real service (yet) I think they should become one...

                        • 9. Re: commands & EJB 3
                          tom.baeyens

                          AuthenticationService is a real service and it is configured by default

                          AuthorizationService is defined as a service, but it is not included in the default configuration

                          • 10. Re: commands & EJB 3
                            camunda

                            Sorrz Tom, I don't get it, can you post some code how to get the AuthorizationService? Would be nice, thanks in advance...

                            By the way: progress is good, I think I will finish the translation of our code to Commands and get the Swing Admin-Client and Task-Form-Framework the next week. After that I plan to commit the Commands and write a documentation for the Swing stuff....

                            • 11. Re: commands & EJB 3
                              tom.baeyens

                              In the constructor of your authorization service impl, you can fetch the JbpmContext with JbpmContext.getCurrentContext(). (ignore the deprecated. that is to indicate that the method jbpmConfiguration.getCurrentContext() is to be preferred. but in the case of service construction, you don't have a pointer to the jbpmConfiguration...)

                              To navigate from the jbpmContext to other services, use jbpmContext.getServices().getService(...) where ... is one of the constants defined in Services.

                              To navigate from the jbpmContext to the sessions for db access, use jbpmContext.getXxxSession().

                              You can also use jbpmContext.getSession() and put your queries directly in the service.


                              i know this services/session stuff stinks :-) it's one of the main topics to be improved in jbpm 4.

                              • 12. Re: commands & EJB 3
                                tom.baeyens

                                The method in the authorization service looks like this

                                void checkPermission(Permission permission) throws AccessControlException;


                                the idea is that in the jbpm code, we should just check for jbpm type of permissions. e.g. org.jbpm.permission.TokenPermission or org.jbpm.permission.TaskPermission (to be created).

                                in the authorization service checkPermission method, you could then map these permissions to EjbRoleRefPermissions WebRolePermission (or something like that) from the JACC specification and then use the SecurityManager to perform the actual check. the result will be a role check as if it was done inside of the webapp or ejb's.

                                does this help you further ?

                                regards, tom.

                                • 13. Re: commands & EJB 3
                                  tom.baeyens

                                   

                                  "tom.baeyens@jboss.com" wrote:

                                  the idea is that in the jbpm code, we should just check for jbpm type of permissions. e.g. org.jbpm.permission.TokenPermission or org.jbpm.permission.TaskPermission (to be created).


                                  in your application this should be CommandPermission or something like that. you could put the command inside of the CommandPermission.

                                  but still there is something that needs to be cleared out first. how authentication is passed into authorization.

                                  i see 2 different situations. in case of a webapp or a swing app, the user is already authenticated when a command is created.

                                  in case of client server execution of commands. a client sends a command to the server for execution. in that case, there must be some client identification and credentials passed along with the command. in case of ejb, that is handled by ejb spec, i think. so the authentication context is passed allong with the method invocation over the wire. probably something similar will exist in the web service specifications in case we want to expose the command execution service via web services.

                                  concluding, the most important is that the authentication/authorization solution that we work out should cover both scenarios: web/swing-apps and server side execution of commands send by a remote client.

                                  regards, tom.

                                  • 14. Re: commands & EJB 3
                                    tom.baeyens

                                    writing as i think....

                                    public class WebRoleAuthorizationService implements AuthorizationService {
                                    
                                     public void checkPermission(Permission permission) throws AccessControlException {
                                    
                                     Permission mappedPermission = null;
                                    
                                     if (permission instanceof CommandPermission) {
                                     CommandPermission commandPermission = (CommandPermission) permission;
                                     Command command = commandPermission.getCommand();
                                     mappedPermission = new javax.security.jacc.WebRoleRefPermission(...map the command to a web role...);
                                     } else {
                                     ...map the other permissions...
                                     }
                                    
                                     SecurityManager sm = System.getSecurityManager();
                                     if (sm!=null) {
                                     sm.checkPermission(mappedPermission);
                                     }
                                    }
                                    


                                    does this show/illustrate the idea a bit ?