[security-dev] IDM Configuration API

Anil Saldhana Anil.Saldhana at redhat.com
Tue Nov 6 16:33:32 EST 2012


Shane - the configuration API is important. Go ahead.

On 11/06/2012 10:34 AM, Jason Porter wrote:
> +1 at all sounds good to me.
>
>
> On Tue, Nov 6, 2012 at 3:08 AM, Shane Bryzak <sbryzak at redhat.com 
> <mailto:sbryzak at redhat.com>> wrote:
>
>     Hey guys,
>
>     For the past few days I've been wracking my brain trying to come
>     up with
>     a design for the IDM configuration API that doesn't suck, and allows
>     easy configuration in both Java SE and EE environments while
>     maintaining
>     separation between the API and implementation.  I think I've come up
>     with something that's quite flexible and extensible, so I'd like
>     to run
>     it past everyone for some feedback.
>
>     The starting point for configuring the Identity Management API is a
>     concrete class called IdentityConfiguration:
>
>     public class IdentityConfiguration {
>          private List<IdentityStoreConfiguration> configuredStores = new
>     ArrayList<IdentityStoreConfiguration>();
>          public List<IdentityStoreConfiguration> getConfiguredStores() {
>              return configuredStores;
>          }
>          public void addStoreConfiguration(IdentityStoreConfiguration
>     config) {
>              configuredStores.add(config);
>          }
>     }
>
>     This class simply provides a holder for one or more
>     IdentityStoreConfiguration(s), an abstract class that provides the
>     basics for configuring an IdentityStore:
>
>     public abstract class IdentityStoreConfiguration {
>          private final Map<String,String> properties = new
>     HashMap<String,String>();
>          private final Set<Feature> supportedFeatures = new
>     HashSet<Feature>();
>          public Set<Feature> getSupportedFeatures() {
>              return supportedFeatures;
>          }
>          public void addSupportedFeature(Feature feature) {
>              supportedFeatures.add(feature);
>          }
>          public void removeSupportedFeature(Feature feature) {
>              supportedFeatures.remove(feature);
>          }
>          public void setProperty(String name, String value) {
>              properties.put(name, value);
>          }
>          public String getPropertyValue(String name) {
>              return properties.get(name);
>          }
>     }
>
>     Each IdentityStore implementation (such as JPAIdentityStore,
>     LDAPIdentityStore, etc) should have a corresponding
>     IdentityStoreConfiguration implementation that provides an API for
>     setting specific property values for its IdentityStore.  For example,
>     this is the one for JPAIdentityStore which allows a number of entity
>     classes to be set:
>
>     public class JPAIdentityStoreConfiguration extends
>     IdentityStoreConfiguration {
>          private Class<?> identityClass;
>          private Class<?> membershipClass;
>          private Class<?> credentialClass;
>          private Class<?> attributeClass;
>          public Class<?> getIdentityClass() {
>              return identityClass;
>          }
>          public void setIdentityClass(Class<?> identityClass) {
>              this.identityClass = identityClass;
>          }
>          public Class<?> getCredentialClass() {
>              return credentialClass;
>          }
>          public void setCredentialClass(Class<?> credentialClass) {
>              this.credentialClass = credentialClass;
>          }
>          public Class<?> getMembershipClass() {
>              return membershipClass;
>          }
>          public void setMembershipClass(Class<?> membershipClass) {
>              this.membershipClass = membershipClass;
>          }
>          public Class<?> getAttributeClass() {
>              return attributeClass;
>          }
>          public void setAttributeClass(Class<?> attributeClass) {
>              this.attributeClass = attributeClass;
>          }
>     }
>
>     The IdentityStore-specific configurations are intended to be part
>     of the
>     API, so they should be placed in the API module within the
>     org.picketlink.idm.config package.
>
>     After creating an IdentityConfiguration, you can create an
>     IdentityManager and provide the configuration via the bootstrap()
>     method:
>
>     IdentityConfiguration identityConfig = new IdentityConfiguration();
>     JPAIdentityStoreConfiguration storeConfig = new
>     JPAIdentityStoreConfiguration();
>     // snip storeConfig configuration
>
>     identityConfig.addStoreConfiguration(storeConfig);
>
>     IdentityManager identityManager = new DefaultIdentityManager();
>     identityManager.bootstrap(identityConfig, new
>     DefaultIdentityStoreInvocationContextFactory(null));
>
>     The reason we use bootstrap() instead of performing configuration
>     in the
>     constructor is so the developer has a chance to override the
>     IdentityStoreFactory.  This is an SPI interface that defines a
>     couple of
>     methods which are used to control which IdentityStoreConfigurations
>     correspond to which IdentityStore.
>
>     public interface IdentityStoreFactory {
>          /**
>           * Creates an instance of an IdentityStore using the provided
>     configuration
>           *
>           * @param config
>           * @return
>           */
>          IdentityStore createIdentityStore(IdentityStoreConfiguration
>     config);
>
>          /**
>           * Maps specific implementations of
>     IdentityStoreConfiguration to a
>     corresponding
>           * IdentityStore implementation.
>           *
>           * @param configClass
>           * @param storeClass
>           */
>          void mapConfiguration(Class<? extends IdentityStoreConfiguration>
>     configClass,
>                  Class<? extends IdentityStore> storeClass);
>     }
>
>     By default, the DefaultIdentityManager will create and use an instance
>     of DefaultIdentityStoreFactory - this factory knows about all the
>     built-in IdentityStore implementations and can create IdentityStore
>     instances based on their corresponding IdentityStoreConfiguration.
>      If a
>     developer wished to provide their own IdentityStore though (or
>     override
>     the behaviour of one of the built-in ones) then we need to provide a
>     hook to allow them to override the default factory with their own.
>      This
>     is provided by the IdentityManager.setIdentityStoreFactory()
>     method - by
>     invoking this method with a new IdentityStoreFactory the developer can
>     provide an alternative factory for creating IdentityStore instances
>     based on non built-in configurations before bootstrap() is called.
>
>     Here's an example where the built-in identity stores are supplemented
>     with support for a native Hibernate-based identity store:
>
>     IdentityManager identityManager = new DefaultIdentityManager();
>
>     DefaultIdentityStoreFactory factory = new
>     DefaultIdentityStoreFactory();
>     factory.mapConfiguration(HibernateIdentityStoreConfiguration.class,
>     HibernateIdentityStore.class);
>     identityManager.setIdentityStoreFactory(factory);
>
>     identityManager.bootstrap(identityConfig, new
>     DefaultIdentityStoreInvocationContextFactory(null));
>
>     The last piece of the puzzle is the second parameter to the
>     bootstrap()
>     method.  This parameter should be an instance of
>     IdentityStoreInvocationContextFactory (I know, it's a mouthful),
>     an SPI
>     interface that declares a single method:
>
>     public interface IdentityStoreInvocationContextFactory {
>          IdentityStoreInvocationContext getContext(IdentityStore store);
>     }
>
>     The implementation of this interface is responsible for creating
>     IdentityStoreInvocationContext instances, which are passed as a
>     parameter value to pretty much all of the IdentityStore methods and
>     allow the IdentityStore implementation to be shared between multiple
>     threads (i.e. a stateless design).  The IdentityStoreInvocationContext
>     is responsible for providing the IdentityStore with any state (besides
>     the IdentityStore configuration) required to execute its requested
>     operation.  It also provides a gateway to the event bridge, which
>     allows
>     events to be raised during an IdentityStore operation and
>     propagated to
>     any environment, such as the CDI event bus.  The
>     IdentityStoreInvocationContext implementation/s are currently still a
>     work in progress, however the basic API should not change.
>
>     This essentially wraps up the description of the configuration
>     API. What
>     I haven't touched upon yet are the builders (classes that parse a
>     configuration source such as a file to create an
>     IdentityStoreConfiguration) however I'm hoping Anil that you might
>     want
>     to have a go at this.
>
>     With these changes comes a small TO-DO list:
>
>     1) IdentityStoreConfiguration implementations should be created in the
>     API module within the org.picketlink.idm.config package for each
>     of the
>     IdentityStore implementations (we already have one for LDAP, but it
>     needs to be moved and possibly renamed to
>     LDAPIdentityStoreConfiguration
>     for consistency).
>
>     2) During the course of the refactor I had to provide workarounds for
>     many of the tests, and I also managed to totally break quite a few
>     others.  The test suite needs a quick review to see why the tests are
>     broken, and once configurations are provided for the other identity
>     stores the workarounds can be removed.
>
>     3) The getFeatureSet() method should be correctly implemented for all
>     IdentityStores.  With the change to the configuration API we now have
>     proper support for partitioning, and it's important that this method
>     accurately reflect the underlying capabilities of the IdentityStore
>     implementation for this feature to work correctly.
>
>     Thanks for listening, and I'm looking forward to getting some feedback
>     on this!
>
>     Shane
>     _______________________________________________
>     security-dev mailing list
>     security-dev at lists.jboss.org <mailto:security-dev at lists.jboss.org>
>     https://lists.jboss.org/mailman/listinfo/security-dev
>
>
>
>
> -- 
> Jason Porter
> http://lightguard-jp.blogspot.com
> http://twitter.com/lightguardjp
>
> Software Engineer
> Open Source Advocate
>
> PGP key id: 926CCFF5
> PGP key available at: keyserver.net <http://keyserver.net>, 
> pgp.mit.edu <http://pgp.mit.edu>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/security-dev/attachments/20121106/ef691a12/attachment.html 


More information about the security-dev mailing list