public async Task CheckAccess(AuthorizeOperation operation, params object[] criteria) { if (criteria == null) { throw new ArgumentNullException(nameof(criteria)); } if (IsRegistered) { var methods = AuthorizationRules(operation); var methodFound = false; foreach (var ruleMethod in methods) { var method = ruleMethod.Method; if (method.GetParameters().Count() == criteria.Length) { var parameterTypes = method.GetParameters().Cast <ParameterInfo>().Select(p => p.ParameterType).GetEnumerator(); var criteriaTypes = criteria.Select(c => c.GetType()).GetEnumerator(); var match = true; parameterTypes.MoveNext(); criteriaTypes.MoveNext(); while (match && parameterTypes.Current != null && criteriaTypes.Current != null) { if (!parameterTypes.Current.IsAssignableFrom(criteriaTypes.Current)) { match = false; } parameterTypes.MoveNext(); criteriaTypes.MoveNext(); } if (match) { // Only allow one; maybe take this out later // AuthorizationRules should be stringent if (methodFound) { throw new AuthorzationRulesMethodException($"More than one {operation.ToString()} method with no criteria found in {ruleMethod.AuthorizationRule.GetType().ToString()}"); } methodFound = true; IAuthorizationRuleResult ruleResult; var methodResult = method.Invoke(ruleMethod.AuthorizationRule, criteria); var methodResultAsync = methodResult as Task <IAuthorizationRuleResult>; if (methodResultAsync != null) { await methodResultAsync; ruleResult = ((IAuthorizationRuleResult)methodResultAsync.Result); } else { ruleResult = ((IAuthorizationRuleResult)methodResult); } if (!ruleResult.HasAccess) { throw new AccessDeniedException(ruleResult.Message); } } } } if (!methodFound) { throw new AccessDeniedException($"Missing authorization method for {operation.ToString()} with criteria [{string.Join(", ", criteria.Select(x => x.GetType().FullName))}]"); } } }
public async Task CheckAccess(AuthorizeOperation operation) { if (IsRegistered) { var methods = AuthorizationRules(operation); var methodFound = false; foreach (var ruleMethod in methods) { var method = ruleMethod.Method; if (!method.GetParameters().Any()) { // Only allow one; maybe take this out later // AuthorizationRules should be stringent if (methodFound) { throw new AuthorzationRulesMethodException($"More than one {operation.ToString()} method with no criteria found in {ruleMethod.AuthorizationRule.GetType().ToString()}"); } methodFound = true; IAuthorizationRuleResult ruleResult; var methodResult = method.Invoke(ruleMethod.AuthorizationRule, new object[0]); var methodResultAsync = methodResult as Task <IAuthorizationRuleResult>; if (methodResultAsync != null) { await methodResultAsync; ruleResult = ((IAuthorizationRuleResult)methodResultAsync.Result); } else { ruleResult = ((IAuthorizationRuleResult)methodResult); } if (!ruleResult.HasAccess) { throw new AccessDeniedException(ruleResult.Message); } } } if (!methodFound) { throw new AccessDeniedException($"Missing authorization method for {operation.ToString()} with no criteria"); } } }