c# - 在 ASP.net Framework 和 Core 2 之间使用身份验证 Cookie 进行单点登录
问题描述
我们有一系列应用程序通过共享的 ASP 身份验证 cookie 使用单点登录。这些应用程序是在 Framework 4.6.1 中构建的 MVC 应用程序。所有的应用程序都在同一个域上,所以设置cookie域可以让我们实现单点登录。
我们正在研究使用 .net core 3 添加新应用程序的可能性。我知道这里有在 Framework 和 Core 之间设置共享 cookie 的文档
我已尝试按照本指南进行操作,但我无法看到新的核心应用程序拾取 cookie。
框架 Sarup.Auth 在这里找到
namespace Authentication
{
public partial class Startup
{
private static void ApplyRedirect(CookieApplyRedirectContext context)
{
Uri absoluteUri;
if (Uri.TryCreate(context.RedirectUri, UriKind.Absolute, out absoluteUri))
{
var path = PathString.FromUriComponent(absoluteUri);
if (path == context.OwinContext.Request.PathBase + context.Options.LoginPath)
{
context.RedirectUri = AppLocator.GetAppBaseUrl(AppType.Net) + "/Account/Account/Login" +
new QueryString(
context.Options.ReturnUrlParameter,
context.Request.Uri.AbsoluteUri);
}
}
context.Response.Redirect(context.RedirectUri);
}
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
CookieName = ".AspNet.SharedCookie",
CookieDomain = ConfigurationManager.AppSettings["CookieDomain"],
AuthenticationType = "Identity.Application",
LoginPath = new PathString("/Account/Login"),
LogoutPath = new PathString("/Account/Logout"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, User, int>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
getUserIdCallback: (id) => (id.GetUserId<int>())),
OnApplyRedirect = ApplyRedirect
},
ExpireTimeSpan = TimeSpan.FromMinutes(ApplicationConfiguration.GetCookieSessionTimoutInMinutes()),
SlidingExpiration = true,
TicketDataFormat = new AspNetTicketDataFormat(
new DataProtectorShim(
DataProtectionProvider.Create(new DirectoryInfo(@"c:\shared-auth-ticket-keys\"), (builder) => { builder.SetApplicationName("SharedCookieApp"); })
.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies." +
"CookieAuthenticationMiddleware",
"Identity.Application",
"v2")))
});
}
我已经设置了新的 DataProtection 提供程序,并且在此应用程序中继续唱歌。新核心应用程序的设置
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace IdentityTest
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
});
services.AddControllersWithViews();
services.AddRazorPages();
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"c:\shared-auth-ticket-keys\"))
.SetApplicationName("SharedCookieApp");
services.AddAuthentication("Identity.Application").AddCookie("Identity.Application",options=>
{
options.Cookie.Name = ".AspNet.SharedCookie";
options.Cookie.Domain = "";
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.SecurePolicy = CookieSecurePolicy.None;
options.DataProtectionProvider = DataProtectionProvider.Create(new DirectoryInfo(@"c:\shared-auth-ticket-keys\")).CreateProtector("Microsoft.AspNetCore.Authentication.Cookies." +
"CookieAuthenticationMiddleware",
"Identity.Application",
"v2");
});
//services.ConfigureApplicationCookie(options => {
// options.Cookie.Name = ".AspNet.SharedCookie";
//});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
var cookiePolicyOptions = new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.None,
Secure = CookieSecurePolicy.None
};
app.UseCookiePolicy(cookiePolicyOptions);
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
}
}
当我尝试导航到授权控制器时,我在我的应用程序中看到以下输出
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed.
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[12]
AuthenticationScheme: Identity.Application was challenged.
所以它似乎在尝试使用正确的方法进行授权,但没有获取应该在应用程序之间共享的 cookie。声明身份未创建且用户未显示为已通过身份验证。
有没有人成功地跨框架和核心 2/3 应用程序生成共享 cookie。有没有我遗漏的问题。我想知道是不是因为我正在使用框架身份进入核心而不是相反。但任何帮助或见解将不胜感激。
解决方案
推荐阅读
- php - ZF3 你能记录未捕获的异常吗?
- mysql - MySQL - 如何根据两个不同表之间的关系从表中选择所有结果?
- rust - 如何检索 Rust 编译器插件中绑定的特征的完整路径?
- javascript - 年复一年
- javascript - 在托管环境中重新连接到以前的 Puppeteer 会话
- r - 基因表达不起作用,因为“参数意味着不同的行数”
- java - 从 JSP 调用 servlet 时 request.getParameter 中的空值
- ios - UIPickerView 在错误的组件中选择行(需要驱魔?)
- checkbox - 错误:不正确的维数 Shiny
- build - 为外部 CMake 依赖项指定构建选项