/// <summary> /// Specifies an authorization rule for a principal applying a specific command type to a specific resource type. /// </summary> /// <param name="requirement">The requirement.</param> /// <param name="message">A message indicating the reason for the authorization failure. This message is intended for diagnostic and monitoring purposes only.</param> public static void Requires(Func <TPrincipal, TCommand, TResource, bool> requirement, string message = null) { ValidateTypeParameters(); ValidationPlan <IAuthorizationQuery <TResource, TCommand, TPrincipal> > plan = AuthorizationPolicy.For <TResource, TCommand, TPrincipal>().ValidationPlan; var defaultRule = AuthorizationPolicy <TResource, TCommand, TPrincipal> .Default; if (plan.Any(rule => rule == defaultRule)) { // the default rule will cause the authz check to fail, so we remove it plan.Remove(defaultRule); } var authzRule = Validate .That <IAuthorizationQuery <TResource, TCommand, TPrincipal> >(query => requirement(query.Principal, query.Command, query.Resource)) .WithErrorMessage(message ?? ("Requirement for " + typeof(TCommand))); plan.AddRule(authzRule); }