WCF PrincipalPermission

In my previous post, I was using PrincipalPermissionAttribute, the limitation of this solution is, developers have to hardcode the authorized role list into code. To improve it, we can call Demand() method explicitly.


// WCF Service
public void DeleteEmailRole(EmailRoleDto emailRoleDto)
 {
// Will throw SecurityException and then WCF will convert it to SecurityAccessDeniedException
// to WCF client side, so we don't need add SecurityException to Contract, because it will not be
    // caught as FaultException.
    AuthorizationChecker.CheckPermissionForCurrentUserOn("DeleteEmailRole");
EmailService.Delete(emailRoleDto);
 }

public class AuthorizationChecker : IAuthorizationChecker
 {
private readonly IAuthRoleRepository _authRoleRepository;

public AuthorizationChecker(IAuthRoleRepository authRoleRepository)
{
_authRoleRepository = authRoleRepository;
}

/// <summary>
/// Can be used by UI to enable/disable buttons/menus.
/// </summary>
public bool IsCurrentUserAllowedTo(string serviceName)
{
try
{
CheckPermissionForCurrentUserOn(serviceName);
}
catch (SecurityException)
{
return false;
}

return true;
}

public void CheckPermissionForCurrentUserOn(string serviceName)
{
IPermission permissionSet = null;

foreach (var role in
_authRoleRepository.FetchAllRolesHavingAccessTo(serviceName))
{
var permission = new PrincipalPermission(null, role);
permissionSet = permissionSet == null ?  permission : permissionSet.Union(permission);
}

// Demand will throw Security exception if user has no permission defined in authRoleRepository.
if (permissionSet != null) permissionSet.Demand();
}
 }

// Client code
protected void HandleException(Exception e)
{

if (e is SecurityAccessDeniedException)
{
_messageBox.Show("Sorry you don't have permission to this method.\n" + e.Message);
throw e;
}

}

Advertisements