On 14 Nov 2012, at 00:26, Shane Bryzak wrote:
I'd like to go through the proposed design for Realms and
Applications in detail, as this is quite an important feature to get right and we all need
to be on the same page with this before we proceed.
To start with the basics, let's look at the relationship between Realms and
Applications:
Each realm is a totally segregated "island" of identity state, with no
crossover of state between the realms. Applications, Users, Groups and Roles only exist
within the scope of their containing realm. Realms are top level constructs, and due to
reasons of complexity and practicality we don't support a Realm "hierarchy";
i.e. there are no Realms within Realms.
Let's take a look next at how Users and Groups fit into this:
All User and Group objects are first class citizens within a Realm. If we think of this
in terms of the corporate model, a company may be represented by a single Realm, with its
employees as Users. Each department and sub-division could be represented as a Group,
with Users (employees) belonging to one or more of these Groups. There is also a
hierarchy for Groups, which allows greater flexibility in defining the company structure.
Let's take a closer look at how this structure is defined:
Each User can be a member of zero or more Groups, while each Group may be a subgroup of
one parent Group.
Let's take a look at Roles next. While both Users and Groups sit at the top level of
the Realm, Roles are all application specific:
Each Application may define zero or more Roles, each of which may be used within the
scope of the Application's authorization rules to determine the appropriate privilege
levels for Users. Roles may be granted to either a User or a Group, as illustrated by the
following diagram:
Each role may be granted as an Application Role (i.e. a Role membership that has no Group
component) or as a "standard" Role (which does have a Group component). An
Application Role is used to grant broad application privileges to a select User or Group,
for example you might wish to grant an Application-specific "admin" role to all
members of the "/employees/itdepartment/managers" Group. A standard role is
used when you wish to grant a Group-specific privilege to either an individual User or a
Group of Users, for example granting a User the Role "TechSupport" for the Group
"/department/cardiology/doctors".
So in summary, PicketLink will support:
1) Realms, which represent top level boundaries of segregated identity state, and are
arranged in a flat (rather than hierarchical) structure.
2) Applications, which essentially represent a group of services and resources.
3) Roles, which are specific to an Application and are defined for the purpose of
controlling access to the services and resources provided by the Application.
4) Users, a top level construct within a Realm that represents an entity that may access
the services and resources provided by one or more Applications.
5) Groups, another type of top level construct within a Realm, arranged within a
hierarchical structure and that may be used to define broader associations of Users and
sub-Groups for the purpose of assigning coarse-grained privileges to an Application's
services and resources.
Impact on Identity Management API
-----------------------------------------------
One of the most important factors in implementing support for Realms and Applications is
the impact on the IDM API. As a primary goal for PicketLink is to provide a simplified
API for developers, this support must be provided in a manner that doesn't pollute the
API with unnecessary complexity. To that end, let's start by looking at the simplest
use case, in which a developer embeds PicketLink into their own application.
Default Realm and Application
--------------------------------------
To allow for a developer to use PicketLink in the simplest way possible, I propose that
we introduce the concept of a "default" Realm and "default"
Application. By doing this, we can allow the developer to simply use the basic PicketLink
API without having to be aware of these more advanced features. For example, let's
pretend that the developer wants to create a new User:
User user = new SimpleUser("jsmith");
If we were forcing the developer to deal with Realms and Applications, they would then
have to write something like this to create the new User:
identityManager
.forRealm("default")
.createUser(user);
However by assuming that an unspecified Realm is the "default" realm, the code
looks like this:
identityManager
.createUser(user);
If the default Realm doesn't exist at the time, it will be created automatically (the
same goes for the default Application).
Likewise, when creating a new Role:
Role role = new SimpleRole("admin");
The developer would have to write the following code if we didn't support a default
application:
identityManager
.forApplication("default")
.createRole(role);
If we do support a default though, the code looks like this:
identityManager
.createRole(role);
As a side note, the above examples are slightly contrived because the forRealm() and
forApplication() methods wouldn't accept a String (rather they'd expect either a
Realm or Application object) - this leads us into our next point.
Realm and Application Management
----------------------------------------------
To properly support Realms and Applications we will require a number of management
methods, similar to what we have for Users, Groups and Roles. I propose the addition of
the following methods to IdentityManager:
void createRealm(Realm realm);
Realm getRealm(String realm);
void removeRealm(Realm realm);
Collection<Realm> getRealms();
void createApplication(Application application);
Application getApplication(Realm realm, String application);
void removeApplication(Application application);
Collection<Application> getApplications(Realm realm);
This obviously requires the addition of two new classes to the model API also, Realm and
Application:
public class Realm {
private String name;
public Realm(String name) {
this.name = name;
};
public String getName() {
return name;
}
}
public class Application {
private Realm realm;
private String name;
public Application(Realm realm, String name) {
this.realm = realm;
this.name = name;
}
public Realm getRealm() {
return realm;
}
public String getName() {
return name;
}
}
Usage
--------
One other thing I'd like to discuss is usage scenarios, specifically in Java EE6
applications. I'd like to propose that we provide a producer method that supports the
following form of injection for the IdentityManager:
First of all, injecting an IdentityManager that uses the default Realm and default
Application (the most common use case for embedded PicketLink):
@Inject IdentityManager identityManager;
Secondly, injecting an IdentityManager for a specific Realm:
@Inject @ForRealm("public") IdentityManager identityManager;
Lastly, injecting an IdentityManager for a specific Application:
@Inject @ForRealm("public") @ForApplication("forums") IdentityManager
identityManager;
This seems good, except we should allow for creating annotations to represent realms,
applications etc. A bit like resource producers.
It would also be nice if we could provide support for "configure once", where
the developer can configure a specific Realm and Application and any injected
IdentityManager would default to using them. There's probably a few different ways to
achieve this, so if anyone has a preference please let me know.
Summary
------------
This pretty much describes the entire proposal for Realms and Applications. I'd like
all stakeholders to please carefully review the design, in particular the 5 summary points
that describe the restrictions of this model. If we all agree on this, then we should be
able to release a stable version of the API very shortly. Some further work may be
required the bring the configuration and some IdentityStore implementation details inline
with the new design, but that won't affect the API.
Thanks!
Shane
_______________________________________________
security-dev mailing list
security-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/security-dev