IT:AD:Unity:HowTo:Interception/Raising Exceptions
Summary
When creating an AOP Interception for Authorisation purposes, you'll want to return an AuthorisationException of some kind if the current Principal doesn't have sufficient privileges.
Process
The basic principals of raising Exceptions are:
Regarding throwing Exceptions: http://msdn.microsoft.com/en-us/library/ff660871(v=pandp.20).aspx
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
GregorianCalendar cal = new GregorianCalendar();
DayOfWeek weekDay = cal.GetDayOfWeek(DateTime.Now);
if ((weekDay == DayOfWeek.Saturday) || (weekDay == DayOfWeek.Sunday))
{
// Create the exception to return and the return message.
Exception ex = new Exception("Available on weekdays only");
IMethodReturn msg = input.CreateExceptionMethodReturn(ex);
return msg;
}
else
{
// Do nothing except invoke the next handler.
return getNext()(input, getNext);
}
}
In an authorisation scenario, this comes out as:
/// <summary>
/// An AOP Call Handler registered within
/// <see cref="ScanAndRegisterSecurityBindingsInitializationStep"/>
/// (an Initialization step)
/// to monitor all Service Facade calls.
/// </summary>
public class AuthenticationCallHandler : ICallHandler
{
IAuthorisationByMethodService AuthorisationByMethodService
{
get
{
return _authorisationByMethodService ??
(_authorisationByMethodService =
XAct.Services.ServiceLocatorService.Current.GetInstance<IAuthorisationByMethodService>());
}
}
private IAuthorisationByMethodService _authorisationByMethodService;
public AuthenticationCallHandler()
{
}
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
MethodInfo methodInfo = (MethodInfo) input.MethodBase;
//Once we have the method, we can pass it to a service to
//see how the current principal fits within a matrix of Roles to Methods:
bool result = this.AuthorisationByMethodService.AuthenticatePrincipalByMethod(methodInfo);
if (!result)
{
Exception exception;
exception = System.ServiceModel.OperationContext.Current != null
? (Exception)
new FaultException<InvalidCredentialException>(new InvalidCredentialException(methodInfo.Name),
new FaultReason(typeof(InvalidCredentialException).Name),
new FaultCode(typeof(InvalidCredentialException).Name))
: new InvalidCredentialException(methodInfo.Name);
IMethodReturn resultException = input.CreateExceptionMethodReturn(exception);
return resultException;
}
//If it's not valid, what do we do?
////service.Trace.AppendLine(entryAttrib.Message);
//Put any logic here you would like to invoke BEFORE the method is invoked.
//Console.WriteLine("Before method Invocation happened");
//This invokes the next item in the Injection pipeline, or eventually
//calls your method
var methodReturn = getNext().Invoke(input, getNext);
return methodReturn;
}
}