Add CombineAuthorizeFilters option
This commit is contained in:
parent
acd6f7b064
commit
73bd09dc1c
|
|
@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Mvc.Core;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.AspNetCore.Mvc.Internal;
|
using Microsoft.AspNetCore.Mvc.Internal;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.Authorization
|
namespace Microsoft.AspNetCore.Mvc.Authorization
|
||||||
{
|
{
|
||||||
|
|
@ -22,6 +23,9 @@ namespace Microsoft.AspNetCore.Mvc.Authorization
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AuthorizeFilter : IAsyncAuthorizationFilter, IFilterFactory
|
public class AuthorizeFilter : IAsyncAuthorizationFilter, IFilterFactory
|
||||||
{
|
{
|
||||||
|
private MvcOptions _mvcOptions;
|
||||||
|
private AuthorizationPolicy _effectivePolicy;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new <see cref="AuthorizeFilter"/> instance.
|
/// Initializes a new <see cref="AuthorizeFilter"/> instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -104,15 +108,46 @@ namespace Microsoft.AspNetCore.Mvc.Authorization
|
||||||
|
|
||||||
bool IFilterFactory.IsReusable => true;
|
bool IFilterFactory.IsReusable => true;
|
||||||
|
|
||||||
/// <inheritdoc />
|
private async Task<AuthorizationPolicy> GetEffectivePolicyAsync(AuthorizationFilterContext context)
|
||||||
public virtual async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
|
||||||
{
|
{
|
||||||
if (context == null)
|
if (_effectivePolicy != null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(context));
|
return _effectivePolicy;
|
||||||
}
|
}
|
||||||
|
|
||||||
var effectivePolicy = Policy;
|
var effectivePolicy = Policy;
|
||||||
|
|
||||||
|
if (_mvcOptions == null)
|
||||||
|
{
|
||||||
|
_mvcOptions = context.HttpContext.RequestServices.GetRequiredService<IOptions<MvcOptions>>().Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_mvcOptions.CombineAuthorizeFilters)
|
||||||
|
{
|
||||||
|
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 (effectivePolicy == null)
|
||||||
{
|
{
|
||||||
if (PolicyProvider == null)
|
if (PolicyProvider == null)
|
||||||
|
|
@ -126,6 +161,24 @@ namespace Microsoft.AspNetCore.Mvc.Authorization
|
||||||
effectivePolicy = await AuthorizationPolicy.CombineAsync(PolicyProvider, AuthorizeData);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
||||||
|
{
|
||||||
|
if (context == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
var effectivePolicy = await GetEffectivePolicyAsync(context);
|
||||||
if (effectivePolicy == null)
|
if (effectivePolicy == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.AspNetCore.Mvc.Formatters;
|
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||||
|
|
@ -242,6 +243,13 @@ namespace Microsoft.AspNetCore.Mvc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool RequireHttpsPermanent { get; set; }
|
public bool RequireHttpsPermanent { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value that determines if policies on instances of <see cref="AuthorizeFilter" />
|
||||||
|
/// will be combined into a single effective policy. This was always to be the intended behavior,
|
||||||
|
/// but was not the case.
|
||||||
|
/// </summary>
|
||||||
|
public bool CombineAuthorizeFilters { get; set;}
|
||||||
|
|
||||||
IEnumerator<ICompatibilitySwitch> IEnumerable<ICompatibilitySwitch>.GetEnumerator()
|
IEnumerator<ICompatibilitySwitch> IEnumerable<ICompatibilitySwitch>.GetEnumerator()
|
||||||
{
|
{
|
||||||
return ((IEnumerable<ICompatibilitySwitch>)_switches).GetEnumerator();
|
return ((IEnumerable<ICompatibilitySwitch>)_switches).GetEnumerator();
|
||||||
|
|
|
||||||
|
|
@ -221,6 +221,68 @@ namespace Microsoft.AspNetCore.Mvc.Authorization
|
||||||
Assert.Null(authorizationContext.Result);
|
Assert.Null(authorizationContext.Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AuthorizationFilterCombinesMultipleFilters()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAssertion(a => true).Build());
|
||||||
|
var authorizationContext = GetAuthorizationContext(anonymous: false, registerServices: s => s.Configure<MvcOptions>(o => o.CombineAuthorizeFilters = true));
|
||||||
|
// Effective policy should fail, if both are combined
|
||||||
|
authorizationContext.Filters.Add(authorizeFilter);
|
||||||
|
var secondFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAssertion(a => false).Build());
|
||||||
|
authorizationContext.Filters.Add(secondFilter);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await secondFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<ForbidResult>(authorizationContext.Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AuthorizationFilterIgnoresFirstFilterWhenCombining()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAssertion(a => false).Build());
|
||||||
|
var authorizationContext = GetAuthorizationContext(anonymous: false, registerServices: s => s.Configure<MvcOptions>(o => o.CombineAuthorizeFilters = true));
|
||||||
|
// Effective policy should fail, if both are combined
|
||||||
|
authorizationContext.Filters.Add(authorizeFilter);
|
||||||
|
var secondFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAssertion(a => false).Build());
|
||||||
|
authorizationContext.Filters.Add(secondFilter);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Null(authorizationContext.Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AuthorizationFilterCombinesDerivedFilters()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAssertion(a => true).Build());
|
||||||
|
var authorizationContext = GetAuthorizationContext(anonymous: false, registerServices: s => s.Configure<MvcOptions>(o => o.CombineAuthorizeFilters = true));
|
||||||
|
// Effective policy should fail, if both are combined
|
||||||
|
authorizationContext.Filters.Add(authorizeFilter);
|
||||||
|
authorizationContext.Filters.Add(new DerivedAuthorizeFilter());
|
||||||
|
authorizationContext.Filters.Add(new DerivedAuthorizeFilter());
|
||||||
|
var lastFilter = new DerivedAuthorizeFilter();
|
||||||
|
authorizationContext.Filters.Add(lastFilter);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await lastFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<ForbidResult>(authorizationContext.Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DerivedAuthorizeFilter : AuthorizeFilter
|
||||||
|
{
|
||||||
|
public DerivedAuthorizeFilter() : base(new AuthorizationPolicyBuilder().RequireAssertion(a => false).Build())
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task AuthZResourceShouldBeAuthorizationFilterContext()
|
public async Task AuthZResourceShouldBeAuthorizationFilterContext()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Copyright (c) .NET Foundation. 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.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using SecurityWebSite;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
|
{
|
||||||
|
public class CombineAuthorizeTests : IClassFixture<MvcTestFixture<StartupWithGlobalAuthorizeAndCombineAuthorizeFilters>>
|
||||||
|
{
|
||||||
|
public CombineAuthorizeTests(MvcTestFixture<StartupWithGlobalAuthorizeAndCombineAuthorizeFilters> fixture)
|
||||||
|
{
|
||||||
|
Client = fixture.Client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpClient Client { get; }
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task CanAuthorizeWithOnlyCookie2()
|
||||||
|
{
|
||||||
|
// Arrange & Act
|
||||||
|
var response = await Client.PostAsync("http://localhost/Administration/SignInCookie2", null);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.True(response.Headers.Contains("Set-Cookie"));
|
||||||
|
|
||||||
|
var cookie2 = response.Headers.GetValues("Set-Cookie").SingleOrDefault();
|
||||||
|
|
||||||
|
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Administration/EitherCookie");
|
||||||
|
request.Headers.Add("Cookie", cookie2);
|
||||||
|
|
||||||
|
response = await Client.SendAsync(request);
|
||||||
|
var body = await response.Content.ReadAsStringAsync();
|
||||||
|
Assert.Equal("Administration.EitherCookie:AuthorizeCount=1", body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -42,5 +43,30 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
var body = await response.Content.ReadAsStringAsync();
|
var body = await response.Content.ReadAsStringAsync();
|
||||||
Assert.Equal("Administration.AllowAnonymousAction", body);
|
Assert.Equal("Administration.AllowAnonymousAction", body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AuthorizationPoliciesDoNotCombineByDefault()
|
||||||
|
{
|
||||||
|
// Arrange & Act
|
||||||
|
var response = await Client.PostAsync("http://localhost/Administration/SignInCookie2", null);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.True(response.Headers.Contains("Set-Cookie"));
|
||||||
|
|
||||||
|
var cookie2 = response.Headers.GetValues("Set-Cookie").SingleOrDefault();
|
||||||
|
|
||||||
|
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Administration/EitherCookie");
|
||||||
|
request.Headers.Add("Cookie", cookie2);
|
||||||
|
|
||||||
|
// Will fail because default cookie is not sent so [Authorize] fails
|
||||||
|
response = await Client.SendAsync(request);
|
||||||
|
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Headers.Location);
|
||||||
|
Assert.Equal(
|
||||||
|
"http://localhost/Home/Login?ReturnUrl=%2FAdministration%2FEitherCookie",
|
||||||
|
response.Headers.Location.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -17,6 +17,7 @@ using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
using Microsoft.Extensions.ObjectPool;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.IntegrationTests
|
namespace Microsoft.AspNetCore.Mvc.IntegrationTests
|
||||||
|
|
@ -70,8 +71,8 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
|
||||||
serviceCollection.AddMvc();
|
serviceCollection.AddMvc();
|
||||||
serviceCollection
|
serviceCollection
|
||||||
.AddTransient<ILoggerFactory, LoggerFactory>()
|
.AddTransient<ILoggerFactory, LoggerFactory>()
|
||||||
.AddTransient<ILogger<DefaultAuthorizationService>, Logger<DefaultAuthorizationService>>();
|
.AddTransient<ILogger<DefaultAuthorizationService>, Logger<DefaultAuthorizationService>>()
|
||||||
|
.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();
|
||||||
return serviceCollection.BuildServiceProvider();
|
return serviceCollection.BuildServiceProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,13 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Authorization.Policy;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace SecurityWebSite.Controllers
|
namespace SecurityWebSite.Controllers
|
||||||
{
|
{
|
||||||
|
|
@ -15,10 +20,27 @@ namespace SecurityWebSite.Controllers
|
||||||
return Content("Administration.Index");
|
return Content("Administration.Index");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Either cookie should allow access to this action (if CombineAuthorizeFilters is true)
|
||||||
|
// If CombineAuthorizeFilters is false, the main cookie is required.
|
||||||
|
[Authorize(AuthenticationSchemes = "Cookie2")]
|
||||||
|
public IActionResult EitherCookie()
|
||||||
|
{
|
||||||
|
var countEvaluator = (CountingPolicyEvaluator)HttpContext.RequestServices.GetRequiredService<IPolicyEvaluator>();
|
||||||
|
return Content("Administration.EitherCookie:AuthorizeCount="+countEvaluator.AuthorizeCount);
|
||||||
|
}
|
||||||
|
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public IActionResult AllowAnonymousAction()
|
public IActionResult AllowAnonymousAction()
|
||||||
{
|
{
|
||||||
return Content("Administration.AllowAnonymousAction");
|
return Content("Administration.AllowAnonymousAction");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AllowAnonymous]
|
||||||
|
public async Task<IActionResult> SignInCookie2()
|
||||||
|
{
|
||||||
|
await HttpContext.SignInAsync("Cookie2", new ClaimsPrincipal(new ClaimsIdentity("Cookie2")));
|
||||||
|
return Content("SignInCookie2");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright (c) .NET Foundation. 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.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Authorization.Policy;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
|
namespace SecurityWebSite
|
||||||
|
{
|
||||||
|
public class CountingPolicyEvaluator : PolicyEvaluator
|
||||||
|
{
|
||||||
|
public int AuthorizeCount { get; private set; }
|
||||||
|
|
||||||
|
public CountingPolicyEvaluator(IAuthorizationService authorization) : base(authorization) { }
|
||||||
|
|
||||||
|
public override Task<PolicyAuthorizationResult> AuthorizeAsync(AuthorizationPolicy policy, AuthenticateResult authenticationResult, HttpContext context, object resource) {
|
||||||
|
AuthorizeCount++;
|
||||||
|
return base.AuthorizeAsync(policy, authenticationResult, context, resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Mvc\Microsoft.AspNetCore.Mvc.csproj" />
|
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Mvc\Microsoft.AspNetCore.Mvc.csproj" />
|
||||||
|
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Authorization.Policy" Version="$(MicrosoftAspNetCoreAuthorizationPolicyPackageVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="$(MicrosoftAspNetCoreAuthenticationCookiesPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="$(MicrosoftAspNetCoreAuthenticationCookiesPackageVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
|
using Microsoft.AspNetCore.Authorization.Policy;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace SecurityWebSite
|
namespace SecurityWebSite
|
||||||
|
|
@ -19,7 +20,9 @@ namespace SecurityWebSite
|
||||||
{
|
{
|
||||||
options.LoginPath = "/Home/Login";
|
options.LoginPath = "/Home/Login";
|
||||||
options.LogoutPath = "/Home/Logout";
|
options.LogoutPath = "/Home/Logout";
|
||||||
});
|
}).AddCookie("Cookie2");
|
||||||
|
|
||||||
|
services.AddScoped<IPolicyEvaluator, CountingPolicyEvaluator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
|
using Microsoft.AspNetCore.Authorization.Policy;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace SecurityWebSite
|
||||||
|
{
|
||||||
|
public class StartupWithGlobalAuthorizeAndCombineAuthorizeFilters
|
||||||
|
{
|
||||||
|
// This method gets called by the runtime. Use this method to add services to the container.
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
// Add framework services.
|
||||||
|
services.AddMvc(o =>
|
||||||
|
{
|
||||||
|
o.CombineAuthorizeFilters = true;
|
||||||
|
o.Filters.Add(new AuthorizeFilter());
|
||||||
|
});
|
||||||
|
|
||||||
|
services.AddAntiforgery();
|
||||||
|
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
|
||||||
|
{
|
||||||
|
options.LoginPath = "/Home/Login";
|
||||||
|
options.LogoutPath = "/Home/Logout";
|
||||||
|
}).AddCookie("Cookie2");
|
||||||
|
|
||||||
|
services.AddScoped<IPolicyEvaluator, CountingPolicyEvaluator>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
public void Configure(IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
app.UseAuthentication();
|
||||||
|
|
||||||
|
app.UseMvc(routes =>
|
||||||
|
{
|
||||||
|
routes.MapRoute(
|
||||||
|
name: "default",
|
||||||
|
template: "{controller=Home}/{action=Index}/{id?}");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
|
using Microsoft.AspNetCore.Authorization.Policy;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Mvc.Authorization;
|
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
@ -18,12 +19,14 @@ namespace SecurityWebSite
|
||||||
{
|
{
|
||||||
options.LoginPath = "/Home/Login";
|
options.LoginPath = "/Home/Login";
|
||||||
options.LogoutPath = "/Home/Logout";
|
options.LogoutPath = "/Home/Logout";
|
||||||
});
|
}).AddCookie("Cookie2");
|
||||||
|
|
||||||
services.AddMvc(o =>
|
services.AddMvc(o =>
|
||||||
{
|
{
|
||||||
o.Filters.Add(new AuthorizeFilter());
|
o.Filters.Add(new AuthorizeFilter());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
services.AddScoped<IPolicyEvaluator, CountingPolicyEvaluator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Configure(IApplicationBuilder app)
|
public void Configure(IApplicationBuilder app)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue