Add AllowAnonymous for some Identity razor pages (#1644)
Addresses #1617
This commit is contained in:
parent
e0885a5017
commit
298a1e2a78
|
|
@ -5,12 +5,14 @@ using System;
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||
{
|
||||
[AllowAnonymous]
|
||||
[IdentityDefaultUI(typeof(ForgotPasswordModel<>))]
|
||||
public abstract class ForgotPasswordModel : PageModel
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@ using System.ComponentModel.DataAnnotations;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||
{
|
||||
[AllowAnonymous]
|
||||
[IdentityDefaultUI(typeof(LoginModel<>))]
|
||||
public abstract class LoginModel : PageModel
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,12 +4,14 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||
{
|
||||
[AllowAnonymous]
|
||||
[IdentityDefaultUI(typeof(LoginWith2faModel<>))]
|
||||
public abstract class LoginWith2faModel : PageModel
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,12 +4,14 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||
{
|
||||
[AllowAnonymous]
|
||||
[IdentityDefaultUI(typeof(LoginWithRecoveryCodeModel<>))]
|
||||
public abstract class LoginWithRecoveryCodeModel : PageModel
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@
|
|||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||
{
|
||||
[AllowAnonymous]
|
||||
[IdentityDefaultUI(typeof(LogoutModel<>))]
|
||||
public abstract class LogoutModel : PageModel
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
|
@ -12,6 +13,7 @@ using Microsoft.Extensions.Logging;
|
|||
|
||||
namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||
{
|
||||
[AllowAnonymous]
|
||||
[IdentityDefaultUI(typeof(RegisterModel<>))]
|
||||
public abstract class RegisterModel : PageModel
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity.UI.Pages
|
||||
{
|
||||
[AllowAnonymous]
|
||||
public class ErrorModel : PageModel
|
||||
{
|
||||
public string RequestId { get; set; }
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
|
|||
"/Identity/Account/Manage/SetPassword",
|
||||
"/Identity/Account/Manage/ShowRecoveryCodes",
|
||||
"/Identity/Account/Manage/TwoFactorAuthentication",
|
||||
"/Identity/Account/Logout",
|
||||
};
|
||||
|
||||
[Theory]
|
||||
|
|
@ -78,7 +77,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
|
|||
// Arrange
|
||||
var client = ServerFactory.CreateDefaultClient();
|
||||
await UserStories.RegisterNewUserAsync(client);
|
||||
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync(url);
|
||||
|
||||
|
|
@ -117,5 +116,31 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
|
|||
// Assert
|
||||
await ResponseAssert.IsHtmlDocumentAsync(response);
|
||||
}
|
||||
|
||||
public static TheoryData<string> UnauthorizedPagesAllowAnonymous =>
|
||||
new TheoryData<string>
|
||||
{
|
||||
"/Identity/Error",
|
||||
"/Identity/Account/Register",
|
||||
"/Identity/Account/Login",
|
||||
"/Identity/Account/ForgotPassword",
|
||||
"/Identity/Account/Logout"
|
||||
};
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(UnauthorizedPagesAllowAnonymous))]
|
||||
public async Task AnonymousUserAllowedAccessToPages_WithGlobalAuthorizationFilter(string url)
|
||||
{
|
||||
// Arrange
|
||||
var server = ServerFactory.CreateServer(builder =>
|
||||
builder.ConfigureServices(services => services.SetupGlobalAuthorizeFilter()));
|
||||
var client = ServerFactory.CreateDefaultClient(server);
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
await ResponseAssert.IsHtmlDocumentAsync(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Identity.DefaultUI.WebSite;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
|
|
@ -25,5 +27,15 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
|
|||
|
||||
public static IServiceCollection SetupEmailRequired(this IServiceCollection services) =>
|
||||
services.Configure<IdentityOptions>(o => o.SignIn.RequireConfirmedEmail = true);
|
||||
|
||||
public static IServiceCollection SetupGlobalAuthorizeFilter(this IServiceCollection services) =>
|
||||
services.AddMvc(config =>
|
||||
{
|
||||
var policy = new AuthorizationPolicyBuilder()
|
||||
.RequireAuthenticatedUser()
|
||||
.Build();
|
||||
config.Filters.Add(new AuthorizeFilter(policy));
|
||||
})
|
||||
.Services;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,28 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
|
|||
await UserStories.LoginExistingUser2FaAsync(newClient, userName, password, twoFactorKey);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanLogInWithTwoFactorAuthentication_WithGlobalAuthorizeFilter()
|
||||
{
|
||||
// Arrange
|
||||
var server = ServerFactory.CreateServer(builder =>
|
||||
builder.ConfigureServices(services => services.SetupGlobalAuthorizeFilter()));
|
||||
var client = ServerFactory.CreateDefaultClient(server);
|
||||
var newClient = ServerFactory.CreateDefaultClient(server);
|
||||
|
||||
var userName = $"{Guid.NewGuid()}@example.com";
|
||||
var password = $"!Test.Password1$";
|
||||
|
||||
var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password);
|
||||
var showRecoveryCodes = await UserStories.EnableTwoFactorAuthentication(loggedIn);
|
||||
|
||||
var twoFactorKey = showRecoveryCodes.Context.AuthenticatorKey;
|
||||
|
||||
// Act & Assert
|
||||
// Use a new client to simulate a new browser session.
|
||||
await UserStories.LoginExistingUser2FaAsync(newClient, userName, password, twoFactorKey);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanLogInWithRecoveryCode()
|
||||
{
|
||||
|
|
@ -79,6 +101,28 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
|
|||
await UserStories.LoginExistingUserRecoveryCodeAsync(newClient, userName, password, recoveryCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanLogInWithRecoveryCode_WithGlobalAuthorizeFilter()
|
||||
{
|
||||
// Arrange
|
||||
var server = ServerFactory.CreateServer(builder =>
|
||||
builder.ConfigureServices(services => services.SetupGlobalAuthorizeFilter()));
|
||||
var client = ServerFactory.CreateDefaultClient(server);
|
||||
var newClient = ServerFactory.CreateDefaultClient(server);
|
||||
|
||||
var userName = $"{Guid.NewGuid()}@example.com";
|
||||
var password = $"!Test.Password1$";
|
||||
|
||||
var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password);
|
||||
var showRecoveryCodes = await UserStories.EnableTwoFactorAuthentication(loggedIn);
|
||||
|
||||
var recoveryCode = showRecoveryCodes.Context.RecoveryCodes.First();
|
||||
|
||||
// Act & Assert
|
||||
// Use a new client to simulate a new browser session.
|
||||
await UserStories.LoginExistingUserRecoveryCodeAsync(newClient, userName, password, recoveryCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CannotLogInWithoutRequiredEmailConfirmation()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
// 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.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace Identity.DefaultUI.WebSite.Pages
|
||||
{
|
||||
[AllowAnonymous]
|
||||
public class IndexModel : PageModel
|
||||
{
|
||||
public void OnGet()
|
||||
|
|
|
|||
Loading…
Reference in New Issue