Hi Daniel,
See some answers below.
Daniel L�pez wrote:
>
> Hi Joni,
>
> That sounds pretty interesting, however, I still have some doubts.
> Let's see:
> .- Where do you get the user from (the one you use with
> user.getSubject()). Can these users be specified dynamically through a
> standard interface? Or do they have to be specified in a container
> specific way?
JAAS is not in any way related to user management. Since there's not
(sadly) yet any standard way to do user management I decided to roll my
own. However, this approach should work no matter what kind of user
management is used. Here's some concepts and how the process flows:
- LoginModule (JAAS concept) handles user login. JAAS supports pluggable
login modules which means that it is possible to user different kinds of
login modules without affecting to the rest of the application (e.g. at
some point I could change my login module to use fingerprints instead of
username and passwords).
- Principal (Java security concept) represents some identity for a user
(e.g. Principal("John Doe"), GroupPrincipal("user"),
IdPrincipal(12345-12))
- Subject (JAAS concept) groups one particular user's various Principals
together. So, the Subject is linked to a user.
- Permission (Java security concept) represents a permission for
something. These are usually really simple tag-like objects.
- Policy (JAAS concept) represents access control policy. To get all the
permissions for a user you can use: PermissionCollection pc =
Policy.getPolicy().getPermissions(subject, null);
- User (my implementation) represents a user in a system.
OK, using these concepts the authentication in my system goes:
1. Authenticate user using a configured LoginModules:
LoginContext lc = new LoginContext("DefaultLoginModule",
new LoginCallbackHandler(username,
password));
lc.login(); // This is JAAS's abstraction, actually the call is
eventually dispatched to LoginModule.
2. In the actual LoginModule do the real authentication. This can be
done for instance against RDBMS, LDAP, Solaris user management etc... I
currently a UserManager session bean:
UserManager userManager = userManagerHome.create();
User user = userManager.authenticate(username, new String(password));
3. Fill the user's Subject with the user's Principals if the
authentication succeeds. I currently use two types of Principals: one
which uniquely identifies user (UserIdPrincipal) and one which
represents a group where the user belongs to (GroupPrincipal). I store
this information in an RDBMS and access them through EJB layer:
// Add the identity which uniquely identifies the user.
Set principals = subject.getPrincipals(); // Subject is an object which
created automatically by JAAS.
principals.add(new UserIdPrincipal(user.getId()));
// Add the identities representing the groups for which the user belongs
to.
String[] groupNames = null;
groupNames = userManager.getGroupNamesForUser(user.getId());
for (int i = 0; i < groupNames.length; i++) {
GroupPrincipal p = new GroupPrincipal(groupNames[i]);
if (!principals.contains(p)) {
principals.add(p);
}
}
user.setSubject(subject);
4. Then I cache this information to HttpSession so that it is fast to do
access control on web container layer:
HttpSession session = request.getSession();
session.setAttribute(AttributeConstants.USER, user);
This was the authentication phase. The on subsequent requests the the
user is authorized:
User user = session.getAttribute(AttributeConstants.USER);
Subject subject = user.getSubject();
if (subject != null) {
// This is the permission which is needed for this particular
request.
PagePermission pagePermission = new PagePermission(domain); //
domain is "user", "admin" ...
PermissionCollection pc = Policy.getPolicy().getPermissions(subject,
null);
if (pc.implies(pagePermission)) {
// succeeded.
}
else {
// authorization failed, the user don't have a permission to do
this request
}
}
else {
// Subject == null, the user is not authenticated. Forward to login
page.
}
> .- Can the policy file be specified on a "per web application basis" or
> does it just exist one policy file for the whole system? This way I
> could specify the security of my applications independendently. And
> could this information be extracted from a database/URL instead of a
> system file?
I currently use Sun's reference implementation of JAAS. It ships with
one implementation of Policy which is a file-based subclass called
FilePolicy. Using this implementation it would be a bit awkward to
configure the policy "per web application". Anyway, it should be pretty
simple to do an own implementation of Policy and then configure the
runtime to use it. I guess there might be better implementation's of
Policy in a version which is integrated to JDK 1.4. But I haven't had
time to look into that yet.
Hope this helps! Anyway, since you already have your own implementation
which works, you don't have any hurry to start using JAAS. If I were you
I would swich to JAAS at the same time when you are considering to swich
to JDK 1.4.
--
Joni
[EMAIL PROTECTED]
> Just curious to see how I could use this standard API without losing all
> the flexibility and dynamicity that I've already accomplished with my
> own implementation.
>
> Regards and thanks for the info,
> D.
>
> Joni Suominen wrote:
> >
> > Hi Daniel,
> >
> > JAAS is not necessarily tied to the OS user. Actually you can tie it to
> > the OS user by using proper login modules which can authenticate if a
> > user is already logged into an OS. However, in a true Java spirit, JAAS
> > is much more generic. In fact it is just a framework to implement
> > versatile authentication and authorization schemes. For instance, I
> > authenticate user's against a relational database (some might use LDAP).
> > The JAAS provides abstractions to represent user's identity and
> > permissions. It also provides algortihms to check if configured security
> > policy implies certain permission.
> >
> > Some sample code:
> >
> > PagePermission pagePermission = new
> > PagePermission("admin");
> > PermissionCollection pc =
> > Policy.getPolicy().getPermissions(user.getSubject(), null);
> >
> > if (pc.implies(pagePermission)) {
> > // authorization succeeded...
> > }
> > else {
> > // authorization failed, the current user don't have a permission to
> > view a page on this domain.
> > }
> >
> > Then on policy file I might have:
> >
> > grant Principal org.shiftctrl.framework.security.SCGroupPrincipal
> > "admin" {
> > permission
> > org.shiftctrl.framework.security.permissions.PagePermission "admin";
> > };
> >
> > This way it is easy to implement multiuser Java applications where
> > accesses are controlled on per-user or per-group level. JAAS is also
> > integrated to the JDK 1.4, like the new logging API you mentioned.
> >
> > --
> > Joni
> > [EMAIL PROTECTED]
> >
> <snipped...>