Hi All.

Here's the "Blow by blow" story.

First, we need an example application for the sake of
discussion.  Let it be a simple web publishing
application.  We have three sorts of users: anonymous
users who read the published articles, authors who
create the articles, and editors who edit articles and
schedule them for publication.

So there are three roles:
Anonymous, Author, and Editor

For this application we'll need some Permissions.
ReadArticle, CreateArticle, EditArticle,
PublishArticle.

And we'll need some Scopes.
AllArticles, PublishedArticles, OwnedArticles

And we need to define our Security Policy.  In other
words, we need to map the scopes and roles and
permissions as appropriate for our application.  For
now I'll use a simple xml format to express the
security policy.

<AuthorizationPolicy>
   <grant>
     <principal class="o.a.t.security.turbine.Role">
       Anonymous
     </principal>
     <scope name="PublishedArticles">
       <permission>ReadArticle</permission>
     </scope>
   </grant>

   <grant>
     <principal class="o.a.t.security.turbine.Role">
       Author
     </role>
     <scope name="OwnedArticles">
       <permission>ReadArticle</permission>
       <permission>CreateArticle</permission>
       <permission>EditArticle</permission>
     </scope>
   </grant>

   <grant>
     <principal class="o.a.t.security.turbine.Role">
       Editor
     </principal>
     <scope name="AllArticles">
       <permission>ReadArticle</permission>
       <permission>EditArticle</permission>
       <permission>PublishArticle</permission>
     </scope>
   </grant>
</AuthorizationPolicy>

I think the following DTD is right, but I'm not
entirely sure.
<!ELEMENT AuthorizationPolicy (grant+)>
<!ELEMENT grant (principal+, scope+)>
<!ELEMENT principal (#PCDATA)>
<!ATTLIST principal class CDATA #REQUIRED>
<!ELEMENT scope (permission+)>
<!ATTLIST scope name CDATA #REQUIRED>
<!ELEMENT permission (#PCDATA)>


With that in mind, here's how I think the system would
work.

When a user visits the application for the first time,
a Subject is attached to their session, and the
AnonymousPrincipal is attached to the Subject.  They
are assumed to be Anonymous unless they login.  As an
anonymous user they are presented with a list of
published articles.

Suppose that the user is an Author who now chooses to
login.  They are challenged to provide a userid and
password to verify their identity.  When those
credentials are verified, the authentication code is
responsible for checking the records about the user and
attaching all appropriate principals to the Subject in
the session.  In the case of an author two Principals
are added: a TurbineUserPrincipal which holds their
UserId, and a Role for "Author".

The authentication code might look like this:

     SecurityManager sm = SecurityManager.getInstance();
     try
     {
         TurbineSubject subject = sm.getSubject(userid,password);
         // put the subject into the session object

         // NOTE:
         // getSubject() is responsible for populating
         // the Subject with its Principals.  In the
         // case of an "author" that code might look
         // like this:
         //   subject.getPrincipals().
         //      add(new TurbineUserPrincipal(userid));
         //   subject.getPrincipals().
         //      add(new Role("Author"));
         //   subject.getPrincipals().
         //      add(new Role("Anonymous"));
         // (no reason not to grant the author the same
         // rights as anonymous users)

     }
     catch (AuthenticationException e)
     {
         // notify user of authentication failure
     }


Once the user is authenticated the application should
now present them with additional options as appropriate
for their permissions.

The template for the articlelist.vm might look like the
following.  Assume for the sake of this conversation
that there's a security manager tool ($sm) and the
Subject ($subject) in the velocity context.

#if ($sm.isPermitted($subject,"OwnedArticles","CreateArticle"))
<a href="$link...">Create Article</a><br>
#end

#if ($sm.isPermitted($subject,"OwnedArticles","EditArticle"))
#foreach ($article in $articles.getArticlesByOwner($subject))
#renderHyperlinkToEditArticle($article)
#end


The tool would load that XML security policy into
memory when it is initialized.  And the isPermitted()
method is responsible for interrogating that structure
to determine if any of the $subject's principals have
been granted the "EditArticle" permission in the
"OwnedArticles" scope.

I trust you'll ask for details where I have not been
clear or complete enough.

-Eric
ps.  I should just add this:  although in my example I
have used Roles to group permissions, it should be
clear from earlier postings that this could just as
easily be Groups (like orgainzational units, or
geographic groups, or whathaveyou).  Similarly, I could
grant a user special permissions by attaching those
permissions to their userid principal.

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to