private async Task <AuthorizationPolicy> GetAuthorizationPolicy(IDotvvmRequestContext context) { var policyProvider = GetPolicyProvider(context); var policyBuilder = new AuthorizationPolicyBuilder(); var useDefaultPolicy = true; if (!string.IsNullOrWhiteSpace(Policy)) { var policy = await policyProvider.GetPolicyAsync(Policy); if (policy == null) { throw new InvalidOperationException($"The policy '{Policy}' could not be found!"); } policyBuilder.Combine(policy); useDefaultPolicy = false; } var rolesSplit = Roles?.Split(','); if (rolesSplit != null && rolesSplit.Any()) { var trimmedRolesSplit = rolesSplit.Where(r => !string.IsNullOrWhiteSpace(r)).Select(r => r.Trim()); policyBuilder.RequireRole(trimmedRolesSplit); useDefaultPolicy = false; } var authTypesSplit = ActiveAuthenticationSchemes?.Split(','); if (authTypesSplit != null && authTypesSplit.Any()) { foreach (var authType in authTypesSplit) { if (!string.IsNullOrWhiteSpace(authType)) { policyBuilder.AuthenticationSchemes.Add(authType.Trim()); } } } if (useDefaultPolicy) { policyBuilder.Combine(await policyProvider.GetDefaultPolicyAsync()); } return(policyBuilder.Build()); }
internal async Task <AuthorizationPolicy> GetEffectivePolicyAsync(AuthorizationFilterContext context) { // Combine all authorize filters into single effective policy that's only run on the closest filter var builder = new AuthorizationPolicyBuilder(await ComputePolicyAsync()); for (var i = 0; i < context.Filters.Count; i++) { if (ReferenceEquals(this, context.Filters[i])) { continue; } if (context.Filters[i] is AuthorizeFilter authorizeFilter) { // Combine using the explicit policy, or the dynamic policy provider builder.Combine(await authorizeFilter.ComputePolicyAsync()); } } var endpoint = context.HttpContext.GetEndpoint(); if (endpoint != null) { // When doing endpoint routing, MVC does not create filters for any authorization specific metadata i.e [Authorize] does not // get translated into AuthorizeFilter. Consequently, there are some rough edges when an application uses a mix of AuthorizeFilter // explicilty configured by the user (e.g. global auth filter), and uses endpoint metadata. // To keep the behavior of AuthFilter identical to pre-endpoint routing, we will gather auth data from endpoint metadata // and produce a policy using this. This would mean we would have effectively run some auth twice, but it maintains compat. var policyProvider = PolicyProvider ?? context.HttpContext.RequestServices.GetRequiredService <IAuthorizationPolicyProvider>(); var endpointAuthorizeData = endpoint.Metadata.GetOrderedMetadata <IAuthorizeData>() ?? Array.Empty <IAuthorizeData>(); var endpointPolicy = await AuthorizationPolicy.CombineAsync(policyProvider, endpointAuthorizeData); if (endpointPolicy != null) { builder.Combine(endpointPolicy); } } return(builder.Build()); }
private void AddAccessPolicy(AuthorizationPolicyBuilder builder, AuthorizationOptions options, AccessPolicy policy) { if (policy == null) { throw new ArgumentNullException(nameof(policy)); } // // Forbidden if (policy.Forbidden) { builder.Combine(GetPolicyRequirement(FORBIDDEN, options)); } // // AccessKey if (policy.AccessKey) { builder.Combine(GetPolicyRequirement(ACCESS_KEY, options)); } // // Users if (!policy.Users.Equals("Everyone", StringComparison.OrdinalIgnoreCase)) { builder.Combine(GetPolicyRequirement(WINDOWS_USER, options)); builder.AddRequirements(new NtlmAuthorizationPolicy(policy.Users, _roleMapping)); } else { builder.Combine(GetPolicyRequirement(AUTHENTICATED_USER, options)); } // // Read Only if (policy.ReadOnly) { builder.Combine(GetPolicyRequirement(READ_ONLY, options)); } }
private async Task <AuthorizationPolicy> GetEffectivePolicyAsync(AuthorizationFilterContext context) { if (_effectivePolicy != null) { return(_effectivePolicy); } var effectivePolicy = await ComputePolicyAsync(); var canCache = PolicyProvider == null; if (_mvcOptions == null) { _mvcOptions = context.HttpContext.RequestServices.GetRequiredService <IOptions <MvcOptions> >().Value; } if (_mvcOptions.AllowCombiningAuthorizeFilters) { if (!context.IsEffectivePolicy(this)) { return(null); } // Combine all authorize filters into single effective policy that's only run on the closest filter var builder = new AuthorizationPolicyBuilder(effectivePolicy); for (var i = 0; i < context.Filters.Count; i++) { if (ReferenceEquals(this, context.Filters[i])) { continue; } if (context.Filters[i] is AuthorizeFilter authorizeFilter) { // Combine using the explicit policy, or the dynamic policy provider builder.Combine(await authorizeFilter.ComputePolicyAsync()); canCache = canCache && authorizeFilter.PolicyProvider == null; } } effectivePolicy = builder?.Build() ?? effectivePolicy; } // We can cache the effective policy when there is no custom policy provider if (canCache) { _effectivePolicy = effectivePolicy; } return(effectivePolicy); }
/// <summary> /// Combines the specified <see cref="AuthorizationPolicy"/> into a single policy. /// </summary> /// <param name="policies">The authorization policies to combine.</param> /// <returns> /// A new <see cref="AuthorizationPolicy"/> which represents the combination of the /// specified <paramref name="policies"/>. /// </returns> public static AuthorizationPolicy Combine(IEnumerable <AuthorizationPolicy> policies) { if (policies == null) { throw new ArgumentNullException(nameof(policies)); } var builder = new AuthorizationPolicyBuilder(); foreach (var policy in policies) { builder.Combine(policy); } return(builder.Build()); }
private async Task <AuthorizationPolicy> GetEffectivePolicyAsync(AuthorizationFilterContext context) { if (_effectivePolicy != null) { return(_effectivePolicy); } var effectivePolicy = Policy; if (_mvcOptions == null) { _mvcOptions = context.HttpContext.RequestServices.GetRequiredService <IOptions <MvcOptions> >().Value; } if (_mvcOptions.AllowCombiningAuthorizeFilters) { if (!context.IsEffectivePolicy <AuthorizeFilter>(this)) { return(null); } // Combine all authorize filters into single effective policy that's only run on the closest filter AuthorizationPolicyBuilder builder = null; for (var i = 0; i < context.Filters.Count; i++) { if (ReferenceEquals(this, context.Filters[i])) { continue; } if (context.Filters[i] is AuthorizeFilter authorizeFilter) { builder = builder ?? new AuthorizationPolicyBuilder(effectivePolicy); builder.Combine(authorizeFilter.Policy); } } effectivePolicy = builder?.Build() ?? effectivePolicy; } if (effectivePolicy == null) { if (PolicyProvider == null) { throw new InvalidOperationException( Resources.FormatAuthorizeFilter_AuthorizationPolicyCannotBeCreated( nameof(AuthorizationPolicy), nameof(IAuthorizationPolicyProvider))); } effectivePolicy = await AuthorizationPolicy.CombineAsync(PolicyProvider, AuthorizeData); } // We can cache the effective policy when there is no custom policy provider if (PolicyProvider == null) { _effectivePolicy = effectivePolicy; } return(effectivePolicy); }
/// <summary> /// Combines the <see cref="AuthorizationPolicy"/> provided by the specified /// <paramref name="policyProvider"/>. /// </summary> /// <param name="policyProvider">A <see cref="IAuthorizationPolicyProvider"/> which provides the policies to combine.</param> /// <param name="authorizeData">A collection of authorization data used to apply authorization to a resource.</param> /// <returns> /// A new <see cref="AuthorizationPolicy"/> which represents the combination of the /// authorization policies provided by the specified <paramref name="policyProvider"/>. /// </returns> public static async Task <AuthorizationPolicy> CombineAsync(IAuthorizationPolicyProvider policyProvider, IEnumerable <IAuthorizeData> authorizeData) { if (policyProvider == null) { throw new ArgumentNullException(nameof(policyProvider)); } if (authorizeData == null) { throw new ArgumentNullException(nameof(authorizeData)); } var policyBuilder = new AuthorizationPolicyBuilder(); var any = false; foreach (var authorizeDatum in authorizeData) { any = true; var useDefaultPolicy = true; if (!string.IsNullOrWhiteSpace(authorizeDatum.Policy)) { var policy = await policyProvider.GetPolicyAsync(authorizeDatum.Policy); if (policy == null) { //throw new InvalidOperationException(Resources.FormatException_AuthorizationPolicyNotFound(authorizeDatum.Policy)); throw new InvalidOperationException(nameof(authorizeDatum.Policy)); } policyBuilder.Combine(policy); useDefaultPolicy = false; } var rolesSplit = authorizeDatum.Roles?.Split(','); if (rolesSplit != null && rolesSplit.Any()) { var trimmedRolesSplit = rolesSplit.Where(r => !string.IsNullOrWhiteSpace(r)).Select(r => r.Trim()); policyBuilder.RequireRole(trimmedRolesSplit); useDefaultPolicy = false; } if (authorizeDatum is IPermissionAuthorizeData permissionAuthorizeDatum) { var groupsSplit = permissionAuthorizeDatum.Groups?.Split(','); if (groupsSplit != null && groupsSplit.Any()) { var trimmedGroupsSplit = groupsSplit.Where(r => !string.IsNullOrWhiteSpace(r)).Select(r => r.Trim()); policyBuilder.RequireClaim(TubumuClaimTypes.Group, trimmedGroupsSplit); //policyBuilder.AddRequirements(new GroupsAuthorizationRequirement(trimmedGroupsSplit)); useDefaultPolicy = false; } var permissionsSplit = permissionAuthorizeDatum.Permissions?.Split(','); if (permissionsSplit != null && permissionsSplit.Any()) { var trimmedPermissionsSplit = permissionsSplit.Where(r => !string.IsNullOrWhiteSpace(r)).Select(r => r.Trim()); policyBuilder.RequireClaim(TubumuClaimTypes.Permission, trimmedPermissionsSplit); //policyBuilder.AddRequirements(new PermissionsAuthorizationRequirement(trimmedPermissionsSplit)); useDefaultPolicy = false; } } var authTypesSplit = authorizeDatum.AuthenticationSchemes?.Split(','); if (authTypesSplit != null && authTypesSplit.Any()) { foreach (var authType in authTypesSplit) { if (!string.IsNullOrWhiteSpace(authType)) { policyBuilder.AuthenticationSchemes.Add(authType.Trim()); } } } if (useDefaultPolicy) { policyBuilder.Combine(await policyProvider.GetDefaultPolicyAsync()); } } return(any ? policyBuilder.Build() : null); }
public async Task <AuthorizationPolicy> CombineAsync(AuthorizeData authorizeData) { // Avoid allocating enumerator if the data is known to be empty var skip = authorizeData == null; if (skip) { // If we have no policy by now, use the fallback policy if we have one var fallbackPolicy = await PolicyProvider.GetFallbackPolicyAsync(); if (fallbackPolicy != null) { return(fallbackPolicy); } } else { AuthorizationPolicyBuilder policyBuilder = new AuthorizationPolicyBuilder(); var useDefaultPolicy = true; if (authorizeData.DeniedAll) { policyBuilder.AddRequirements(new DenyAllAuthorizationRequirement(true)); useDefaultPolicy = false; } else { if (!authorizeData.AuthenticationSchemes.IsNullOrEmpty()) { foreach (string scheme in authorizeData.AuthenticationSchemes) { policyBuilder.AuthenticationSchemes.Add(scheme.Trim()); } } // 假如允许所有角色访问,只需要求登录即可 if (authorizeData.AllowedAllRoles) { policyBuilder.RequireAuthenticatedUser(); useDefaultPolicy = false; } else { if (!authorizeData.Policies.IsNullOrEmpty()) { foreach (string policyName in authorizeData.Policies) { var policy = await PolicyProvider.GetPolicyAsync(policyName); if (policy == null) { throw new InvalidOperationException($"找不到名为: '{policyName}'的策略!"); } policyBuilder.Combine(policy); } useDefaultPolicy = false; } if (!authorizeData.AllowedUsers.IsNullOrEmpty() || !authorizeData.AllowedRoles.IsNullOrEmpty()) { policyBuilder.AddRequirements(new RolesOrUsersAuthorizationRequirement(authorizeData.AllowedUsers, authorizeData.AllowedRoles)); useDefaultPolicy = false; } } if (useDefaultPolicy) { policyBuilder.Combine(await PolicyProvider.GetDefaultPolicyAsync()); } } return(policyBuilder?.Build()); } return(null); }