I needed to authorize some pages not just by annotation but also based on
PageParameters.
I came up with this:
App.init()
((CompoundAuthorizationStrategy)getSecuritySettings().getAuthorizationStrategy())
.add(new RequiresRolesUnlessAdminAuthorizationStrategy(new
Roles("ADMIN")));
public interface IRequiresRole
{
Roles requiresRoles();
}
public class ProfilePage extends MyWebPage implements IRequiresRole
{
private String id;
public ProfilePage(PageParameters p) {
id = p.get("id").toString();
}
public Roles requiresRoles() {
return new Roles(id); // I'm just using the id as a role for
testing but you can lookup your object and see what roles it needs here
}
}
And the fun one:
public class RequiresRolesUnlessAdminAuthorizationStrategy implements
IAuthorizationStrategy {
private Roles alwaysAllow;
public RequiresRolesUnlessAdminAuthorizationStrategy(Roles alwaysAllow)
{
this.alwaysAllow = alwaysAllow;
}
public boolean isActionAuthorized(Component component, Action action) {
if (component instanceof IRequiresRole)
{
Roles r = ((IRequiresRole) component).requiresRoles();
return AuthenticatedWebSession.get().isSignedIn() &&
(
AuthenticatedWebSession.get().getRoles().hasAllRoles(r)
||
(alwaysAllow != null &&
AuthenticatedWebSession.get().getRoles().hasAnyRole(alwaysAllow))
);
}
return true;
}
public <T extends IRequestableComponent> boolean
isInstantiationAuthorized(
Class<T> componentClass) {
return true;
}
}
So if you are ADMIN you can do anything, otherwise you need whatever role
corresponds to object identified by the PageParameter id.
Am I re-inventing someone's wheel here, or does this sound good?
Thanks,
-- Jim.