/// <summary> /// Create a local security policy /// </summary> public AdoSecurityPolicy(DbSecurityPolicy policy) { this.CanOverride = policy.CanOverride; this.Key = policy.Key; this.Name = policy.Name; this.Oid = policy.Oid; this.IsActive = policy.ObsoletionTime == null || policy.ObsoletionTime < DateTimeOffset.Now; if (!String.IsNullOrEmpty(policy.Handler) && !s_handlers.TryGetValue(policy.Handler, out this.m_handler)) { Type handlerType = Type.GetType(policy.Handler); if (handlerType == null) { throw new InvalidOperationException("Cannot find policy handler"); } var ci = handlerType.GetConstructor(Type.EmptyTypes); if (ci == null) { throw new InvalidOperationException("Cannot find parameterless constructor"); } this.m_handler = ci.Invoke(null) as IPolicyHandler; if (this.m_handler == null) { throw new InvalidOperationException("Policy handler does not implement IPolicyHandler"); } lock (s_lockObject) s_handlers.Add(policy.Handler, this.m_handler); } }
/// <summary> /// Get a policy outcome /// </summary> public PolicyDecisionOutcomeType GetPolicyOutcome(IPrincipal principal, string policyId) { if (principal == null) { throw new ArgumentNullException(nameof(principal)); } else if (String.IsNullOrEmpty(policyId)) { throw new ArgumentNullException(nameof(policyId)); } // Can we make this decision based on the claims? if (principal is ClaimsPrincipal && (principal as ClaimsPrincipal).HasClaim(c => c.Type == OpenIzClaimTypes.OpenIzGrantedPolicyClaim && policyId.StartsWith(c.Value))) { return(PolicyDecisionOutcomeType.Grant); } // Get the user object from the principal var pip = ApplicationContext.Current.GetService <IPolicyInformationService>(); // Policies var activePolicies = pip.GetActivePolicies(principal).Where(o => policyId.StartsWith(o.Policy.Oid)); // Most restrictive IPolicyInstance policyInstance = null; foreach (var pol in activePolicies) { if (policyInstance == null) { policyInstance = pol; } else if (pol.Rule < policyInstance.Rule) { policyInstance = pol; } } if (policyInstance == null) { // TODO: Configure OptIn or OptOut return(PolicyDecisionOutcomeType.Deny); } else if (!policyInstance.Policy.CanOverride && policyInstance.Rule == PolicyDecisionOutcomeType.Elevate) { return(PolicyDecisionOutcomeType.Deny); } else if (!policyInstance.Policy.IsActive) { return(PolicyDecisionOutcomeType.Grant); } else if ((policyInstance.Policy as ILocalPolicy)?.Handler != null) { IPolicyHandler handlerInstance = null; var policy = policyInstance.Policy as ILocalPolicy; if (policy != null) { return(policy.Handler.GetPolicyDecision(principal, policy, null).Outcome); } } return(policyInstance.Rule); }