MSDN Magazine - October 2008 - (Page 66) Aside from programmatically calling IsInRole to perform rolebased security checks, there is also an attribute called PrincipalPermissionAttribute that allows you to annotate your service operations with role requirements. PrincipalPermissionAttribute will signal a negative authorization outcome to your client by throwing a SecurityException prior to executing the service operation. WCF will catch this exception and turn it into an Access Denied fault message that is returned. The WCF client plumbing will turn this special fault into a .NET exception of type SecurityAccessDeniedException. Figure 1 shows the various ways to do a role check and perform error handling. The ServiceAuthorization service behavior controls the creation of the IPrincipal instance to be associated with the request thread. By default, WCF assumes Windows authentication and tries to populate Thread.CurrentPrincipal with a WindowsPrincipal. When your clients are not Windows users, you have the choice between getting roles from an ASP.NET role provider or implementing a custom authorization policy in order to get the roles from a custom database. Another alternative is to implement a custom IPrincipal type and then take complete control over the IsInRole implementation. Figure 2 6DPSOH5ROH3URYLGHUDQG&RQ¾JXUDWLRQ(QWULHV Role Provider class CustomRoleProvider : RoleProvider { public override string[] GetRolesForUser(string username) { if (username == 'administrator') { return new string[] { 'administrators', 'users' }; } else { return new string[] { 'sales', 'marketing', 'users' }; } } public override bool IsUserInRole(string username, string roleName) { return GetRolesForUser(username).Contains(roleName); } } <serviceAuthorization principalPermissionMode='UseAspNetRoles' roleProviderName='CustomProvider' ASP.NET Role Provider WCF can use an ASP.NET role provider to retrieve roles for a user. You can either use one of the built-in providers (for SQL Server or Microsoft Authorization Manager) or write one of your own by deriving from System.Web.Security.RoleProvider. To make the connection to the role provider, WCF attaches a RoleProviderPrincipal to the executing thread that forwards all calls to IsInRole to the role provider’s IsUserInRole method. This method takes the user name and role in question and returns true if the user is a member of that role and false if not. Figure 2 shows a sample custom role provider along with the necessary configuration entries. WCF will call the role provider for every role check that occurs in your service. If you have a lot of role checks, it would be beneficial to implement some sort of caching strategy to avoid excessive round-trips to the role store. Customizations like caching could be implemented in the role provider itself or via a custom IPrincipal implementation. That’s the next option we will explore. Custom Principal Another option is to supply your custom IPrincipal implementation to WCF. This gives you the chance to implicitly run code after the authentication stage of each request. For this you have to create your own custom principal and return it to the WCF plumbing. The custom principal will then be available from Thread.CurrentPrincipal to the service code. Custom principals allow full customization of role-based security and expose specialized security logic for the service developer to use. 66 msdn magazine Service Station http://www.steema.com
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.