> On Nov 10, 2015, at 1:52 AM, Jan Sindberg <[email protected]> wrote:
> 
> Well, it is mostly a question of personal taste, architectural style and 
> secure programming. If a Permission is really a value-object, then it should 
> be immutable once created (personal opinion). I could use annotations to make 
> my objects immutable. 
> I show my own wrapper below.
> 

Yes I can see why you say that.  I never worried too much about (before) it 
because Fortress treats perms as a value object (noun) instead of a privilege 
to an action (verb).  There are no heavy resources being consumed during 
construction.  The permission gets created, used in a checkAccess and thrown 
away (usually).  There is no real value in caching because it relatively 
inexpensive to create a new one.

On the other hand, there is no reason it shouldn’t be made immutable.  That is 
I can’t see a use case where we’d change one of the attributes after it first 
gets setup.  

> 
> On Nov 10, 2015, at 1:52 AM, Jan Sindberg <[email protected]> wrote:
> 
>> 
>> Regarding your question about using/storing manager and session objects
>> globally…
>> 
>> All of the manager objects are threadsafe, may be created, held, and reused
>> across multiple thread contexts without concern.  On the other hand, they
>> are also relatively cheap to create, so no real concern if you want to create
>> and throw them away on every usage.
>> 
>> One word of caution wrt multienancy - manager’s are scoped to a single
>> tenant, and your usages need to be aware of that scoping, if processing in a
>> multitenant context.
>> 
>> The session object is not thread safe (like all other fortress entities) so 
>> bear
>> that in mind as you build your system.
>> 
>> Hope this helps,
>> 
>> Shawn
> 
> Still new to session management and thread issues. I am looking at Shiro and 
> consider if I want to use that as API and Apache Fortress as Realm. Shiro 
> handles sessions and also allows multiple Realms.
> Here is what my current homebrew experiment looks like.:
> 
> // Singleton to hold instances
> // setPrincipal should be called where users are logged in and out.
> public class SecurityUtil
> {
>  private static SecurityUtil ourInstance = new SecurityUtil();
>  ThreadLocal<Principal> infoThreadLocal = new InheritableThreadLocal();
> 
>  public static SecurityUtil getInstance()
>  {
>    return ourInstance;
>  }
> 
>  private SecurityUtil()
>  {
>  }
> 
>  public void setPrincipal(Principal _principal)
>  {
>    this.infoThreadLocal.set(_principal);
>  }
> 
>  public Principal getPrincipal()
>  {
>    return (Principal) this.infoThreadLocal.get();
>  }
> 
>  /**
>   * Todo
>   * @return
>   */
>  public boolean initializePrincipal()
>  {
>    return false;
>  }
> }
> 
> // The principal holds the session and the accessMgr.
> // This allows for each principal to have individually configured accessMgr.
> // You might want to subclass this to add you own user object, etc.
> public class Principal
> {
>  private AccessMgr accessMgr;
>  private Session session;
> 
>  protected AccessMgr getAccessMgr()
>  {
>    return accessMgr;
>  }
> 
>  protected void setAccessMgr(AccessMgr _accessMgr)
>  {
>    accessMgr = _accessMgr;
>  }
> 
>  public Session getSession()
>  {
>    return session;
>  }
> 
>  public void setSession(Session _session)
>  {
>    session = _session;
>  }
> 
>  // Should not be used outside this package
>  // See PermissionObject
>  public protected checkAccess(Permission _permission)
>  {
>    // Do audit log ?
>    //...
> 
>    boolean result = false;
>    if (session.isAuthenticated())
>    {
>      try
>      {
>        result = accessMgr.checkAccess(session, _permission);
>      }
>      catch (org.apache.directory.fortress.core.SecurityException e)
>      {
>        e.printStackTrace();  //todo
>      }
>    }
>    return result;
>  }
> }
> 
> // A simple class to express a permission with an operation
> public class PermissionObject
> {
>  private String objName;
>  private String opName;
>  private Permission permission;
> 
>  public PermissionObject(String _objName, String _opName)
>  {
>    objName = _objName;
>    opName = _opName;
>    permission = new Permission(_objName, _opName);
>  }
> 
>   public boolean authZ()
>   {
>     boolean result = false;
>     Principal principal = SecurityUtil.getInstance().getPrincipal();
>     if (principal != null)
>     {
>       result = principal.checkAccess(permission);
>     }
>     return result;
>   }
> 
>  public boolean authZ(String _objId)
>  {
>    boolean result = false;
>    Principal principal = SecurityUtil.getInstance().getPrincipal();
>    if (principal != null)
>    {
>      result = principal.checkAccess(new Permission(objName, opName, _objId));
>    }
>    return result;
>  }
> }
> 
> // A collection of permissions.
> // This is the application or domain specific permissions to be used
> public class FMPerm_Letters
> {
>  private static String name = "LETTERS";
>  public static final PermissionObject EDIT_CONSIGNMENT_LETTER = new 
> PermissionObject(name, "EDIT_CONSIGNMENT_LETTER");
>  public static final PermissionObject EDIT_WITHDRAWAL_LETTER = new 
> PermissionObject(name, "EDIT_WITHDRAWAL_LETTER");
>  ....
> }
> 
> // A very simplified example of usage
> public class SomeDataObject {
> 
>  public Button getEditConsignmentLetterButton()
>  {
>     If (EDIT_CONSIGNMENT_LETTER.authZ()) {
>         return ButtonBuilder.getEditConsignmentLetter();
>     }
>     else {
>        return null;
>     }
>  }
> }
> 
> A nicer solution would be to use annotations on the getter-methods instead. 
> But that's an example for another time. The inner workings of the annotation 
> would be somewhat similar but determining return value by reflection and 
> application specific requirements.

I’ll have to study your example a bit before I can comment too much.  It would 
help if you could add some commentary about it.  What are the requirements that 
are missing, or otherwise not being satisfied unless one uses the system in 
this way?

What I can say (now) is I’ve been thinking lately about using apache shiro as 
the api (policy enforcement) but mapping the policy decision point to fortress 
- meaning it still uses fortress style rbac as the back end.  That way we take 
advantage of shiro’s integration with more platforms while still retaining 
fortress style administration and ldap management capability.    

Shawn

Reply via email to