首页 > 解决方案 > 在 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。有没有我遗漏的问题。我想知道是不是因为我正在使用框架身份进入核心而不是相反。但任何帮助或见解将不胜感激。

标签: c#asp.netasp.net-corecookiesasp.net-identity

解决方案


推荐阅读