On Wed, Mar 14, 2012 at 12:05 PM, Andy Dennie <[email protected]> wrote:
> That's a useful technique, and I think I followed most of it, but let me
> confirm a few things. I infer that your YourApplication.*Filtered methods
> instantiate *Filter classes (passing their arguments, excluding the last,
> to the *Filter constructor), and chaining that *Filter to the final
> argument, which is the next Restlet in the chain. Yes?
Yes, e.g.,
protected Restlet xFiltered(XParam1 x1, XParam2 x2, Restlet next) {
return new XFilter(getContext(), x1, x2, next);
}
What does YourApplication.of() do?
Creates a Finder from the resource type, e.g.:
protected Restlet of(Class<? extends ServerResource> resourceType) {
return createFinder(resourceType);
}
> So you do your authenticating and enroling via filters, then do your
> role-based authorization in your resource methods?
>
No, I use a custom Enroler with a RoleAuthorizer. I convey additional
information obtained during authentication (by a custom Verifier) via
clientInfo.principals.
It's equivalent to something like this:
router.attach("/foo", guarded(of(FooServerResource.class), ROLE1,
ROLE2));
where guard is:
protected Restlet guarded(Restlet next, Role... roles) {
RoleAuthorizer authorizer = new RoleAuthorizer();
authorizer.setAuthorizedRoles(roles);
authorizer.setNext(next);
return authorizer;
}
> I suspect I'll need something like that down the road. Right now my only
> role is "admin", but I'll have more later. But do all of your requests need
> to be authenticated?
>
No.
> I need to allow unauthenticated GETs, so I still need to figure out how
> to authenticate in some cases and not others,
>
If the choice of whether to authenticate needs to be done at the resource
level, then clearly the authorization has to be done there, too. Otherwise
(i.e., choice made at routing time) it comes down to whether you wrap your
resources with guarded or not (or the equivalent).
Before you roll your own MethodRoleAuthorizer, however, consider whether it
> wouldn't be more natural to have multiple resources with different
> authorization levels instead of a single resource with a different
> authorization level for each method.
>
> That's actually what I'm doing now, with the same logical resource being
> exposed via two URIs, e.g. /unauthenticateduser/someresource and
> /admin/someresource. But the proliferation of classes is kind of a
> hassle. And I got to thinking -- if there's one logical resource, does it
> really make sense for different users to use different URIs to address it?
> I realize that there can be legitimate reasons to have the same resource
> addressable by multiple URIs (e.g. /users/andy/hometown and
> /users/johndoe/hometown), but in this case, I felt like I was altering my
> API to work around Restlet's idiosyncrasies, which seemed like a Bad Thing.
There's no right or wrong way here. It depends on whether you see it more
as a single resource with a not-quite-uniform interface (different clients
effectively get different responses to OPTIONS), or closely-related
resources, each with a uniform interface.
Like I said, I don't use that technique I sketched, since in my case
non-uniformity is the exception rather than the rule.
That's a good technique to keep in mind, and the public static classes
> would at least tamp down on the class file proliferation.
>
Yup. I hadn't really thought about it until you asked; I'm glad you did!
A potentially useful variation would be to keep the resource interfaces
unrelated (i.e., have ProtectedFooResource *not* extend PublicFooResource),
so you can mix in different sets of functionality all based on a single
abstract implementation. That would address the needs of those who want to
write one ServerResource implementation for Things and collections of
Things, e.g.,
router.attach("/user/", UsersServerResource.class);
// extends AbstractUserServerResource implements UsersResource
router.attach("/user/{user}", UserServerResource.class);
// extends AbstractUserServerResource implements UserResource
--tim
------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2935667