繁体   English   中英

跨MVC 5和ASP.NET核心应用程序的基于Cookie的表单身份验证

[英]Cookie-based Forms Authentication Across MVC 5 and ASP.NET Core applications

我已经在不同的站点 之间使用了表单身份验证,甚至在不同版本的.NET之间 ,但现在我们正在考虑在 ASP.NET 5(MVC 6) ASP.NET Core中启动一个新项目,并希望使用基于cookie的两种形式的身份验证。 登录在“旧”MVC 5应用程序中完成。

是否可以使用当前版本的ASP.NET 5来支持基于cookie的表单身份验证的某些跨应用程序配置? 这可以使用FormsAuthenticationModule MVC6 ASP.NET Core端实现,还是可以使用新的身份验证中间件以某种方式播放? 还有其他建议吗?

在过去的几天里,我一直在为同样的问题敲打我的脑袋......但我已经解决了......(它似乎在坚持)

这是用于转换窗口和后来的窗体身份验证到窗体身份验证MVC5和MVC6所以希望你可以更改足够的代码使它适合你...我计划在重新编写登录脚本时更改一些部分。 (这是alpha所以会做出一些改变!)

我将以下代码放在我们的MVC5 Intranet站点中以获取Windows身份验证的角色

protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
    {
        // Get current windows Identity to get the roles out of it
        WindowsIdentity ident = WindowsIdentity.GetCurrent();

        string[] roles = new string[ident.Groups.Count];
        int i = 0;

        // get the groups from the current Identity
        foreach (var g in ident.Groups)
        {

            roles[i] = g.Translate(typeof(System.Security.Principal.NTAccount)).Value.ToString();
            i++;
        }

        // join into a single string  the roles that the user is a member of 
        string roleData = String.Join(";", roles) ;

        // create the forms ticket that all MVC5 sites with the same machine key will pick up.
        FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, ident.Name, DateTime.Now, DateTime.Now.AddMinutes(30), false, roleData, "/");
        string encTicket = FormsAuthentication.Encrypt(ticket);


        // add the user name first from the Principle and add Windows as this will come from Windows Auth
        roleData = ident.Name + ";" + "Windows;" + roleData;

        //use machine key to encrypt the data
        var encTicket2 = MachineKey.Protect(System.Text.Encoding.UTF8.GetBytes(roleData),
            "Microsoft.Owin.Security.Cookies.CookieAuthenticationMiddleware",
            "ApplicationCookie", "v1");

        //create a new cookie with a base64string of the encrypted bytes
        HttpCookie hc2 = new HttpCookie("cookie1", Convert.ToBase64String(encTicket2));
        hc2.Domain = ".domain.com";
        hc2.Expires = DateTime.Now.AddHours(8);
        Response.Cookies.Add(hc2);

        // NOTE: The name of the HttpCookie must match what the FormsAuth site expects.
        HttpCookie hc = new HttpCookie("cookie2", encTicket);
        hc.Domain = ".domain.com";
        hc.Expires = DateTime.Now.AddHours(8);
        Response.Cookies.Add(hc);
        // Ticket and cookie issued, now go to the FormsAuth site and all should be well.
        Response.Redirect("http://www.yoursite.com");
    }

这将在窗体和MVC6方法中创建一个Windows身份验证票证。

MVC6的字符串看起来像“John.Doe; Windows; Admin”

然后在MVC6启动文件中,我将以下代码放入configure部分......

        app.Use(async (context, next) =>
        {
            Logger _logger = new Logger("C:\\\\Logs\\Log.txt");
            try
            {

                var request = context.Request;
                var cookie = request.Cookies.Get("cookie1");
                var ticket = cookie.ToString();

                ticket = ticket.Replace(" ", "+");

                var padding = 3 - ((ticket.Length + 3)%4);
                if (padding != 0)
                    ticket = ticket + new string('=', padding);

                var bytes = Convert.FromBase64String(ticket);
                bytes = System.Web.Security.MachineKey.Unprotect(bytes,
                    "Microsoft.Owin.Security.Cookies.CookieAuthenticationMiddleware",
                    "ApplicationCookie", "v1");

                string ticketstring = System.Text.Encoding.UTF8.GetString(bytes);

                var ticketSplit = ticketstring.Split(';');

                var claims = new Claim[ticketSplit.Length];

                var OriginalIssuer = "";

                for (int index = 0; index != ticketSplit.Length; ++index)
                {

                    if (index == 0)
                    {
                        claims[index] = new Claim(ClaimTypes.Name, ticketSplit[index], "Windows");
                    }
                    else if (index == 1)
                    {
                        OriginalIssuer = ticketSplit[1];
                    }
                    else
                    {
                        claims[index] = new Claim(ClaimTypes.Role,ticketSplit[0], OriginalIssuer);
                    }
                }

                var identity = new ClaimsIdentity(claims, OriginalIssuer, ClaimTypes.Name,ClaimTypes.Role);

                var principal = new ClaimsPrincipal(identity);

                _logger.Write(principal.Identity.Name);

                context.User = principal;
                _logger.Write("Cookie End");
                await next();
            } catch (Exception ex)
            {
                _logger.Write(ex.Message);
                _logger.Write(ex.StackTrace);
            }
        });

然后,它将获取cookie并从中创建新的声明标识。 我刚刚完成逻辑以使其正常工作所以我确定它可以整理...只是想我会得到它,所以你可以看看你是否可以得到一些想法。

WebForms不是ASP.NET 5的一部分。 根据这篇博客文章,这是#2的变化

更新

ASP.NET MVC 6的新生命周期使用中间件来组合服务。 您可以使用安全包进行身份验证,但不再支持旧的“表单”身份验证。

这是我在Asp.net核心mvc中的简单代码,希望对大家有所帮助:

Startup.cs在函数ConfigureServices添加services.AddAuthorization(); service.AddMvc()

在功能Configure添加如下代码

app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationScheme = "UserLoginCookie",
                LoginPath = new PathString("/Account/Login"),
                AccessDeniedPath = new PathString("/Account/Forbidden"),
                AutomaticAuthenticate = true,
                AutomaticChallenge = true
            }); 

app.UseMvc....之前

在登录方法:核心代码如下:

     var claims = new List<Claim>()
        {
            new Claim(ClaimTypes.Name,userName here),
            new Claim("UserCodeInMyWebApp",Anything you want),
            new Claim(ClaimTypes.Role,"Admin")

        };
            var userPrincipal = new ClaimsPrincipal(new ClaimsIdentity(claims, "UserLoginClaimsIdentity"));
            //signin
            await HttpContext.Authentication.SignInAsync("UserLoginCookie", userPrincipal, new AuthenticationProperties
            {
                ExpiresUtc = DateTime.UtcNow.AddMinutes(20),
                IsPersistent = false,
                AllowRefresh = false
            });

            return RedirectToAction("AuthPage", "Home"); 

然后您可以通过键值访问声明值或检查是否经过身份验证:

bool flag = User.Identity.IsAuthenticated
 ClaimsIdentity user = User.Identity as ClaimsIdentity
 user.Name or user.FindFirst(the key value string you created).Value 

并检查如下:

  [HttpGet]
        [AllowAnonymous]
        public IActionResult Index()
        {
            return View();
        }

        [Authorize(Roles = "Admin")]
        [HttpGet]
        public IActionResult AuthPage()
        {
            return View();
        }

        public IActionResult About()
        {
            return View();
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM