[security-dev] Multi-application support for IDM

Anil Saldhana Anil.Saldhana at redhat.com
Mon Nov 12 17:54:50 EST 2012


In practice, there is always a master realm which can have sub realms.  
If you view a corporate company as a realm, then you will have divisions 
as realms and maybe offices as realms too.  Some applications transcend 
divisions/offices (realms)  but are always contained within the master 
realm.

Regarding roles, they can either apply at the realm level such as 
CompanyEmployee, ChicagoEmployee or can also be application specific.

Shane, IMO we should go with the changes you propose.


On 11/12/2012 09:07 AM, Pete Muir wrote:
> This seems to work to me.
>
> On 12 Nov 2012, at 00:56, Shane Bryzak wrote:
>
>> Actually, after some more thought there may be a third option in which
>> we can support both scenarios. Until now we've assumed both "realm" and
>> "application" are the same thing, a kind of "subgrouping" of identity
>> state (the naming of which is even slightly contentious).  However, what
>> if we supported them both?  By introducing a hierarchy with the Realm at
>> the top, we can then support both scenario A (by making both Users and
>> Applications unique within a Realm) and scenario B (by making Realms
>> totally separate to each other).
>>
>> This would require a slightly more complex (but still intuitive) API.
>> Here's some examples based on a fictional paper company:
>>
>> a) Creating a new user "dschrute" in realm "corporate"
>>
>> identityManager
>>      .forRealm(identityManager.getRealm("corporate"))
>>      .createUser(new SimpleUser("dschrute"));
>>
>> b) Adding this new user to the "sales" Group, in application "cms":
>>
>> Realm corporate = identityManager.getRealm("corporate");
>> Application cms = identityManager.getApplication(corporate, "cms");
>> Group sales = identityManager.getGroup(cms, "sales");
>> User user = identityManager.getUser(corporate, "dschrute");
>>
>> identityManager
>>      .forApplication(cms)
>>      .addToGroup(user, sales);
>>
>> c) Creating a retail customer user and adding them to the "customers" group:
>>
>> Realm retail = identityManager.getRealm("retail");
>> Application onlineSales = identityManager.getApplication(retail,
>> "onlineSales");
>> User user = new SimpleUser("bvance");
>> Group customers = identityManager.getGroup(onlineSales, "customers");
>>
>> identityManager
>>      .forRealm(retail)
>>      .createUser(user);
>>
>> identityManager
>>      .forApplication(onlineSales);
>>      .addToGroup(user, customers);
>>
>>
>>  From the above examples, we can see that Users are specific to Realms,
>> while Groups, Roles and Memberships are specific to Applications.  I'm
>> kind of wondering if we should make Group unique to the Realm instead of
>> the Application (and just leave Roles and Memberships as
>> Application-specific) as this might be a more sensible structure when it
>> comes to modeling real life scenarios.  If you have an opinion either
>> way please let me know what you think.
>>
>>
>> On 11/12/2012 10:19 AM, Shane Bryzak wrote:
>>> I think we need to decide on exactly what level of identity segregation
>>> is going to be supported between each realm/application.  One possible
>>> scenario (let's call it scenario A) is that a single User might have
>>> access to multiple applications, but different permissions within those
>>> applications.  In this scenario, there would be a single User record,
>>> then a separate set of Role/Group/Membership records for that User
>>> within each realm/application.  An example use case for this might be
>>> jboss.org, where a User uses their JBoss login to access multiple
>>> "applications" (for example JBoss Forums, JIRA, Wiki, etc).
>>>
>>> Scenario B is what I would describe as the "multi-tenant" scenario,
>>> where a single identity store may be used to serve multiple, separate
>>> applications.  In this scenario, each realm/application has its own User
>>> database which exists for that realm alone.  In contrast to scenario A,
>>> User "jsmith" in one realm would be a totally different User record to
>>> "jsmith" in another realm.
>>>
>>> I think we need to make a firm decision on this before we proceed any
>>> further.
>>>
>>> On 11/10/2012 01:34 AM, Pete Muir wrote:
>>>> Inline.
>>>>
>>>> On 8 Nov 2012, at 17:08, Bolesław Dawidowicz wrote:
>>>>
>>>>> Both scenarios. For example we have a default realm/application used by
>>>>> several webaps - they all just share idm data. Most simple usecase is
>>>>> company wide IDM service with all the stuff roster and etc. Then few
>>>>> other webapps have isolated user data.
>>>> Agreed, we're going to need both scenarios in order to support some sort of IDM service, that can serve multiple applications, regardless of whether it is in VM or remote.
>>>>
>>>>> I imagine we should have some flexibility in the configuration. So
>>>>> default is that each "application" contains separate isolated IDM data.
>>>>> Either it is single IdentityStore implementation or one shared instance
>>>>> supporting multitenency. I think it should be also possible to
>>>>> preconfigure some application/realm with fixed IdentityStore instance -
>>>>> like for LDAP. Then in second case question is how to implement it.
>>>>> Putting everything in one table schema won't scale well with growing
>>>>> number of applications so I imagine another option would be to to have
>>>>> isolated table set per application.
>>>> I have a feeling that we should be quite flexible here. One way to do this that I think could work, and keeps the programming model quite normalised is to provide some sort of MultiplexingIdentityStore out of the box, which is capable of routing the request to the right actual identity store.
>>>>
>>>>> Basically cloud use case mentioned before requires adding new isolated
>>>>> application/realm on the fly without restarting the service.
>>>>>
>>>>> So this method
>>>>> void createApplication(Application application);
>>>> I think this needs to be up to the IdentityStore impl in use. To carry on my previous point, if you built this around a delegation model, we could provide a base delegating identity store, which the user can override methods on to change the delegation strategies.
>>>>
>>>>> should create isolated space using default JPA store or create new JPA
>>>>> store instance using some defaults.
>>>>>
>>>>> There are some discussions around multitenancy in JPA and Hibernate btw:
>>>>> https://community.jboss.org/wiki/Multi-tenancyDesign
>>>>> https://hibernate.onjira.com/browse/HHH-5697
>>>>>
>>>>> Can be worth checking.
>>>>>
>>>>> On 11/08/2012 03:39 PM, Pedro Igor Silva wrote:
>>>>>> Each application may have/use its own identity store ? Or are we talking about a consolidated store shared by all applications ?
>>>>>>
>>>>>> Today the API only supports one identity store per identity manager instance. Wondering if should provide support for multiple stores too, and give to users features like identity syncronization, for example.
>>>>>>
>>>>>> Regards.
>>>>>> Pedro Igor
>>>>>>
>>>>>> ----- Original Message -----
>>>>>> From: "Bolesław Dawidowicz" <bdawidow at redhat.com>
>>>>>> To: security-dev at lists.jboss.org
>>>>>> Sent: Thursday, November 8, 2012 10:56:20 AM
>>>>>> Subject: Re: [security-dev] Multi-application support for IDM
>>>>>>
>>>>>> I like it very much. Tried to think about proper solution myself
>>>>>> yesterday a bit and didn't manage to come up with anything better. What
>>>>>> I like is that IdentityStore and whole model is not polluted with
>>>>>> something outside of identity objects domain.
>>>> Agreed.
>>>>
>>>>>> Maybe only piece you are missing is some method in IdentityManager to
>>>>>> identify current context it is referring to. getCurrentApplication() ?
>>>> I think this is something that should be provided by the integrator, not by the IDM. The way of establishing the current application varies completely by what wiring you use (e.g. CDI vs JNDI vs MSC vs OSGi etc.) We need to keep the IDM totally free of wiring concepts IMO.
>>>>
>>>> Also, a wiring system typically has a much more flexible approach to this e.g.
>>>>
>>>> @Inject @Current
>>>> Application a;
>>>>
>>>> or
>>>>
>>>> context.lookup("java:comp/Application")
>>>>
>>>>>> I'm not perfectly convinced that application is the proper naming
>>>>>> though. Realm, domain, partition? All in all I imagine that for many
>>>>>> applications it will be handy to reuse same storage space. In
>>>>>> application server environment it would be really handy to just
>>>>>> associate application with some idm context and configure all the rest
>>>>>> with UI console. If we bridge it together with authorization api and
>>>>>> users can easily configure application scoped resources that way it
>>>>>> would be fairly powerful. On the other hand thinking about cloud usecase
>>>>>> name "application" provides quite clear definition of context.
>>>> Tenant? Generally speaking, applications are tenants of the application server, an application can be divided into various tenants etc.
>>>>
>>>>>> As for implementation I think it is useful to both have simple multi
>>>>>> tenant model with application built into schema and clear isolated table
>>>>>> set per application one.
>>>> We split the JPA schema out into a separate module already, which looks like a vey good decision, as now we just produce a simple schema, and a multi-tennant schema for ootb use.
>>>>
>>>>>> Mainly for the sake of scalability. In both
>>>>>> scenarios being able to add new applications on the fly.
>>>>>> IdentityStoreInvocationContext concept is flexible enough to handle it
>>>>>> within single JPAIdentityStore instance
>>>>>> Configuration is probably quite wide separate concern but maybe for a
>>>>>> separate discussion so I won't hijack this thread for it.
>>>>>>
>>>>>> On 11/08/2012 12:27 PM, Shane Bryzak wrote:
>>>>>>> I've been thinking about Bill's request for multi-application support,
>>>>>>> and I think I've come up with a solution that's going to be minimally
>>>>>>> disruptive to the existing API.  For starters, we need to add a few
>>>>>>> methods to IdentityManager to support application management:
>>>>>>>
>>>>>>> void createApplication(Application application);
>>>>>>>
>>>>>>> void removeApplication(Application application);
>>>>>>>
>>>>>>> Application getApplication(String applicationId);
>>>>>>>
>>>>>>> Collection<Application> getAllApplications();
>>>>>>>
>>>>>>> (The getAllApplications() method is necessary as the Query API only
>>>>>>> deals with IdentityTypes, of which Application isn't one).
>>>>>>>
>>>>>>> The next step is to allow the Application to be set somehow for any
>>>>>>> given identity management operation.  I think the easiest way to do this
>>>>>>> is by providing a new method called forApplication():
>>>>>>>
>>>>>>> IdentityManager forApplication(Application application);
>>>>>>>
>>>>>>> The forApplication() method returns an instance of IdentityManager for
>>>>>>> which any operations performed will be within the context of the
>>>>>>> specified Application.  Let's take a look at this in more practical
>>>>>>> terms - for example, pretend we want to grant the "moderator" role to
>>>>>>> user "bill" for the application "JBossForums".  The code would look like
>>>>>>> this:
>>>>>>>
>>>>>>> Application jbossForums = identityManager.getApplication("jbossForums");
>>>>>>>
>>>>>>> IdentityManager im = identityManager.forApplication(jbossForums);
>>>>>>>
>>>>>>> User bill = im.getUser("bill");
>>>>>>> Role moderator = im.getRole("moderator");
>>>>>>> im.grantApplicationRole(bill, moderator);
>>>>>>>
>>>>>>> The selected Application is passed to the underlying IdentityStores via
>>>>>>> the IdentityStoreInvocationContext, to which we will add a
>>>>>>> getApplication() method.  We can also support multi-application
>>>>>>> configuration, where one application might use an LDAP-based identity
>>>>>>> store, while another might use a File-based identity store.
>>>>>>>
>>>>>>> By providing multi-application support in this way, we can maintain the
>>>>>>> existing API (we don't need to refactor every single method to add an
>>>>>>> Application parameter) and for the consumers who don't care about
>>>>>>> multi-application support the feature won't get in their way. We can
>>>>>>> then very easily expose the IDM API as a set of RESTful web services to
>>>>>>> achieve a standalone identity management service.
>>>>>>>
>>>>>>> What do you guys think?


More information about the security-dev mailing list