From 7b2fb55ef6c4a85bda754d74f42636018b028214 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Thu, 15 Jan 2015 23:41:52 -0800 Subject: [PATCH] React to Security Auth changes --- samples/MvcSample.Web/FiltersController.cs | 4 +- samples/MvcSample.Web/Startup.cs | 15 ++ .../Filters/AuthorizeAttribute.cs | 86 ++++---- .../MvcServiceCollectionExtensions.cs | 7 +- src/Microsoft.AspNet.Mvc/MvcServices.cs | 1 - .../Filters/AuthorizeAttributeTests.cs | 201 +++++++++++++++--- .../Filters/AuthorizeAttributeTestsBase.cs | 9 + .../FiltersTest.cs | 31 +++ .../AuthorizeBasicMiddleware.cs | 61 ++++++ .../Controllers/AuthorizeUserController.cs | 17 +- test/WebSites/FiltersWebSite/Startup.cs | 19 ++ 11 files changed, 371 insertions(+), 80 deletions(-) create mode 100644 test/WebSites/FiltersWebSite/AuthorizeBasicMiddleware.cs diff --git a/samples/MvcSample.Web/FiltersController.cs b/samples/MvcSample.Web/FiltersController.cs index 68c8b448e6..e9909c8719 100644 --- a/samples/MvcSample.Web/FiltersController.cs +++ b/samples/MvcSample.Web/FiltersController.cs @@ -50,14 +50,14 @@ namespace MvcSample.Web return new ChallengeResult(); } - [Authorize("Permission", "CanViewPage")] + [Authorize("CanViewPage")] public ActionResult NotGrantedClaim(int age = 20, string userName = "SampleUser") { return Index(age, userName); } [FakeUser] - [Authorize("Permission", "CanViewPage", "CanViewAnything")] + [Authorize("CanViewAnything")] public ActionResult AllGranted(int age = 20, string userName = "SampleUser") { return Index(age, userName); diff --git a/samples/MvcSample.Web/Startup.cs b/samples/MvcSample.Web/Startup.cs index 305b556be5..7410c6b95f 100644 --- a/samples/MvcSample.Web/Startup.cs +++ b/samples/MvcSample.Web/Startup.cs @@ -3,10 +3,12 @@ using System; using System.IO; +using System.Security.Claims; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Mvc; using Microsoft.AspNet.Mvc.Razor; using Microsoft.AspNet.Routing; +using Microsoft.AspNet.Security; using Microsoft.Framework.ConfigurationModel; using Microsoft.Framework.DependencyInjection; using MvcSample.Web.Filters; @@ -38,6 +40,19 @@ namespace MvcSample.Web app.UseServices(services => { + services.ConfigureAuthorization(auth => + { + auth.AddPolicy("CanViewPage", + new AuthorizationPolicyBuilder() + .RequiresClaim("Permission", "CanViewPage", "CanViewAnything").Build()); + auth.AddPolicy("CanViewAnything", + new AuthorizationPolicyBuilder() + .RequiresClaim("Permission", "CanViewAnything").Build()); + // This policy basically requires that the auth type is present + var basicPolicy = new AuthorizationPolicyBuilder("Basic").RequiresClaim(ClaimTypes.NameIdentifier); + auth.AddPolicy("RequireBasic", basicPolicy.Build()); + }); + services.AddMvc(); services.AddSingleton(); services.AddSingleton(); diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/AuthorizeAttribute.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/AuthorizeAttribute.cs index d4ff495086..9c46d71217 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Filters/AuthorizeAttribute.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Filters/AuthorizeAttribute.cs @@ -2,9 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Security; @@ -14,69 +11,74 @@ namespace Microsoft.AspNet.Mvc { public class AuthorizeAttribute : AuthorizationFilterAttribute { - protected Claim[] _claims; + private string _roles; + private string[] _rolesSplit; - public AuthorizeAttribute() + public AuthorizeAttribute() { } + + public AuthorizeAttribute(string policy) { - _claims = new Claim[0]; + Policy = policy; } - public AuthorizeAttribute([NotNull]IEnumerable claims) - { - _claims = claims.ToArray(); - } + public string Policy { get; set; } - public AuthorizeAttribute(string claimType, string claimValue) + public string Roles { - _claims = new[] { new Claim(claimType, claimValue) }; - } - - public AuthorizeAttribute(string claimType, string claimValue, params string[] otherClaimValues) - : this(claimType, claimValue) - { - if (otherClaimValues.Length > 0) + get { return _roles; } + set { - _claims = _claims.Concat(otherClaimValues.Select(claim => new Claim(claimType, claim))).ToArray(); + _roles = value; + if (string.IsNullOrWhiteSpace(_roles)) + { + _rolesSplit = null; + } + else + { + _rolesSplit = _roles.Split(','); + } } } public override async Task OnAuthorizationAsync([NotNull] AuthorizationContext context) { var httpContext = context.HttpContext; - var user = httpContext.User; - // when no claims are specified, we just need to ensure the user is authenticated - if (_claims.Length == 0) + // Allow Anonymous skips all authorization + if (HasAllowAnonymous(context)) { - var userIsAnonymous = - user == null || - user.Identity == null || - !user.Identity.IsAuthenticated; + return; + } - if (userIsAnonymous && !HasAllowAnonymous(context)) + var authService = httpContext.RequestServices.GetRequiredService(); + + // Build a policy for the requested roles if specified + if (_rolesSplit != null) + { + var rolesPolicy = new AuthorizationPolicyBuilder(); + rolesPolicy.RequiresRole(_rolesSplit); + if (!await authService.AuthorizeAsync(rolesPolicy.Build(), httpContext, context)) { Fail(context); + return; } } - else + + var authorized = (Policy == null) + // [Authorize] with no policy just requires any authenticated user + ? await authService.AuthorizeAsync(BuildAnyAuthorizedUserPolicy(), httpContext, context) + : await authService.AuthorizeAsync(Policy, httpContext, context); + if (!authorized) { - var authorizationService = httpContext.RequestServices.GetRequiredService(); - - if (authorizationService == null) - { - throw new InvalidOperationException( - Resources.AuthorizeAttribute_AuthorizationServiceMustBeDefined); - } - - var authorized = await authorizationService.AuthorizeAsync(_claims, user); - - if (!authorized) - { - Fail(context); - } + Fail(context); } } + private static AuthorizationPolicy BuildAnyAuthorizedUserPolicy() + { + return new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build(); + } + public sealed override void OnAuthorization([NotNull] AuthorizationContext context) { // The async filter will be called by the filter pipeline. diff --git a/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs index 72be824d09..4596ff9996 100644 --- a/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs @@ -1,9 +1,12 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNet.Mvc; using Microsoft.AspNet.Routing; -using Microsoft.AspNet.Security.DataProtection; +using Microsoft.AspNet.Security; using Microsoft.Framework.ConfigurationModel; namespace Microsoft.Framework.DependencyInjection @@ -23,10 +26,12 @@ namespace Microsoft.Framework.DependencyInjection services.AddDataProtection(configuration); services.AddRouting(configuration); services.AddScopedInstance(configuration); + services.AddAuthorization(configuration); services.Configure(routeOptions => routeOptions.ConstraintMap .Add("exists", typeof(KnownRouteValueConstraint))); + } } } diff --git a/src/Microsoft.AspNet.Mvc/MvcServices.cs b/src/Microsoft.AspNet.Mvc/MvcServices.cs index 90de0a7cb0..188b5a8ba8 100644 --- a/src/Microsoft.AspNet.Mvc/MvcServices.cs +++ b/src/Microsoft.AspNet.Mvc/MvcServices.cs @@ -151,7 +151,6 @@ namespace Microsoft.AspNet.Mvc // Security and Authorization - yield return describe.Transient(); yield return describe.Singleton(); yield return describe.Singleton(); yield return describe.Singleton()); - var authorizeAttribute = new AuthorizeAttribute("Permission", "CanViewPage"); + var authorizeAttribute = new AuthorizeAttribute("CanViewPage"); var authorizationContext = GetAuthorizationContext(services => - services.AddInstance(authorizationService) - ); + { + services.AddAuthorization(null, options => + { + var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage"); + options.AddPolicy("CanViewPage", policy.Build()); + }); + }); // Act await authorizeAttribute.OnAuthorizationAsync(authorizationContext); @@ -34,12 +36,11 @@ namespace Microsoft.AspNet.Mvc.Core.Test public async Task Invoke_EmptyClaimsShouldRejectAnonymousUser() { // Arrange - var authorizationService = new DefaultAuthorizationService(Enumerable.Empty()); + var authorizationOptions = new AuthorizationOptions(); var authorizeAttribute = new AuthorizeAttribute(); var authorizationContext = GetAuthorizationContext(services => - services.AddInstance(authorizationService), - anonymous: true - ); + services.AddAuthorization(), + anonymous: true); // Act await authorizeAttribute.OnAuthorizationAsync(authorizationContext); @@ -52,12 +53,13 @@ namespace Microsoft.AspNet.Mvc.Core.Test public async Task Invoke_EmptyClaimsWithAllowAnonymousAttributeShouldNotRejectAnonymousUser() { // Arrange - var authorizationService = new DefaultAuthorizationService(Enumerable.Empty()); var authorizeAttribute = new AuthorizeAttribute(); var authorizationContext = GetAuthorizationContext(services => - services.AddInstance(authorizationService), - anonymous: true - ); + { + services.AddAuthorization(); + services.AddTransient(); + }, + anonymous: true); authorizationContext.Filters.Add(new AllowAnonymousAttribute()); @@ -72,11 +74,12 @@ namespace Microsoft.AspNet.Mvc.Core.Test public async Task Invoke_EmptyClaimsShouldAuthorizeAuthenticatedUser() { // Arrange - var authorizationService = new DefaultAuthorizationService(Enumerable.Empty()); var authorizeAttribute = new AuthorizeAttribute(); var authorizationContext = GetAuthorizationContext(services => - services.AddInstance(authorizationService) - ); + { + services.AddAuthorization(); + services.AddTransient(); + }); // Act await authorizeAttribute.OnAuthorizationAsync(authorizationContext); @@ -89,11 +92,16 @@ namespace Microsoft.AspNet.Mvc.Core.Test public async Task Invoke_SingleValidClaimShouldSucceed() { // Arrange - var authorizationService = new DefaultAuthorizationService(Enumerable.Empty()); - var authorizeAttribute = new AuthorizeAttribute("Permission", "CanViewComment", "CanViewPage"); + var authorizeAttribute = new AuthorizeAttribute("CanViewCommentOrPage"); var authorizationContext = GetAuthorizationContext(services => - services.AddInstance(authorizationService) - ); + { + services.AddAuthorization(null, options => + { + var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewComment", "CanViewPage"); + options.AddPolicy("CanViewCommentOrPage", policy.Build()); + }); + services.AddTransient(); + }); // Act await authorizeAttribute.OnAuthorizationAsync(authorizationContext); @@ -102,15 +110,96 @@ namespace Microsoft.AspNet.Mvc.Core.Test Assert.Null(authorizationContext.Result); } + [Fact] + public async Task Invoke_RequireAdminRoleShouldFailWithNoHandlers() + { + // Arrange + var authorizeAttribute = new AuthorizeAttribute { Roles = "Administrator" }; + var authorizationContext = GetAuthorizationContext(services => + { + services.AddOptions(); + services.AddTransient(); + }); + + // Act + await authorizeAttribute.OnAuthorizationAsync(authorizationContext); + + // Assert + Assert.NotNull(authorizationContext.Result); + } + + [Fact] + public async Task Invoke_RequireAdminAndUserRoleWithNoPolicyShouldSucceed() + { + // Arrange + var authorizeAttribute = new AuthorizeAttribute { Roles = "Administrator,User" }; + var authorizationContext = GetAuthorizationContext(services => + { + services.AddAuthorization(); + services.AddTransient(); + }); + + // Act + await authorizeAttribute.OnAuthorizationAsync(authorizationContext); + + // Assert + Assert.Null(authorizationContext.Result); + } + + [Fact] + public async Task Invoke_RequireUnknownRoleShouldFail() + { + // Arrange + var authorizeAttribute = new AuthorizeAttribute { Roles = "Wut" }; + var authorizationContext = GetAuthorizationContext(services => + { + services.AddAuthorization(); + services.AddTransient(); + }); + + // Act + await authorizeAttribute.OnAuthorizationAsync(authorizationContext); + + // Assert + Assert.NotNull(authorizationContext.Result); + } + + [Fact] + public async Task Invoke_RequireAdminRoleButFailPolicyShouldFail() + { + // Arrange + var authorizeAttribute = new AuthorizeAttribute { Roles = "Administrator", Policy = "Basic" }; + var authorizationContext = GetAuthorizationContext(services => + { + services.AddAuthorization(null, options => + { + var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewComment"); + options.AddPolicy("CanViewComment", policy.Build()); + }); + services.AddTransient(); + }); + + // Act + await authorizeAttribute.OnAuthorizationAsync(authorizationContext); + + // Assert + Assert.NotNull(authorizationContext.Result); + } + [Fact] public async Task Invoke_InvalidClaimShouldFail() { // Arrange - var authorizationService = new DefaultAuthorizationService(Enumerable.Empty()); - var authorizeAttribute = new AuthorizeAttribute("Permission", "CanViewComment"); + var authorizeAttribute = new AuthorizeAttribute("CanViewComment"); var authorizationContext = GetAuthorizationContext(services => - services.AddInstance(authorizationService) - ); + { + services.AddAuthorization(null, options => + { + var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewComment"); + options.AddPolicy("CanViewComment", policy.Build()); + }); + services.AddTransient(); + }); // Act await authorizeAttribute.OnAuthorizationAsync(authorizationContext); @@ -126,16 +215,16 @@ namespace Microsoft.AspNet.Mvc.Core.Test bool authorizationServiceIsCalled = false; var authorizationService = new Mock(); authorizationService - .Setup(x => x.AuthorizeAsync(Enumerable.Empty(), null, null)) + .Setup(x => x.AuthorizeAsync("CanViewComment", null, null)) .Returns(() => { authorizationServiceIsCalled = true; return Task.FromResult(true); }); - var authorizeAttribute = new AuthorizeAttribute("Permission", "CanViewComment"); + var authorizeAttribute = new AuthorizeAttribute("CanViewComment"); var authorizationContext = GetAuthorizationContext(services => - services.AddInstance(authorizationService.Object) + services.AddInstance(authorizationService.Object) ); authorizationContext.Result = new HttpStatusCodeResult(401); @@ -148,14 +237,60 @@ namespace Microsoft.AspNet.Mvc.Core.Test } [Fact] - public async Task Invoke_NullPoliciesShouldNotFail() + public async Task Invoke_FailWhenLookingForClaimInOtherIdentity() { // Arrange - var authorizationService = new DefaultAuthorizationService(policies: null); - var authorizeAttribute = new AuthorizeAttribute("Permission", "CanViewPage"); + var authorizeAttribute = new AuthorizeAttribute("CanViewComment"); var authorizationContext = GetAuthorizationContext(services => - services.AddInstance(authorizationService) - ); + { + services.AddAuthorization(null, options => + { + var policy = new AuthorizationPolicyBuilder("Bearer").RequiresClaim("Permission", "CanViewComment"); + options.AddPolicy("CanViewComment", policy.Build()); + }); + services.AddTransient(); + }); + + // Act + await authorizeAttribute.OnAuthorizationAsync(authorizationContext); + + // Assert + Assert.NotNull(authorizationContext.Result); + } + + [Fact] + public async Task Invoke_CanLookingForClaimsInMultipleIdentities() + { + // Arrange + var authorizeAttribute = new AuthorizeAttribute("CanViewCommentCupBearer"); + var authorizationContext = GetAuthorizationContext(services => + { + services.AddAuthorization(null, options => + { + var policy = new AuthorizationPolicyBuilder("Basic", "Bearer") + .RequiresClaim("Permission", "CanViewComment") + .RequiresClaim("Permission", "CupBearer"); + options.AddPolicy("CanViewComment", policy.Build()); + }); + services.AddTransient(); + }); + + // Act + await authorizeAttribute.OnAuthorizationAsync(authorizationContext); + + // Assert + Assert.NotNull(authorizationContext.Result); + } + + public async Task Invoke_NoPoliciesShouldNotFail() + { + // Arrange + var authorizeAttribute = new AuthorizeAttribute("CanViewPage"); + var authorizationContext = GetAuthorizationContext(services => + { + services.AddAuthorization(); + services.AddTransient(); + }); // Act await authorizeAttribute.OnAuthorizationAsync(authorizationContext); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Filters/AuthorizeAttributeTestsBase.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Filters/AuthorizeAttributeTestsBase.cs index 2daddc8006..c6a50844c4 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Filters/AuthorizeAttributeTestsBase.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Filters/AuthorizeAttributeTestsBase.cs @@ -21,9 +21,18 @@ namespace Microsoft.AspNet.Mvc.Core.Test new Claim[] { new Claim("Permission", "CanViewPage"), new Claim(ClaimTypes.Role, "Administrator"), + new Claim(ClaimTypes.Role, "User"), new Claim(ClaimTypes.NameIdentifier, "John")}, "Basic")); + validUser.AddIdentity( + new ClaimsIdentity( + new Claim[] { + new Claim("Permission", "CupBearer"), + new Claim(ClaimTypes.Role, "Token"), + new Claim(ClaimTypes.NameIdentifier, "John Bear")}, + "Bearer")); + // ServiceProvider var serviceCollection = new ServiceCollection(); if (registerServices != null) diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/FiltersTest.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/FiltersTest.cs index 75aa9a7f74..27ef0e4dcd 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/FiltersTest.cs +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/FiltersTest.cs @@ -122,6 +122,37 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests Assert.Equal("Hello World!", await response.Content.ReadAsStringAsync()); } + [Fact] + public async Task AllowAnonymousOverridesAuthorize() + { + // Arrange + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // Act + var response = await client.GetAsync( + "http://localhost/AuthorizeUser/AlwaysCanCallAllowAnonymous"); + + // Assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal("Hello World!", await response.Content.ReadAsStringAsync()); + } + + [Fact] + public async Task ImpossiblePolicyFailsAuthorize() + { + // Arrange + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // Act + var response = await client.GetAsync( + "http://localhost/AuthorizeUser/Impossible"); + + // Assert + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + } + [Fact] public async Task ServiceFilterUsesRegisteredServicesAsFilter() { diff --git a/test/WebSites/FiltersWebSite/AuthorizeBasicMiddleware.cs b/test/WebSites/FiltersWebSite/AuthorizeBasicMiddleware.cs new file mode 100644 index 0000000000..8f17b77b03 --- /dev/null +++ b/test/WebSites/FiltersWebSite/AuthorizeBasicMiddleware.cs @@ -0,0 +1,61 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Security.Claims; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.Framework.OptionsModel; + +namespace FiltersWebSite +{ + public class BasicOptions : AuthenticationOptions + { + public BasicOptions() + { + AuthenticationType = "Basic"; + AuthenticationMode = AuthenticationMode.Passive; + } + + } + + public class AuthorizeBasicMiddleware : AuthenticationMiddleware + { + public AuthorizeBasicMiddleware( + RequestDelegate next, + IServiceProvider services, + IOptions options) : + base(next, services, options, null) + { } + + protected override AuthenticationHandler CreateHandler() + { + return new BasicAuthenticationHandler(); + } + } + + public class BasicAuthenticationHandler : AuthenticationHandler + { + protected override void ApplyResponseChallenge() + { + } + + protected override void ApplyResponseGrant() + { + } + + protected override AuthenticationTicket AuthenticateCore() + { + var id = new ClaimsIdentity( + new Claim[] { + new Claim("Permission", "CanViewPage"), + new Claim(ClaimTypes.Role, "Administrator"), + new Claim(ClaimTypes.NameIdentifier, "John")}, + "Basic"); + + return new AuthenticationTicket(id, new AuthenticationProperties()); + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Controllers/AuthorizeUserController.cs b/test/WebSites/FiltersWebSite/Controllers/AuthorizeUserController.cs index 637d6a0301..27c8ba2a7c 100644 --- a/test/WebSites/FiltersWebSite/Controllers/AuthorizeUserController.cs +++ b/test/WebSites/FiltersWebSite/Controllers/AuthorizeUserController.cs @@ -6,12 +6,27 @@ using Microsoft.AspNet.Mvc; namespace FiltersWebSite { [AuthorizeUser] + [Authorize("RequireBasic")] public class AuthorizeUserController : Controller { - [Authorize("Permission", "CanViewPage")] + [Authorize("CanViewPage")] public string ReturnHelloWorldOnlyForAuthorizedUser() { return "Hello World!"; } + + [Authorize("Impossible")] + [AllowAnonymous] + public string AlwaysCanCallAllowAnonymous() + { + return "Hello World!"; + } + + [Authorize("Impossible")] + public string Impossible() + { + return "Hello World!"; + } + } } \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Startup.cs b/test/WebSites/FiltersWebSite/Startup.cs index f95b7b6644..70ea5da1c3 100644 --- a/test/WebSites/FiltersWebSite/Startup.cs +++ b/test/WebSites/FiltersWebSite/Startup.cs @@ -1,8 +1,10 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Security.Claims; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Mvc; +using Microsoft.AspNet.Security; using Microsoft.Framework.DependencyInjection; namespace FiltersWebSite @@ -16,6 +18,21 @@ namespace FiltersWebSite app.UseServices(services => { services.AddMvc(configuration); + services.Configure(options => + { + // This policy cannot succeed since it has no requirements + options.AddPolicy("Impossible", + new AuthorizationPolicyBuilder() + .Build()); + options.AddPolicy("RequireBasic", + new AuthorizationPolicyBuilder("Basic") + .RequiresClaim(ClaimTypes.NameIdentifier) + .Build()); + options.AddPolicy("CanViewPage", + new AuthorizationPolicyBuilder() + .RequiresClaim("Permission", "CanViewPage") + .Build()); + }); services.AddSingleton(); services.AddSingleton(); @@ -31,6 +48,8 @@ namespace FiltersWebSite app.UseErrorReporter(); + app.UseMiddleware(); + app.UseMvc(); } }