我想在 ASP.NET Core MVC 应用程序中结合 Okta 和 Entra 身份验证方案。
Program.cs
:
// Okta
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.LoginPath = new PathString("/Account/SignIn");
})
.AddOktaMvc(new OktaMvcOptions
{
OktaDomain = builder.Configuration.GetValue<string>("Okta:OktaDomain"),
ClientId = builder.Configuration.GetValue<string>("Okta:ClientId"),
ClientSecret = builder.Configuration.GetValue<string>("Okta:ClientSecret"),
AuthorizationServerId = builder.Configuration.GetValue<string>("Okta:AuthorizationServerId"),
Scope = new List<string> { "openid", "profile", "email" },
});
// Entra
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
但是,我收到此错误:
System.InvalidOperationException:“方案已存在:Cookie”
如何将两者结合起来,以便内部用户将使用 Entra 进行身份验证,而外部用户将使用 Okta 进行身份验证?
System.InvalidOperationException:'方案已存在:Cookies
我通过在
Program.cs
类中添加 okta 的 cookie 身份验证和 Entra 身份验证来修复上述错误。
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "OktaScheme";
})
.AddCookie("Cookies", options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
})
程序.cs:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "OktaScheme";
})
.AddCookie("Cookies", options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
})
.AddOpenIdConnect("OktaScheme", options =>
{
options.ClientId = builder.Configuration["Okta:ClientId"];
options.ClientSecret = builder.Configuration["Okta:ClientSecret"];
options.Authority = $"{builder.Configuration["Okta:OktaDomain"]}/oauth2/{builder.Configuration["Okta:AuthorizationServerId"]}";
options.ResponseType = "code";
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");
options.SaveTokens = true;
options.CallbackPath = new PathString("/authorization-code/callback");
})
.AddMicrosoftIdentityWebApp(options =>
{
builder.Configuration.GetSection("AzureAd").Bind(options);
options.NonceCookie.SecurePolicy = CookieSecurePolicy.Always;
options.CorrelationCookie.SecurePolicy = CookieSecurePolicy.Always;
}, null, "EntraScheme", null);
builder.Services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
builder.Services.AddRazorPages()
.AddMicrosoftIdentityUI();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();
app.Run();
AccountController.cs:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;
namespace WebApplication11.Controllers
{
public class AccountController : Controller
{
[HttpGet]
public IActionResult SignIn(string userType)
{
if (userType == "internal")
{
return Challenge(new AuthenticationProperties { RedirectUri = "/" }, "EntraScheme");
}
else
{
return Challenge(new AuthenticationProperties { RedirectUri = "/" }, "OktaScheme");
}
}
[HttpGet]
public IActionResult SignOut()
{
return SignOut(
new AuthenticationProperties { RedirectUri = "/" },
CookieAuthenticationDefaults.AuthenticationScheme, "OktaScheme", "EntraScheme");
}
}
}
appsettings.json:
{
"Okta": {
"OktaDomain": "https://<domain>.okta.com",
"ClientId": "<clientID>",
"ClientSecret": "<clientSecret>",
"AuthorizationServerId": "default"
},
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "<domain>.onmicrosoft.com",
"TenantId": "<tenantID>",
"ClientId": "<clientID>",
"CallbackPath": "/authorization-code/callback"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}