diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs b/src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs index 14da299d91..c2931a52cb 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs @@ -11,6 +11,11 @@ namespace Microsoft.AspNet.Authorization { private IDictionary PolicyMap { get; } = new Dictionary(StringComparer.OrdinalIgnoreCase); + /// + /// The initial default policy is to require any authenticated user + /// + public AuthorizationPolicy DefaultPolicy { get; set; } = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build(); + public void AddPolicy([NotNull] string name, [NotNull] AuthorizationPolicy policy) { PolicyMap[name] = policy; diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs b/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs index 6f2ecc79e9..1efb4afd24 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs @@ -45,7 +45,7 @@ namespace Microsoft.AspNet.Authorization foreach (var authorizeAttribute in attributes.OfType()) { any = true; - var requireAnyAuthenticated = true; + var useDefaultPolicy = true; if (!string.IsNullOrWhiteSpace(authorizeAttribute.Policy)) { var policy = options.GetPolicy(authorizeAttribute.Policy); @@ -54,13 +54,13 @@ namespace Microsoft.AspNet.Authorization throw new InvalidOperationException(Resources.FormatException_AuthorizationPolicyNotFound(authorizeAttribute.Policy)); } policyBuilder.Combine(policy); - requireAnyAuthenticated = false; + useDefaultPolicy = false; } var rolesSplit = authorizeAttribute.Roles?.Split(','); if (rolesSplit != null && rolesSplit.Any()) { policyBuilder.RequireRole(rolesSplit); - requireAnyAuthenticated = false; + useDefaultPolicy = false; } var authTypesSplit = authorizeAttribute.ActiveAuthenticationSchemes?.Split(','); if (authTypesSplit != null && authTypesSplit.Any()) @@ -70,9 +70,9 @@ namespace Microsoft.AspNet.Authorization policyBuilder.ActiveAuthenticationSchemes.Add(authType); } } - if (requireAnyAuthenticated) + if (useDefaultPolicy) { - policyBuilder.RequireAuthenticatedUser(); + policyBuilder.Combine(options.DefaultPolicy); } } return any ? policyBuilder.Build() : null; diff --git a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs index 801ab8447c..ecad6ff4b8 100644 --- a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs @@ -16,16 +16,17 @@ namespace Microsoft.Framework.DependencyInjection } public static IServiceCollection AddAuthorization([NotNull] this IServiceCollection services) - { - return services.AddAuthorization(configureOptions: null); - } - - public static IServiceCollection AddAuthorization([NotNull] this IServiceCollection services, Action configureOptions) { services.AddOptions(); services.TryAdd(ServiceDescriptor.Transient()); services.AddTransient(); return services; } + + public static IServiceCollection AddAuthorization([NotNull] this IServiceCollection services, [NotNull] Action configureOptions) + { + services.ConfigureAuthorization(configureOptions); + return services.AddAuthorization(); + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Authorization.Test/AuthorizationPolicyFacts.cs b/test/Microsoft.AspNet.Authorization.Test/AuthorizationPolicyFacts.cs index 208c53b1c3..5f04c2b78f 100644 --- a/test/Microsoft.AspNet.Authorization.Test/AuthorizationPolicyFacts.cs +++ b/test/Microsoft.AspNet.Authorization.Test/AuthorizationPolicyFacts.cs @@ -42,5 +42,29 @@ namespace Microsoft.AspNet.Authroization.Test Assert.Equal(2, combined.Requirements.OfType().Count()); Assert.Equal(1, combined.Requirements.OfType().Count()); } + + [Fact] + public void CanReplaceDefaultPolicy() + { + // Arrange + var attributes = new AuthorizeAttribute[] { + new AuthorizeAttribute(), + new AuthorizeAttribute("2") { ActiveAuthenticationSchemes = "dupe" } + }; + var options = new AuthorizationOptions(); + options.DefaultPolicy = new AuthorizationPolicyBuilder("default").RequireClaim("default").Build(); + options.AddPolicy("2", policy => policy.RequireClaim("2")); + + // Act + var combined = AuthorizationPolicy.Combine(options, attributes); + + // Assert + Assert.Equal(2, combined.ActiveAuthenticationSchemes.Count()); + Assert.True(combined.ActiveAuthenticationSchemes.Contains("dupe")); + Assert.True(combined.ActiveAuthenticationSchemes.Contains("default")); + Assert.Equal(2, combined.Requirements.Count()); + Assert.False(combined.Requirements.Any(r => r is DenyAnonymousAuthorizationRequirement)); + Assert.Equal(2, combined.Requirements.OfType().Count()); + } } } \ No newline at end of file