I'm not really sure what the best/safest approach is here in terms of
integration with .NET framework. I'm apprehensive about violating the
assumptions of the RoleProvider interface (er, abstract class) as it's
very difficult to understand the complete impact with regard to
security. With CAS authentication and assertion-based authorization, we
really can't afford to make assumptions that might compromise the
security of web applications. I'm not sure if this what you're
suggesting or not, so let me know if I'm off the mark.
Assuming you subclassed RoleProvider for the assertion support...
> > // Can't be implemented on read-only providers
> > void AddUsersToRoles(string[] usernames, string[] roleNames);
> > void CreateRole(string roleName);
> > bool DeleteRole(string roleName, bool throwOnPopulatedRole);
> > void RemoveUsersFromRoles(string[] usernames, string[] roleNames);
>
> I'm fairly certain that it's acceptable that some methods can throw
> NotImplementedException in support of a read-only provider.
I think that's correct--at least I know it is for read-only
MembershipProvider implementations. It can be tricky in some cases when
you are following the role implementation guide... Sometimes you should
return null instead of throwing an exception for non-primitive return
types, but these 4 seem like NotImplementedExceptions to me.
> > // Can't be implemented without a list of the entire set of Roles
> > string[] GetAllRoles();
> > bool RoleExists(string roleName);
>
> One option here is to implement these with static data.
Definitely doable, though relatively inflexible.
> > // Can't be implemented without a mapping of all {user, role}'s
> > string[] FindUsersInRole(string roleName, string usernameToMatch);
> > string[] GetRolesForUser(string username);
> > string[] GetUsersInRole(string roleName);
> > string[] GetRolesForUser(string username);
> > bool IsUserInRole(string username, string roleName);
>
> I'm fairly certain we can accommodate authorization use cases without
> a global (user,role) mapping. I believe that it should be sufficient
> to answer questions about the current principal whose data would be
> fully available in the assertion.
If you're still thinking in terms of a .NET RoleProvider implementation,
at the bare minimum you need to implement:
- string[] GetRolesForUser(string username);
- bool IsUserInRole(string username, string roleName);
It would be very dangerous to ignore the username argument and just look
up the roles in the assertion of the current user. These methods need
to support looking at the data for other users in the system, otherwise:
- RoleManagerModule breaks as it relies on GetRolesForUser to populate
its state
- UrlAuthorizationModule breaks as it relies on IsUserInRole
I think Dianne is on the right track with the IPrincipal's
IsUserInRole(...) method, I'm just not sure whether the CasPrincipal
and/or CasAuthenticationModule is the place to do it. It looks like the
CasPrincipal is discarded and replaced with a RolePrincipal during the
PostAuthenticateRequest step by the RoleManagerModule. We might be able
to require 'cacheRolesInCookie' on the Role Provider be set to true in
web.config and have the CasAuthenticationModule stuff the assertion
roles in the cookie in a way that doesn't break the existing
RoleManagerModules implementation (in much the same way that
CasAuthenticationModule generates/validates real
FormsAuthenticationTickets in a way that doesn't interfere with/require
the FormsAuthenticationModule).
Is there a compelling reason to not go to the underlying data source
(i.e., LDAP server) for role lookup? It would simplify the integration.
Here's a pretty good article on how the Role-based authorization stuff
works.
http://www.asp.net/learn/security/tutorial-11-cs.aspx
-ScottH
--
You are currently subscribed to [email protected] as:
[email protected]
To unsubscribe, change settings or access archives, see
http://www.ja-sig.org/wiki/display/JSG/cas-dev