如何在ASP.NET Core 6中配置Azure AD独立登录/登出页面
自定义Azure AD登录页:未认证用户重定向至自有Razor页面(ASP.NET Core 6)
问题背景
我之前集成Okta时,它提供可嵌入的登录组件,能通过控制器触发认证流程。但Azure AD没有类似组件,所以我想把带自有Logo的Razor页面(路径/pages/login/index)设为唯一允许匿名访问的页面,作为未登录用户的初始界面,点击页面按钮后调用控制器Post操作跳转至Azure AD登录页。
当前代码会直接跳转到微软登录页,核心Program.cs代码如下:
using System.Collections.Generic; using System.Configuration; using System.IO; using Project.Models; using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Authorization; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Hosting; using Microsoft.Identity.Web; using Microsoft.Identity.Web.UI; var builder = WebApplication.CreateBuilder(args); //authentication pipeline var initialScopes = builder.Configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' '); builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi")) .AddInMemoryTokenCaches(); builder.Services.AddControllers(options => { var policy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); options.Filters.Add(new AuthorizeFilter(policy)); }); builder.Services.AddRazorPages() .AddMicrosoftIdentityUI(); var RootPath = builder.Environment.ContentRootPath; var WebPath = builder.Environment.WebRootPath; var fileDirectory = Path.Combine(Directory.GetParent(RootPath).Parent.ToString(), "armsfiles"); IFileProvider physicalProvider = new PhysicalFileProvider(fileDirectory); builder.Services.AddSingleton<IFileProvider>(physicalProvider); var connectionString = builder.Configuration.GetConnectionString("DBContext"); builder.Services.AddDbContext<DBContext>(options => options.UseSqlServer(connectionString)); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); app.UseHsts(); } else { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseStaticFiles(new StaticFileOptions { FileProvider = physicalProvider, RequestPath = "/files" }); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapRazorPages(); app.MapControllerRoute( name: "default", pattern: "{controller}/{action}/{id?}", defaults: new { controller = "Home", action = "Index" }); app.Run();
尝试过的配置
我曾添加过Razor页面权限配置,但不确定是否生效,因为找不到未登录用户的重定向设置:
builder.Services.AddRazorPages().AddRazorPagesOptions(options => { options.Conventions.AllowAnonymousToFolder("/Login"); options.Conventions.AuthorizeFolder("/"); options.Conventions.AuthorizeFolder("/files"); });
已解决的部分(2022年11月22日更新)
除了未认证用户自动重定向至/login/页面外,其余问题已解决。登录页按钮的OnPost方法已实现挑战逻辑:
public class IndexModel : PageModel { private string SignedInRedirectUri; public IndexModel(IConfiguration configuration) { SignedInRedirectUri = configuration["AzureAd:SignedInRedirectUri"]; } public void OnGet() { } public IActionResult OnPost() { return Challenge( new AuthenticationProperties { RedirectUri = SignedInRedirectUri }, OpenIdConnectDefaults.AuthenticationScheme); } }
核心疑问
是否存在类似Cookie认证中设置LoginPath的方式,让未认证用户自动重定向到自定义登录页?比如Cookie认证的配置方式:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(cookieOptions => { cookieOptions.Cookie.Name = "UserLoginCookie"; cookieOptions.LoginPath = "/Login/"; cookieOptions.ExpireTimeSpan = TimeSpan.FromMinutes(30); cookieOptions.SlidingExpiration = true; });
解决方案
在ASP.NET Core 6中使用Azure AD(Microsoft Identity Web)时,要实现未认证用户重定向到自定义登录页,需要通过Cookie认证选项配置,因为Azure AD的OpenID Connect认证最终依赖Cookie维持会话。
修改认证配置
修改Program.cs中的认证配置段,在AddMicrosoftIdentityWebApp之后添加Cookie配置,指定LoginPath:
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi")) .AddInMemoryTokenCaches() // 配置Cookie认证的LoginPath,指向自定义登录页 .AddCookie(options => { options.LoginPath = "/Login"; });
确保Razor页面权限配置正确
调整Razor页面服务配置,确保/Login文件夹允许匿名访问,其余路径强制认证:
builder.Services.AddRazorPages(options => { options.Conventions.AllowAnonymousToFolder("/Login"); options.Conventions.AuthorizeFolder("/"); options.Conventions.AuthorizeFolder("/files"); }) .AddMicrosoftIdentityUI();
关键说明
- Azure AD的OpenID Connect认证默认使用Cookie存储会话,因此修改Cookie认证的
LoginPath即可控制未认证用户的重定向目标。 - 自定义登录页的
OnPost触发Azure AD认证的逻辑无需修改,保持现有实现即可。 - 必须确保
/Login路径确实允许匿名访问,否则会出现重定向循环。
内容的提问来源于stack exchange,提问作者Qiuzman
相关产品推荐
相关产品推荐

