1 2 Previous Next 19 Replies Latest reply on Jun 7, 2010 2:57 AM by bdaw

    Seam Security 3.0 and PicketLink

    shane.bryzak

      I've been discussing with Anil our plans for the Seam Security 3.0 release, in regards to integration with PicketLink IDM.  We are adopting the API model defined by PicketLink in Seam, and I'm currently in the process of refactoring Seam's identity management features.

       

      We have identified a number of requirements for the Seam 3 release that are currently not provided by PicketLink.  To facilitate a timely release, our plan is to address these requirements in the 3.0 release itself, and then deprecate them in Seam as they are (hopefully) implemented in PicketLink.  Here's a non-exhaustive summary of the requirements that we have identified so far:
      1) IdentityStore implementation for JPA.  I'm currently working on this - we have an implementation in Seam 2.x but I'm rewriting it again based on PicketLink's SPI model.  We could potentially port this to PicketLink with minimal difficulty.
      2) Support for raising CDI events in response to certain operations.  For example, when an entity is created for a new user, group, etc, a pre and post event should be raised to give the user a chance to modify the entity before it is persisted, or to establish additional references to it from other entities after it is persisted.  This could be achieved via some kind of callback mechanism.
      3) Annotations for configuring entities to be used for identity management.
      4) A simplified API for identity management.  In PicketLink there are multiple APIs for this - PersistenceManager, RelationshipManager, RoleManager, etc.  In Seam we have a single interface, IdentityManager which provides all identity management operations.
      5) Authorization for identity management operations.  In Seam we perform an additional security check when a user tries to create a user, role, group etc or grant or revoke privileges to ensure they have the necessary privileges to execute such an operation.
      6) Ability to plug in a cache for role and group memberships for users.  It is our plan to use Infinispan in Seam to enable this.
      We have some authorization-related requirements also:
      7) Unified authorization architecture - in Seam, authorization checks are performed in a singular manner.  The Identity.hasPermission() method allows for a permission check to be carried out for the current user against multiple PermissionResolver implementations.  We have implementations for Drools (rule-based) and for persistent permissions (ACL-based).  A single permission check will invoke all registered PermissionResolver implementations to determine whether a user has the necessary privileges to execute a secured operation.  This contrasts to PicketBox which requires that you create a specific provider for the type of permission check required, e.g. ACLProvider.  Our strategy for addressing this requirement will be to provide a PermissionResolver implementation for each of the providers offered by PicketBox, which can then be plugged into Seam's unified permission framework.  One particular drawback that we have identified with the ACL support in PicketBox is the requirement for "resource" classes to implement the Resource interface.  In Seam we use an IdentifierPolicy API which alleviates this requirement and allows any class to be assigned permissions, even String literals.
      8) We require the ability to assign more than just the basic CRUD (create, read, update, delete) permissions to objects (this may be possibly already).
      9) It should be possible to store ACL permissions in a database via JPA.
      There is probably much more to discuss in terms of authorization, however in the interests of brevity I'll cut it short here.  I would however like to see a unification of the two ACL-based solutions that we have independently developed, as it would be in our best interest to not have to continue maintaining two competing solutions.

       

      Looking forward to hearing some feedback on these ideas.

        • 1. Re: Seam Security 3.0 and PicketLink
          theute

          Shane Bryzak wrote:

           

          2) Support for raising CDI events in response to certain operations.  For example, when an entity is created for a new user, group, etc, a pre and post event should be raised to give the user a chance to modify the entity before it is persisted, or to establish additional references to it from other entities after it is persisted.  This could be achieved via some kind of callback mechanism.
          I would definitely welcome this
          4) A simplified API for identity management.  In PicketLink there are multiple APIs for this - PersistenceManager, RelationshipManager, RoleManager, etc.  In Seam we have a single interface, IdentityManager which provides all identity management operations.
          But you keep your own API right ?
          5) Authorization for identity management operations.  In Seam we perform an additional security check when a user tries to create a user, role, group etc or grant or revoke privileges to ensure they have the necessary privileges to execute such an operation.
          Interesting indeed.
          7) Unified authorization architecture - in Seam, authorization checks are performed in a singular manner.  The Identity.hasPermission() method allows for a permission check to be carried out for the current user against multiple PermissionResolver implementations.  We have implementations for Drools (rule-based) and for persistent permissions (ACL-based).  A single permission check will invoke all registered PermissionResolver implementations to determine whether a user has the necessary privileges to execute a secured operation.  This contrasts to PicketBox which requires that you create a specific provider for the type of permission check required, e.g. ACLProvider.  Our strategy for addressing this requirement will be to provide a PermissionResolver implementation for each of the providers offered by PicketBox, which can then be plugged into Seam's unified permission framework.  One particular drawback that we have identified with the ACL support in PicketBox is the requirement for "resource" classes to implement the Resource interface.  In Seam we use an IdentifierPolicy API which alleviates this requirement and allows any class to be assigned permissions, even String literals.
          8) We require the ability to assign more than just the basic CRUD (create, read, update, delete) permissions to objects (this may be possibly already).
          9) It should be possible to store ACL permissions in a database via JPA.
          There is probably much more to discuss in terms of authorization, however in the interests of brevity I'll cut it short here.  I would however like to see a unification of the two ACL-based solutions that we have independently developed, as it would be in our best interest to not have to continue maintaining two competing solutions.

          I guess this is more about Picketlink Authz developped by Sohil. It isn't used in a project yet, so it's perfect timing to see how the 2 can be merged.

           

           

          • 2. Re: Seam Security 3.0 and PicketLink
            anil.saldhana
            1. It should be the goal to use PL IDM API for Identity API usage.
            2. Breaking down into managers (persistence, roles, relationships) etc helps in separation of concern.  One IdentityManager.xxx is one overloaded giant.    Both have their advantages and disadvantages.
            3. Authorization aspects can be worked out in the future if we are able to first assimilate the identity parts into seam3.
            4. Shane, thanks for the jpa implementation of IdentityStore interface.
            • 3. Re: Seam Security 3.0 and PicketLink
              shane.bryzak

              ANIL SALDHANA wrote:

               

              1. It should be the goal to use PL IDM API for Identity API usage.
              2. Breaking down into managers (persistence, roles, relationships) etc helps in separation of concern.  One IdentityManager.xxx is one overloaded giant.    Both have their advantages and disadvantages.

               

              Agreed, however to our users this separation is too fine-grained and not consistent with Seam's design.  It would be nice if we could work together to create a simplified API, even if it is just a layer above the existing API.

               

              3. Authorization aspects can be worked out in the future if we are able to first assimilate the identity parts into seam3.
              4. Shane, thanks for the jpa implementation of IdentityStore interface.

               

              No problem, hopefully it won't be too difficult to port to PicketLink once it's complete.

              • 4. Re: Seam Security 3.0 and PicketLink
                bdaw

                Shane Bryzak wrote:

                 

                1) IdentityStore implementation for JPA.  I'm currently working on this - we have an implementation in Seam 2.x but I'm rewriting it again based on PicketLink's SPI model.  We could potentially port this to PicketLink with minimal difficulty.

                 

                I think the simplest approach would be to fork Hibernate implementation and remove Hibernate specific tweaks. AFAIR it is only about Criteria API, mappings for collections and HQL. I also suggest to have mappings in xml instead of annotations as in case of DB specific issues in the feature it is easier to provide a patched xmls. Current HibernateIdentityStoreImpl started as a JPA one so there may be some usefull things in svn history

                 

                2) Support for raising CDI events in response to certain operations.  For example, when an entity is created for a new user, group, etc, a pre and post event should be raised to give the user a chance to modify the entity before it is persisted, or to establish additional references to it from other entities after it is persisted.  This could be achieved via some kind of callback mechanism.

                Sounds good. At the moment there is simple event API (http://anonsvn.jboss.org/repos/picketlink/idm/tags/1.1.5.CR01/picketlink-idm-api/src/main/java/org/picketlink/idm/api/event/) but it doesn't expose entity modifications. I was also thinking about CDI usage as a bootstrap mechanism in the feature.

                 

                3) Annotations for configuring entities to be used for identity management.

                I would need to look a bit more on how it is done in Seam. I guess you are talking here about hibernate like annotations? Current API model is rather simple where user or group can be represented by string reference. Such feature would fit in a layer on top of current framework.

                 

                4) A simplified API for identity management.  In PicketLink there are multiple APIs for this - PersistenceManager, RelationshipManager, RoleManager, etc.  In Seam we have a single interface, IdentityManager which provides all identity management operations.

                 

                Like Anil wrote imagine that of current managers are merged - quite a huge messy interface. We can consider doing a simplified API and in fact what you have in IdentityManager interface could be easily implemented using PLIDM API with minimal translations. I also see that you don't support any kind of pagination or more sophisticated searches. Doesn't it hit you with bigger stores?

                 

                5) Authorization for identity management operations.  In Seam we perform an additional security check when a user tries to create a user, role, group etc or grant or revoke privileges to ensure they have the necessary privileges to execute such an operation.

                I would like to keep authorization outside of the IDM framework but rather provide nessesary extension points and optional integration.

                 

                6) Ability to plug in a cache for role and group memberships for users.  It is our plan to use Infinispan in Seam to enable this.

                Currently there are interfaces for API and SPI/Store cache providers:

                http://anonsvn.jboss.org/repos/picketlink/idm/tags/1.1.5.CR01/picketlink-idm-api/src/main/java/org/picketlink/idm/cache/APICacheProvider.java

                http://anonsvn.jboss.org/repos/picketlink/idm/tags/1.1.5.CR01/picketlink-idm-spi/src/main/java/org/picketlink/idm/spi/cache/IdentityStoreCacheProvider.java

                 

                both have JBoss Cache implementations and are pluggable. Does it fit you needs?

                 

                 

                We have some authorization-related requirements also:

                 

                Did you look at Sohil work?:

                http://authz.blogspot.com/

                http://anonsvn.jboss.org/repos/jbossidentity/authz/

                 

                Like Thomas wrote this is something we are considering to use in GateIn and I believe should anwser most of your concerns. I'm sure that Sohil will love to hear some feedback and discuss the design and architecture. Like I wrote before I would like to keep authorization outside of IDM component but expose proper extension points and separate integration module with chosen framework. 

                • 5. Re: Seam Security 3.0 and PicketLink
                  bdaw

                  For JPA store you could develop it directly in picketlink svn. I can make proper tweaks in testsuite to ease the development and plug it into default set of tests run in hudson against all used DBs.

                   

                  The main requirement from our side in terms of future changes in the framework is to leave the SPI model not affected if possible. As EPP/GateIn is using PLIDM we would like to prevent any unnecessary DB schema changes to avoid migration issues. What matters also is contract between API and SPI (like the hardcoded relationship types to distinguish roles from simple user/group assignment). I think I will need to improve testsuite to ease implementation of internal componets.

                   

                  I would also be interested to discuss possible improvements in configuration mechanism. If we talk about CDI more flexible injection of different framework components could improve bootstrap process. Current xml style is very flexible and has advantage of no DI framework dependencies but some convention over configuration could simplify usage of PLIDM in simple cases where required configuration tweaks are minimal.

                  • 6. Re: Seam Security 3.0 and PicketLink
                    shane.bryzak

                    Boleslaw Dawidowicz wrote:

                     

                    I think the simplest approach would be to fork Hibernate implementation and remove Hibernate specific tweaks. AFAIR it is only about Criteria API, mappings for collections and HQL. I also suggest to have mappings in xml instead of annotations as in case of DB specific issues in the feature it is easier to provide a patched xmls. Current HibernateIdentityStoreImpl started as a JPA one so there may be some usefull things in svn history

                     

                    I wouldn't be so hasty about removing the Hibernate implementation, from my understanding there's a lot of people still using plain Hibernate without JPA.

                    Sounds good. At the moment there is simple event API (http://anonsvn.jboss.org/repos/picketlink/idm/tags/1.1.5.CR01/picketlink-idm-api/src/main/java/org/picketlink/idm/api/event/) but it doesn't expose entity modifications. I was also thinking about CDI usage as a bootstrap mechanism in the feature.

                     

                    We may be able to use this to achieve what we need event-wise, I'll take a look.

                    I would need to look a bit more on how it is done in Seam. I guess you are talking here about hibernate like annotations? Current API model is rather simple where user or group can be represented by string reference. Such feature would fit in a layer on top of current framework.

                     

                     

                    In my latest design, I have a single annotation which is used to configure the entities for identity management.  Here's an example:

                     

                    @Entity

                    public class IdentityObject implements Serializable {

                      private Long id;

                      private String name;

                      private IdentityObjectType type;

                     

                      @Id @GeneratedValue public Long getId() { return id; }

                      public void setId(Long id) { this.id = id; }

                     

                      @IdentityProperty(NAME) public String getName() { return name; }

                      public void setName(String name) { this.name = name; }

                     

                      @IdentityProperty(TYPE) @ManyToOne public IdentityObjectType getType() { return type; }

                      public void setType(IdentityObjectType type) { this.type = type; }

                    }

                     

                    The @IdentityProperty annotation can be used to mark the relevant properties of the entities in the following db schema.  It has a value attribute which has possible values of NAME, TYPE, VALUE, RELATIONSHIP_FROM, RELATIONSHIP_TO which cover all requirements of the PicketLink SPI model.

                     

                    identity_db_model.png

                    Like Anil wrote imagine that of current managers are merged - quite a huge messy interface. We can consider doing a simplified API and in fact what you have in IdentityManager interface could be easily implemented using PLIDM API with minimal translations. I also see that you don't support any kind of pagination or more sophisticated searches. Doesn't it hit you with bigger stores?

                     

                     

                    I don't think the interface is that huge, it has identity-management related operations for creating, updating and deleting users, groups and roles, performing authentication, and a few search operations.  We can examine it in more detail and attempt to refine it further (it could probably do with a little refinement) but IMHO its scope is quite reasonable.

                    5) Authorization for identity management operations.  In Seam we perform an additional security check when a user tries to create a user, role, group etc or grant or revoke privileges to ensure they have the necessary privileges to execute such an operation.

                     

                    I would like to keep authorization outside of the IDM framework but rather provide nessesary extension points and optional integration.

                     

                     

                    Some kind of "hook" here would be nice so that we can plug in some authorization checks.

                    6) Ability to plug in a cache for role and group memberships for users.  It is our plan to use Infinispan in Seam to enable this.

                     

                    Currently there are interfaces for API and SPI/Store cache providers:

                    http://anonsvn.jboss.org/repos/picketlink/idm/tags/1.1.5.CR01/picketlink-idm-api/src/main/java/org/picketlink/idm/cache/APICacheProvider.java

                    http://anonsvn.jboss.org/repos/picketlink/idm/tags/1.1.5.CR01/picketlink-idm-spi/src/main/java/org/picketlink/idm/spi/cache/IdentityStoreCacheProvider.java

                     

                    both have JBoss Cache implementations and are pluggable. Does it fit you needs?

                     

                    Possibly, I wasn't aware of this feature. I'll be sure to check it out.

                     

                    We have some authorization-related requirements also:

                     

                    Did you look at Sohil work?:

                    http://authz.blogspot.com/

                    http://anonsvn.jboss.org/repos/jbossidentity/authz/

                     

                    Like Thomas wrote this is something we are considering to use in GateIn and I believe should anwser most of your concerns. I'm sure that Sohil will love to hear some feedback and discuss the design and architecture. Like I wrote before I would like to keep authorization outside of IDM component but expose proper extension points and separate integration module with chosen framework. 

                    From my understanding the authz stuff is XACML based, right?  IMHO the rule-based security features in Seam (provided by Drools) are far superior, and much easier to work with.  I intend to still integrate the XACML stuff anyway, because I'm sure there's probably some users out there that might like to have it.

                    • 7. Re: Seam Security 3.0 and PicketLink
                      shane.bryzak

                      Boleslaw Dawidowicz wrote:

                       

                      For JPA store you could develop it directly in picketlink svn. I can make proper tweaks in testsuite to ease the development and plug it into default set of tests run in hudson against all used DBs.

                       

                      The main requirement from our side in terms of future changes in the framework is to leave the SPI model not affected if possible. As EPP/GateIn is using PLIDM we would like to prevent any unnecessary DB schema changes to avoid migration issues. What matters also is contract between API and SPI (like the hardcoded relationship types to distinguish roles from simple user/group assignment). I think I will need to improve testsuite to ease implementation of internal componets.

                       

                      I would also be interested to discuss possible improvements in configuration mechanism. If we talk about CDI more flexible injection of different framework components could improve bootstrap process. Current xml style is very flexible and has advantage of no DI framework dependencies but some convention over configuration could simplify usage of PLIDM in simple cases where required configuration tweaks are minimal.

                       

                      I'd prefer to get it working in Seam first, and then port it over once I'm satisfied that it's working as intended.  I imagine this should be within the next week anyway.

                       

                      I definitely have no intention of touching the SPI model, in fact that is the model that we will recommend our users adopt for their database schema (see the schema diagram in my previous post).  I have also adopted the PicketLink API model in Seam (as specified here) as I think it is more powerful than the API we previously had.

                       

                      We can definitely talk more about configuration.  CDI has some fantastic advantages when it comes to application configuration and it would be interesting to explore the possibilities of using it in PL.

                      • 8. Re: Seam Security 3.0 and PicketLink
                        bdaw
                        I wouldn't be so hasty about removing the Hibernate implementation, from my understanding there's a lot of people still using plain Hibernate without JPA.

                         

                        Not removing - I just think it would make sense to have both available. Btw. from your diagram I assume that you don't want to cover SPI named relationships (API Roles) in JPA store implementation for now?

                         

                        In my latest design, I have a single annotation which is used to configure the entities for identity management.  Here's an example:

                         

                        @Entity

                        public class IdentityObject implements Serializable {

                          private Long id;

                          private String name;

                          private IdentityObjectType type;

                         

                          @Id @GeneratedValue public Long getId() { return id; }

                          public void setId(Long id) { this.id = id; }

                         

                          @IdentityProperty(NAME) public String getName() { return name; }

                          public void setName(String name) { this.name = name; }

                         

                          @IdentityProperty(TYPE) @ManyToOne public String getType() { return type; }

                          public void setType(IdentityObjectType type) { this.type = type; }

                        }

                        ok... I thought you were talking about API level while this is about pluggable SPI entities. Looks good.

                         

                        From my understanding the authz stuff is XACML based, right?  IMHO the rule-based security features in Seam (provided by Drools) are far superior, and much easier to work with.  I intend to still integrate the XACML stuff anyway, because I'm sure there's probably some users out there that might like to have it.

                        I will let Sohil comment on this but AFAIR he was considering to leverage Drools in some way.

                         

                         

                        I definitely have no intention of touching the SPI model, in fact that is the model that we will recommend our users adopt for their database schema (see the schema diagram in my previous post).  I have also adopted the PicketLink API model in Seam (as specified here) as I think it is more powerful than the API we previously had.

                        If you have any comments on API areas that could improve don't hesitate to share.

                         

                        I would like to have some way to ensure that any reimplemented component is compatible with default implementation - current testsuite is not that good in this. It would be perfect to have a dedicated testsuite to test any IdentityStore or IdentityStoreRepository implementation for compatibility with framework core.

                         

                        From what I understand in first iteration you are doing JPA IdentityStore and wrapper implementation of Seam IdentityManager using PLIDM API and reusing all default core components? 

                        • 9. Re: Seam Security 3.0 and PicketLink
                          shane.bryzak

                          Boleslaw Dawidowicz wrote:

                           

                          I wouldn't be so hasty about removing the Hibernate implementation, from my understanding there's a lot of people still using plain Hibernate without JPA.

                           

                          Not removing - I just think it would make sense to have both available. Btw. from your diagram I assume that you don't want to cover SPI named relationships (API Roles) in JPA store implementation for now?

                           

                           

                          Oops, I meant to update the schema to include a role type table - I definitely intend to support this.

                          In my latest design, I have a single annotation which is used to configure the entities for identity management.  Here's an example:

                           

                          @Entity

                          public class IdentityObject implements Serializable {

                            private Long id;

                            private String name;

                            private IdentityObjectType type;

                           

                            @Id @GeneratedValue public Long getId() { return id; }

                            public void setId(Long id) { this.id = id; }

                           

                            @IdentityProperty(NAME) public String getName() { return name; }

                            public void setName(String name) { this.name = name; }

                           

                            @IdentityProperty(TYPE) @ManyToOne public String getType() { return type; }

                            public void setType(IdentityObjectType type) { this.type = type; }

                          }

                          ok... I thought you were talking about API level while this is about pluggable SPI entities. Looks good.

                           

                          From my understanding the authz stuff is XACML based, right?  IMHO the rule-based security features in Seam (provided by Drools) are far superior, and much easier to work with.  I intend to still integrate the XACML stuff anyway, because I'm sure there's probably some users out there that might like to have it.

                          I will let Sohil comment on this but AFAIR he was considering to leverage Drools in some way.

                           

                           

                          I definitely have no intention of touching the SPI model, in fact that is the model that we will recommend our users adopt for their database schema (see the schema diagram in my previous post).  I have also adopted the PicketLink API model in Seam (as specified here) as I think it is more powerful than the API we previously had.

                          If you have any comments on API areas that could improve don't hesitate to share.

                           

                          I would like to have some way to ensure that any reimplemented component is compatible with default implementation - current testsuite is not that good in this. It would be perfect to have a dedicated testsuite to test any IdentityStore or IdentityStoreRepository implementation for compatibility with framework core.

                           

                          From what I understand in first iteration you are doing JPA IdentityStore and wrapper implementation of Seam IdentityManager using PLIDM API and reusing all default core components? 

                           

                          The actual security model API is very good, I don't think I can think of anything that I could suggest to improve it. 

                           

                          Yes, my current intent is to get the JPA stuff working and to develop a fully functional Seam example which will demonstrate its use (an IDM console application).  The idea is that while the example's default configuration will use JPA, its identity stores can be configurable, so it can run off of an ldap server, or whatever.  Let's wait until I get that all working and then decide where to move on from there.

                          • 10. Re: Seam Security 3.0 and PicketLink
                            soshah

                            >From my understanding the authz stuff is XACML based, right?  IMHO the rule-based security features in Seam (provided by Drools) are far >superior, and much easier to work with.  I intend to still integrate the XACML stuff anyway, because I'm sure there's probably some users out there >that might like to have it.

                             

                            Authz Policy Engine is based on XACML, but the developer never has to deal with XACML. The developer uses a set of POJO security components to develop their security layer. The security layer includes both the Enforcement Layer (where actual authorization check occur at runtime), and Provisioning layer (where security policy can be managed/modified at runtime).

                             

                            XACML is actually an ideal spec for really decoupling security code from core business logic. But the fact that using Authz the developer never has to deal with low level XACML details is a best of both worlds for them.

                             

                            IMO Drools is perfect for actually implementing the XACML engine (which is currently the Sun XACML implementation, which is a discussion for another topic).

                             

                            One thing that jumped out for me when looking at Seam Security was its tight coupling to "User Role" as the central attribute around which all security decisions are made. It works for Role Based Access Control, but in Enterprise systems "Role" is just one of many other information that can be used to make access decisions.

                             

                            Atleast in GateIn, we want more than just Role based access control. Access Control can be based on time of the day, IP address of the user, etc.

                             

                            I am not saying Seam Security cannot be extended, but then extending the framework on an on demand basis does not scale.

                             

                            With XACML you can provide whatever type of security profile you want since it only cares about attributes and logic associated with them. It does not care if this information is Role based, or IP based, or something else.

                             

                            I know authorization is a very frustrating topic, so I would recommend, may be wait till we can integrate Authz with Gatein and some of its usecases, to really get a feel for how it works and whats possible.

                             

                            Thanks

                            Sohil

                            • 11. Re: Seam Security 3.0 and PicketLink
                              shane.bryzak

                              Sohil Shah wrote:

                               

                              >From my understanding the authz stuff is XACML based, right?  IMHO the rule-based security features in Seam (provided by Drools) are far >superior, and much easier to work with.  I intend to still integrate the XACML stuff anyway, because I'm sure there's probably some users out there >that might like to have it.

                               

                              Authz Policy Engine is based on XACML, but the developer never has to deal with XACML. The developer uses a set of POJO security components to develop their security layer. The security layer includes both the Enforcement Layer (where actual authorization check occur at runtime), and Provisioning layer (where security policy can be managed/modified at runtime).

                               

                              That's great to hear, the XML policy definitions I've seen in examples is scary looking stuff.

                              XACML is actually an ideal spec for really decoupling security code from core business logic. But the fact that using Authz the developer never has to deal with low level XACML details is a best of both worlds for them.

                               

                              IMO Drools is perfect for actually implementing the XACML engine (which is currently the Sun XACML implementation, which is a discussion for another topic).

                               

                              One thing that jumped out for me when looking at Seam Security was its tight coupling to "User Role" as the central attribute around which all security decisions are made. It works for Role Based Access Control, but in Enterprise systems "Role" is just one of many other information that can be used to make access decisions.

                               

                              Atleast in GateIn, we want more than just Role based access control. Access Control can be based on time of the day, IP address of the user, etc.

                               

                              I am not saying Seam Security cannot be extended, but then extending the framework on an on demand basis does not scale.

                               

                              With XACML you can provide whatever type of security profile you want since it only cares about attributes and logic associated with them. It does not care if this information is Role based, or IP based, or something else.

                               

                              I know authorization is a very frustrating topic, so I would recommend, may be wait till we can integrate Authz with Gatein and some of its usecases, to really get a feel for how it works and whats possible.

                               

                              Thanks

                              Sohil

                               

                              In Seam, we consider role-based authorization to be "coarse-grained", and inadequate for many real world scenarios.  With rule-based permissions in Seam, authorization can be granted based on user role, time of day, IP address, the number of pets the user owns, etc.  Basically anything you can dream of, and it's defined in easy to read Drools rule definitions using MVEL or even a domain-specific language if your application requires it (i.e. the full capabilities of Drools are available). 

                               

                              I know that some of our users store their definitions in a repository and use BRMS to adjust rules at runtime, to me this is the perfect combination and reinforces the total separation of business logic and authorization logic, and even allows even non-technical users such as managers to be able to define and manage security rules.

                               

                              I understand though that even though XACML might duplicate some of this functionality it is definitely going to be an advantage to support it.

                              An benefit of Seam's authorization architecture is it easily allows PermissionResolver implementations to be plugged into the authorization "stack".  This should hopefully mean that it will be straight forward to include Authz support, and I'm looking forward to integrating it with Seam.

                              • 12. Re: Seam Security 3.0 and PicketLink
                                shane.bryzak

                                Here's a rundown of the methods I propose for the IdentityManager interface.  None of these are set in stone, and in fact I'd welcome feedback in the interest of refining them further.

                                 

                                To start off, here's the methods related to user management:

                                 

                                   /**
                                    * Creates a new user with the specified username and credential.
                                    *
                                    * @param username The new user's username
                                    * @param credential The new user's credential
                                    * @return true if the user was successfully created, false otherwise.
                                    */
                                   boolean createUser(String username, Credential credential);
                                  
                                   /**
                                    * Deletes the user with the specified username. This operation also deletes
                                    * all of the user's credentials, relationships and attributes.
                                    *
                                    * @param username The username of the user to delete
                                    * @return true if the user was successfully deleted.
                                    */
                                   boolean deleteUser(String username);
                                 
                                   /**
                                    * Updates the credentials of the user with the specified username
                                    *
                                    * @param username The username of the user's credential to update
                                    * @param credential The new credential
                                    * @return true if the credential was successfully updated
                                    */
                                   boolean updateCredential(String username, Credential credential);
                                  
                                   /**
                                    * Checks if the user with the specified username exists
                                    * 
                                    * @param username The username of the user
                                    * @return true if the user exists
                                    */
                                   boolean userExists(String username); 
                                   /**
                                    * Checks if a user account is currently enabled
                                    *
                                    * @param username The username of the user account to check
                                    * @return true if the user account is enabled
                                    */
                                   boolean isUserEnabled(String username);
                                  
                                   /**
                                    * Enables the user account of the specified username
                                    *
                                    * @param username The username of the account to enable
                                    * @return true if the account was successfully enabled
                                    */
                                   boolean enableUser(String username);
                                  
                                   /**
                                    * Disables the user account of the specified username
                                    * 
                                    * @param username The username of the account to disable
                                    * @return true if the account was successfully disabled
                                    */
                                   boolean disableUser(String username); 
                                The last 3 methods related to user enablement could potentially be removed in favour of using an "enabled" attribute instead.  The next two methods are for user attributes:
                                   /**
                                    * Sets the specified attribute value for the specified user
                                    *
                                    * @param username The username of the user
                                    * @param attribute The name of the attribute to set
                                    * @param value The value of the attribute
                                    * @return true if the attribute was successfully set
                                    */
                                   boolean setUserAttribute(String username, String attribute, Object value);
                                  
                                   /**
                                    * Deletes the specified attribute value from the specified user
                                    *
                                    * @param username The username of the user
                                    * @param attribute The name of the attribute to delete
                                    * @return true if the attribute was successfully deleted
                                    */
                                   boolean deleteUserAttribute(String username, String attribute);
                                Next we have role type management:
                                   /**
                                    * Creates a new role type
                                    *
                                    * @param roleType The name of the new role type
                                    * @return true if the role type was successfully created
                                    */
                                   boolean createRoleType(String roleType);
                                  
                                   /**
                                    * Deletes the specified role type.  All granted roles of the specified
                                    * role type are deleted also.
                                    *
                                    * @param roleType The name of the role type to delete
                                    * @return true if the role type was successfully deleted
                                    */
                                   boolean deleteRoleType(String roleType);
                                Pretty straight forward.  Similarly, we have group management methods also:
                                   /**
                                    * Creates a new group, with the specified name and of the specified group type
                                    *
                                    * @param name The name of the new group
                                    * @param groupType The type of the new group
                                    * @return true if the group was successfully created
                                    */
                                   boolean createGroup(String name, String groupType);
                                  
                                   /**
                                    * Deletes the group with the specified name and group type
                                    * 
                                    * @param name The name of the group to delete
                                    * @param groupType The type of the group to delete
                                    * @return true if the group was successfully deleted
                                    */
                                   boolean deleteGroup(String name, String groupType);
                                Next we have methods for role membership:
                                   /**
                                    * Grants a role membership to the specified user.
                                    *
                                    * @param username The username of the user being granted role membership
                                    * @param roleType The role type of the role being granted
                                    * @param groupName The name of the group the role is being granted in
                                    * @param groupType The type of the group
                                    * @return true if the role was successfully granted
                                    */
                                   boolean grantRole(String username, String roleType, String groupName, String groupType);
                                  
                                   /**
                                    * Revokes role membership from the specified user.
                                    *
                                    * @param username The username of the user being revoked role membership
                                    * @param roleType The role type of the role being revoked
                                    * @param groupName The name of the group the role is being revoked from
                                    * @param groupType The type of the group
                                    * @return true if the role was successfully revoked
                                    */
                                   boolean revokeRole(String username, String roleType, String groupName, String groupType); 
                                And group membership:
                                   /**
                                    * Adds a user to the specified group
                                    * 
                                    * @param username The username of the user being added to the group
                                    * @param groupName The name of the group the user is being added to
                                    * @param groupType The type of the group
                                    * @return true if the user was successfully added
                                    */
                                   boolean addUserToGroup(String username, String groupName, String groupType);
                                  
                                   /**
                                    * Removes a user from the specified group
                                    *
                                    * @param username The username of the user being removed
                                    * @param groupName The name of the group the user is being removed from
                                    * @param groupType The type of the group
                                    * @return true if the user was successfully removed
                                    */
                                   boolean removeUserFromGroup(String username, String groupName, String groupType);
                                Then we have a few methods for querying various things:
                                   /**
                                    * Finds users that match the specified filter.  A filter of null will return
                                    * all users.
                                    *
                                    * @param filter The filter used to perform the search. 
                                    * @return A list of users that match the specified filter.
                                    */
                                   List<String> findUsers(String filter);
                                  
                                   /**
                                    * Returns a list of all the role types.
                                    *
                                    * @return A list of all role types
                                    */
                                   List<String> listRoleTypes();
                                  
                                   /**
                                    * Returns a list of the roles that are explicitly granted to the specified user;
                                    *
                                    * @param name The user for which to return a list of roles
                                    * @return List containing the names of the granted roles
                                    */
                                   List<Role> getGrantedRoles(String name);
                                  
                                   /**
                                    * Returns a list of roles that are either explicitly or indirectly granted to the specified user.
                                    *
                                    * @param name The user for which to return the list of roles
                                    * @return List containing the names of the implied roles
                                    */
                                   List<Role> getImpliedRoles(String name);
                                  
                                   /**
                                    * Returns a list of all members that have been granted the specified role
                                    *
                                    * @param roleType The role type of the role
                                    * @param groupName The name of the group the role has been granted in
                                    * @param groupType The type of the group
                                    * @return A List of IdentityType objects having membership of the specified role
                                    */
                                   List<IdentityType> listRoleMembers(String roleType, String groupName, String groupType);
                                And last of all, a method for authenticating:
                                   /**
                                    * Performs an authentication check using the specified username and credential.
                                    * This operation does not establish any kind of security context, it simply
                                    * returns a result indicating whether authentication is successful or not.
                                    * 
                                    * @param username The username to authenticate
                                    * @param credential The credential to authenticate with
                                    * @return true if authentication was successful, false otherwise.
                                    */
                                   boolean authenticate(String username, Credential credential);

                                That sums up all the methods.  I don't feel that this interface is overloaded by any means, and I believe that its scope meets the requirements of the majority of our users.  I'd be interested to know what other people think about this API, and whether it's missing any potentially important functionality.

                                 

                                Message was edited by: Shane Bryzak (improved source code formatting)

                                • 13. Re: Seam Security 3.0 and PicketLink
                                  bdaw

                                  The list looks fine but I have few concerns. Few quick thoughts:

                                   

                                  1) I was wondering where to place this. In fact the only place that makes sense is another method in IdentitySession - getIdentityManager(). Most of your methods can be implemented with 1 line of code (simple invocation of other XXManager interface) and others with maximum few lines...  However this may look a bit strange to have all those duplicated methods within the same package and the naming can be a bit misleading: IdentityManager, PersistenceManager, RelationshipMenager and so on... I don't have any good name in mind but maybe something like SimpleManager (which also sounds "lame") would be better... I know that such simple API can help with the adoption - just not sure about best way to include it. Btw. I assume that along with such simple interface consider exposing the whole PLIDM API in Seam?

                                   

                                  2) Behavior of methods for "enabled" users would need to be more configurable. We can have special attribute name like "org.picketlink.idm.api.attributes.enabled" with config option to override it, Should user be enabled or disabled by default if such attribute is not set? Having a mixed feelings about this but as this is probably the most commonly used kind of attribute it may be good to have some dedicated logic to handle it.

                                   

                                  3) For roles you use "grant" and "revoke" while in RoleManager there is simple "create" and "remove". Your naming makes sense but not sure if we should stick with simple fork of method names in one place or not - can be misleading.

                                   

                                  4)  getImpliedRoles() is also about indirect role memberships but there is no such functionality in the framework currently. What did you have in mind? I have something like this on the roadmap: https://jira.jboss.org/browse/PLIDM-2 and https://jira.jboss.org/browse/PLIDM-1. Still not sure where and how to implement those but it would lead to another "Manager" interface probably like ExtRelationshipManager...

                                   

                                  5) There are no methods related to simple user/group association. I was thinking about some configuration mapping that would make role of dedicated type like "member" be mapped into such simple relationship in the SPI level so maybe it is good idea to stick with roles only. However association is much simpler and maybe more natural way of thinking about user/group memberships (like in JEE security) so we should consider also associateUser, associateGroup, disassociateUser and disassociateGroup methods.

                                  • 14. Re: Seam Security 3.0 and PicketLink
                                    shane.bryzak

                                    Boleslaw Dawidowicz wrote:

                                     

                                    The list looks fine but I have few concerns. Few quick thoughts:

                                     

                                    1) I was wondering where to place this. In fact the only place that makes sense is another method in IdentitySession - getIdentityManager(). Most of your methods can be implemented with 1 line of code (simple invocation of other XXManager interface) and others with maximum few lines...  However this may look a bit strange to have all those duplicated methods within the same package and the naming can be a bit misleading: IdentityManager, PersistenceManager, RelationshipMenager and so on... I don't have any good name in mind but maybe something like SimpleManager (which also sounds "lame") would be better... I know that such simple API can help with the adoption - just not sure about best way to include it. Btw. I assume that along with such simple interface consider exposing the whole PLIDM API in Seam?

                                     

                                    I can see how this might add to the confusion.  Perhaps something like SimpleIdentityManager might be appropriate?  And yes, I intended to expose the entire PLIDM API in Seam, for the few users who required more advanced functionality.  One thing to remember is that the IdentityManager implementation in Seam also performs an additional security check itself, before carrying out the identity management operation.  This is an essential requirement for Seam.

                                     

                                    2) Behavior of methods for "enabled" users would need to be more configurable. We can have special attribute name like "org.picketlink.idm.api.attributes.enabled" with config option to override it, Should user be enabled or disabled by default if such attribute is not set? Having a mixed feelings about this but as this is probably the most commonly used kind of attribute it may be good to have some dedicated logic to handle it.

                                     

                                    The way I implement this is to have a configurable "user enabled" attribute name in the identity store.  If the attribute is not explicitly set then I would probably tend to think that the user was enabled, however in my opinion if the enabled attribute has been configured then the attribute should always be created whenever a new user is created, and so should always be present. 

                                     

                                    One other related feature that I've been toying with is the ability to support scheduling for user enablement and role membership.  It would be really nice if it were possible for example to only enable users between certain times on certain days, or have their role memberships activated in the same way.  Also useful would be account and membership expiry, where an account or a granted role or group membership would expire after so much time.

                                     

                                    3) For roles you use "grant" and "revoke" while in RoleManager there is simple "create" and "remove". Your naming makes sense but not sure if we should stick with simple fork of method names in one place or not - can be misleading.

                                     

                                    I think that "grant" and "revoke" make more sense from a traditional security point of view.  Is there any way we could rename these methods in PLIDM (and deprecate the old ones)?

                                     

                                    4)  getImpliedRoles() is also about indirect role memberships but there is no such functionality in the framework currently. What did you have in mind? I have something like this on the roadmap: https://jira.jboss.org/browse/PLIDM-2 and https://jira.jboss.org/browse/PLIDM-1. Still not sure where and how to implement those but it would lead to another "Manager" interface probably like ExtRelationshipManager...

                                     

                                    I think this is as simple as allowing groups to become members of other groups (I thought PLIDM already supported this though?).  I don't think it calls for yet another interface - surely another method could just be added to RelationshipManager?

                                     

                                    5) There are no methods related to simple user/group association. I was thinking about some configuration mapping that would make role of dedicated type like "member" be mapped into such simple relationship in the SPI level so maybe it is good idea to stick with roles only. However association is much simpler and maybe more natural way of thinking about user/group memberships (like in JEE security) so we should consider also associateUser, associateGroup, disassociateUser and disassociateGroup methods.

                                     

                                    I thought that the associateUser() etc methods created a relationship with a type name of "JBOSS_IDENTITY_MEMBERSHIP" - this is the intent of the addUserToGroup() etc methods I listed in IdentityManager.  I'm willing to compromise on this though - after thinking about it some more I think I like the PLIDM method names better, so I'll remove addUserToGroup()/removeUserFromGroup() and replace with associateUser, associateGroup etc, that will bring them more in line.

                                     

                                    1 2 Previous Next