public async Task <IActionResult> NewPolicy(NewPolicyViewModel model) { if (!ModelState.IsValid) { return(View(model)); } var foundPolicy = await _service.FetchPolicy(model.Name); if (foundPolicy != null) { ModelState.AddModelError("nameinuse", _sr["The policy name is already in use."]); return(View(model)); } var policy = new AuthorizationPolicyInfo(); policy.Name = model.Name; var result = await _service.CreatePolicy(policy); if (result.Succeeded) { var successFormat = _sr["The policy {0} was successfully created."]; this.AlertSuccess(string.Format(successFormat, model.Name), true); } else { this.AlertDanger(_sr[result.Message], true); } return(RedirectToAction("EditPolicy", new { id = policy.Id })); }
public async Task Create( AuthorizationPolicyInfo policy, CancellationToken cancellationToken = default(CancellationToken)) { if (policy == null) { throw new ArgumentException("policy cannot be null"); } using (var db = _contextFactory.CreateContext()) { var entity = new AuthorizationPolicyEntity(); policy.CopyTo(entity); SyncRoles(db, policy.AllowedRoles, entity); SyncSchemes(db, policy.AuthenticationSchemes, entity); SyncClaimRequirements(db, policy.RequiredClaims, entity); db.Policies.Add(entity); int rowsAffected = await db.SaveChangesAsync(cancellationToken) .ConfigureAwait(false); _cache.ClearListCache(policy.TenantId); } }
public static AuthorizationPolicyInfo ToAuthorizationPolicyInfo(this AuthorizationPolicyEntity entity) { var policy = new AuthorizationPolicyInfo(); policy.Id = entity.Id; policy.Name = entity.Name; policy.TenantId = entity.TenantId; policy.RequireAuthenticatedUser = entity.RequireAuthenticatedUser; policy.RequiredUserName = entity.RequiredUserName; policy.Notes = entity.Notes; foreach (var r in entity.AllowedRoles) { policy.AllowedRoles.Add(r.AllowedRole); } foreach (var s in entity.AuthenticationSchemes) { policy.AuthenticationSchemes.Add(s.AuthenticationScheme); } foreach (var c in entity.RequiredClaims) { var cr = new ClaimRequirement(); cr.ClaimName = c.ClaimName; foreach (var r in c.AllowedValues) { cr.AllowedValues.Add(r.AllowedValue); } policy.RequiredClaims.Add(cr); } return(policy); }
public override async Task <AuthorizationPolicy> GetPolicyAsync(string policyName) { // Check static policies first var policy = await base.GetPolicyAsync(policyName); if (policy == null) { var policyService = _contextAccessor.HttpContext.RequestServices.GetService <PolicyManagementService>(); var policyInfo = await policyService.FetchPolicy(policyName); if (policyInfo != null) { return(policyInfo.ToAuthPolicy()); } if (_policyOptions.AutoCreateMissingPolicies) { //initialize policy in the data storage var newPolicy = new AuthorizationPolicyInfo(); newPolicy.Name = policyName; if (_policyOptions.PolicyNamesToConfigureAsAllowAnonymous.Contains(policyName)) { await policyService.CreatePolicy(newPolicy); return(newPolicy.ToAuthPolicy()); } else if (_policyOptions.PolicyNamesToConfigureAsAnyAuthenticatedUser.Contains(policyName)) { newPolicy.RequireAuthenticatedUser = true; await policyService.CreatePolicy(newPolicy); return(newPolicy.ToAuthPolicy()); } else { var allowedRoles = _policyOptions.AutoPolicyAllowedRoleNamesCsv.Split(','); var roleList = new List <string>(allowedRoles); newPolicy.AllowedRoles = roleList; await policyService.CreatePolicy(newPolicy); policy = new AuthorizationPolicyBuilder() .RequireRole(allowedRoles) .Build(); } var logger = _contextAccessor.HttpContext.RequestServices.GetService <ILogger <DynamicAuthorizationPolicyProvider> >(); logger.LogWarning($"policy named {policyName} was missing so auto creating it with default allowed roles"); } } return(policy); }
public static ClaimRequirement GetClaimRequirement(this AuthorizationPolicyInfo info, string claimName) { foreach (var req in info.RequiredClaims) { if (req.ClaimName == claimName) { return(req); } } return(null); }
public static bool HasClaimRequirement(this AuthorizationPolicyInfo info, string claimName) { foreach (var req in info.RequiredClaims) { if (req.ClaimName == claimName) { return(true); } } return(false); }
public static void CopyTo(this AuthorizationPolicyInfo policy, AuthorizationPolicyEntity entity) { entity.Id = policy.Id; entity.Name = policy.Name; entity.TenantId = policy.TenantId; entity.RequireAuthenticatedUser = policy.RequireAuthenticatedUser; entity.RequiredUserName = policy.RequiredUserName; entity.Notes = policy.Notes; //policy.AllowedRoles.SyncTo(entity.AllowedRoles, entity); //policy.AuthenticationSchemes.SyncTo(entity.AuthenticationSchemes, entity); //policy.RequiredClaims.SyncTo(entity.RequiredClaims, entity); }
public static AuthorizationPolicy ToAuthPolicy(this AuthorizationPolicyInfo info) { var policy = new AuthorizationPolicyBuilder(); var hasAnyRequirements = false; if (info.AllowedRoles.Count > 0) { policy.RequireRole(info.AllowedRoles); hasAnyRequirements = true; } if (info.AuthenticationSchemes.Count > 0) { policy.AuthenticationSchemes = info.AuthenticationSchemes; } if (info.RequireAuthenticatedUser) { policy.RequireAuthenticatedUser(); hasAnyRequirements = true; } if (info.RequiredClaims.Count > 0) { foreach (var c in info.RequiredClaims) { if (c.AllowedValues.Count > 0) { policy.RequireClaim(c.ClaimName, c.AllowedValues); } else { policy.RequireClaim(c.ClaimName); } hasAnyRequirements = true; } } if (!string.IsNullOrWhiteSpace(info.RequiredUserName)) { policy.RequireUserName(info.RequiredUserName); hasAnyRequirements = true; } if (!hasAnyRequirements) { // allow anonymous Func <AuthorizationHandlerContext, bool> allowAny = (AuthorizationHandlerContext authContext) => true; policy.RequireAssertion(allowAny); } return(policy.Build()); }
public static bool RemoveClaimRequirement(this AuthorizationPolicyInfo info, string claimName) { for (int i = 0; i < info.RequiredClaims.Count; i++) { if (info.RequiredClaims[i].ClaimName == claimName) { info.RequiredClaims.RemoveAt(i); return(true); } } return(false); }
public async Task Update( AuthorizationPolicyInfo policy, CancellationToken cancellationToken = default(CancellationToken)) { if (policy == null) { throw new ArgumentException("policy cannot be null"); } await _policyCommands.UpdateAsync( policy.TenantId, policy.Id.ToString(), policy, cancellationToken).ConfigureAwait(false); _cache.ClearListCache(policy.TenantId); }
public async Task <PolicyOperationResult> CreatePolicy( AuthorizationPolicyInfo policy, CancellationToken cancellationToken = default(CancellationToken)) { if (policy == null) { throw new ArgumentException("policy cannot be null"); } policy.TenantId = _tenantProvider.GetTenantId(); try { await _commands.Create(policy, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { // if a policy is auto created it can happen that multipl request threads try to create the missing policy // a unique constraint error would happen so catching the possible error _log.LogError($"handled error {ex.Message}:{ex.StackTrace}"); } return(new PolicyOperationResult(true)); }
public async Task Update( AuthorizationPolicyInfo policy, CancellationToken cancellationToken = default(CancellationToken)) { if (policy == null) { throw new ArgumentException("policy cannot be null"); } using (var db = _contextFactory.CreateContext()) { var entity = await db.Policies .Include(p => p.AllowedRoles) .Include(p => p.AuthenticationSchemes) .Include(p => p.RequiredClaims) .ThenInclude(x => x.AllowedValues) .FirstOrDefaultAsync(p => p.Id == policy.Id, cancellationToken) .ConfigureAwait(false); policy.CopyTo(entity); SyncRoles(db, policy.AllowedRoles, entity); SyncSchemes(db, policy.AuthenticationSchemes, entity); SyncClaimRequirements(db, policy.RequiredClaims, entity); //db.Policies.(entity).State = EntityState.Modified; bool tracking = db.ChangeTracker.Entries <AuthorizationPolicyInfo>().Any(x => x.Entity.Id == entity.Id); if (!tracking) { db.Policies.Update(entity); } // var saved = false; //while (!saved) //{ try { int rowsAffected = await db.SaveChangesAsync(cancellationToken) .ConfigureAwait(false); //saved = true; } catch (DbUpdateConcurrencyException ex) { //foreach (var entry in ex.Entries) //{ // if (entry.Entity is AuthorizationPolicyEntity) // { // var proposedValues = entry.CurrentValues; // var databaseValues = entry.GetDatabaseValues(); // foreach (var property in proposedValues.Properties) // { // var proposedValue = proposedValues[property]; // var databaseValue = databaseValues[property]; // // TODO: decide which value should be written to database // // proposedValues[property] = <value to be saved>; // } // // Refresh original values to bypass next concurrency check // entry.OriginalValues.SetValues(databaseValues); // } // else // { // throw new NotSupportedException( // "Don't know how to handle concurrency conflicts for " // + entry.Metadata.Name); // } //} } //} _cache.ClearListCache(policy.TenantId); } }